From f3eb906bf39ea7d1b9ed41e2672a485dd442b496 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Wed, 21 Jan 1998 20:48:12 +0000 Subject: [PATCH] restructure; new Symb support --- src/dev/Makefile | 4 +- src/dev/Makefile.Vx | 127 - src/dev/apsDev/Makefile | 6 + src/dev/apsDev/Makefile.Vx | 13 + src/dev/{ => apsDev}/devApsEg.c | 4 +- src/dev/{ => apsDev}/devApsEr.c | 2 +- src/dev/{ => apsDev}/devApsEr.h | 0 src/dev/atDev/Makefile | 6 + src/dev/atDev/Makefile.Vx | 11 + src/dev/{ => atDev}/devAt5Vxi.c | 0 src/dev/{ => atDev}/devAt8Fp.c | 0 src/dev/avme9440Dev/Makefile | 6 + src/dev/avme9440Dev/Makefile.Vx | 10 + src/dev/{ => avme9440Dev}/devAvme9440.c | 0 src/dev/camacDev/CamacDevSup_doc.ps | 2402 +++++++++++++++ src/dev/camacDev/Makefile | 6 + src/dev/camacDev/Makefile.Vx | 25 + src/dev/{ => camacDev}/devAaiCamac.c | 0 src/dev/{ => camacDev}/devAaoCamac.c | 0 src/dev/{ => camacDev}/devAiCamac.c | 0 src/dev/{ => camacDev}/devAoCamac.c | 0 src/dev/{ => camacDev}/devBiCamac.c | 0 src/dev/{ => camacDev}/devBoCamac.c | 0 src/dev/{ => camacDev}/devCamac.h | 0 src/dev/{ => camacDev}/devLiCamac.c | 0 src/dev/{ => camacDev}/devLoCamac.c | 0 src/dev/{ => camacDev}/devMbbiCamac.c | 0 src/dev/{ => camacDev}/devMbbiDirectCamac.c | 0 src/dev/{ => camacDev}/devMbboCamac.c | 0 src/dev/{ => camacDev}/devMbboDirectCamac.c | 0 src/dev/{ => camacDev}/devWfCamac.c | 0 src/dev/cometDev/Makefile | 6 + src/dev/cometDev/Makefile.Vx | 10 + src/dev/{ => cometDev}/devWfComet.c | 0 src/dev/compumotorDev/Makefile | 6 + src/dev/compumotorDev/Makefile.Vx | 10 + .../{ => compumotorDev}/devSmCompumotor1830.c | 0 src/dev/devAB1771IFE.c | 267 -- src/dev/devAB1771IL.c | 195 -- src/dev/devAB1771IR.c | 216 -- src/dev/devAB1771IXE.c | 268 -- src/dev/devAB1771OFE.c | 196 -- src/dev/devABBINARY.c | 617 ---- src/dev/devABSLCDCM.c | 584 ---- src/dev/devABStatus.c | 116 - src/dev/devAiCan.c | 344 --- src/dev/devAoCan.c | 319 -- src/dev/devBiCan.c | 265 -- src/dev/devBoCan.c | 244 -- src/dev/devMbbiCan.c | 267 -- src/dev/devMbbiDirectCan.c | 267 -- src/dev/devMbboCan.c | 245 -- src/dev/devMbboDirectCan.c | 245 -- src/dev/devSmAB1746HSTP1.c | 1711 ----------- src/dev/dvxDev/Makefile | 6 + src/dev/dvxDev/Makefile.Vx | 11 + src/dev/{ => dvxDev}/devAiDvx2502.c | 0 src/dev/{ => dvxDev}/devWfDvx2502.c | 0 src/dev/gpibDev/Makefile | 6 + src/dev/gpibDev/Makefile.Vx | 12 + src/dev/{ => gpibDev}/devCommonGpib.c | 3 + src/dev/{ => gpibDev}/devCommonGpib.h | 0 src/dev/hpe1368Dev/Makefile | 6 + src/dev/hpe1368Dev/Makefile.Vx | 10 + src/dev/{ => hpe1368Dev}/devHpe1368a.c | 0 src/dev/joergerDev/Makefile | 6 + src/dev/joergerDev/Makefile.Vx | 10 + src/dev/{ => joergerDev}/devWfJoergerVtr1.c | 0 src/dev/kscV215Dev/Makefile | 6 + src/dev/kscV215Dev/Makefile.Vx | 10 + src/dev/{ => kscV215Dev}/devAiKscV215.c | 0 src/dev/mizarDev/Makefile | 6 + src/dev/mizarDev/Makefile.Vx | 11 + src/dev/{ => mizarDev}/devMz8310.c | 0 src/dev/{ => mizarDev}/devTimerMz8310.c | 0 src/dev/mpvDev/Makefile | 6 + src/dev/mpvDev/Makefile.Vx | 15 + src/dev/{ => mpvDev}/devBiMpv910.c | 0 src/dev/{ => mpvDev}/devBoMpv902.c | 0 src/dev/{ => mpvDev}/devMbbiDirectMpv910.c | 0 src/dev/{ => mpvDev}/devMbbiMpv910.c | 0 src/dev/{ => mpvDev}/devMbboDirectMpv902.c | 0 src/dev/{ => mpvDev}/devMbboMpv902.c | 0 src/dev/omsDev/Makefile | 6 + src/dev/omsDev/Makefile.Vx | 10 + src/dev/{ => omsDev}/devSmOms6Axis.c | 0 src/dev/pentekDev/Makefile | 6 + src/dev/pentekDev/Makefile.Vx | 10 + src/dev/{ => pentekDev}/devWfPentek4261.c | 0 src/dev/softDev/Makefile | 6 + src/dev/softDev/Makefile.Vx | 32 + src/dev/{ => softDev}/devAiSoft.c | 0 src/dev/{ => softDev}/devAiSoftRaw.c | 0 src/dev/{ => softDev}/devAoSoft.c | 0 src/dev/{ => softDev}/devAoSoftRaw.c | 0 src/dev/{ => softDev}/devBiSoft.c | 0 src/dev/{ => softDev}/devBiSoftRaw.c | 0 src/dev/{ => softDev}/devBoSoft.c | 0 src/dev/{ => softDev}/devBoSoftRaw.c | 0 src/dev/{ => softDev}/devEventSoft.c | 0 src/dev/{ => softDev}/devHistogramSoft.c | 0 src/dev/{ => softDev}/devLiSoft.c | 0 src/dev/{ => softDev}/devLoSoft.c | 0 src/dev/{ => softDev}/devMbbiDirectSoft.c | 0 src/dev/{ => softDev}/devMbbiDirectSoftRaw.c | 0 src/dev/{ => softDev}/devMbbiSoft.c | 0 src/dev/{ => softDev}/devMbbiSoftRaw.c | 0 src/dev/{ => softDev}/devMbboDirectSoft.c | 0 src/dev/{ => softDev}/devMbboDirectSoftRaw.c | 0 src/dev/{ => softDev}/devMbboSoft.c | 0 src/dev/{ => softDev}/devMbboSoftRaw.c | 0 src/dev/{ => softDev}/devPtSoft.c | 0 src/dev/{ => softDev}/devSASoft.c | 0 src/dev/{ => softDev}/devSiSoft.c | 0 src/dev/{ => softDev}/devSoSoft.c | 0 src/dev/{ => softDev}/devWfSoft.c | 0 src/dev/symbDev/Makefile | 3 + src/dev/symbDev/Makefile.Vx | 26 + src/dev/symbDev/README | 43 + src/dev/{ => symbDev}/devAiSymb.c | 39 +- src/dev/{ => symbDev}/devAoSymb.c | 44 +- src/dev/symbDev/devBiSymb.c | 112 + src/dev/symbDev/devBoSymb.c | 109 + src/dev/{ => symbDev}/devLiSymb.c | 41 +- src/dev/{ => symbDev}/devLoSymb.c | 45 +- src/dev/symbDev/devMbbiSymb.c | 112 + src/dev/symbDev/devMbbiSymbRaw.c | 110 + src/dev/symbDev/devMbboSymb.c | 109 + src/dev/symbDev/devMbboSymbRaw.c | 109 + src/dev/{ => symbDev}/devSiSymb.c | 44 +- src/dev/{ => symbDev}/devSoSymb.c | 47 +- src/dev/symbDev/devSymb.h | 31 + src/dev/symbDev/devSymbFind.c | 305 ++ src/dev/symbDev/devSymbTest.c | 101 + src/dev/symbDev/devWfSymb.c | 111 + src/dev/symbDev/symb.db | 368 +++ src/dev/symbDev/symb.dbd | 13 + src/dev/testDev/Makefile | 6 + src/dev/testDev/Makefile.Vx | 20 + src/dev/{ => testDev}/devAiTestAsyn.c | 0 src/dev/{ => testDev}/devAoTestAsyn.c | 0 src/dev/{ => testDev}/devBiTestAsyn.c | 0 src/dev/{ => testDev}/devBoTestAsyn.c | 0 src/dev/{ => testDev}/devEventTestIoEvent.c | 0 src/dev/{ => testDev}/devHistogramTestAsyn.c | 0 src/dev/{ => testDev}/devMbbiTestAsyn.c | 0 src/dev/{ => testDev}/devMbboTestAsyn.c | 0 src/dev/{ => testDev}/devSiTestAsyn.c | 0 src/dev/{ => testDev}/devSoTestAsyn.c | 0 src/dev/{ => testDev}/devWfTestAsyn.c | 0 src/dev/vmiDev/Makefile | 6 + src/dev/vmiDev/Makefile.Vx | 11 + src/dev/{ => vmiDev}/devAoVmiVme4100.c | 0 src/dev/{ => vmiDev}/devVmic2534.c | 0 src/dev/vxStatsDev/Makefile | 6 + src/dev/vxStatsDev/Makefile.Vx | 10 + src/dev/{ => vxStatsDev}/devVXStats.c | 0 src/dev/xycomDev/Makefile | 6 + src/dev/xycomDev/Makefile.Vx | 21 + src/dev/{ => xycomDev}/devAiXy566Di.c | 0 src/dev/{ => xycomDev}/devAiXy566DiL.c | 0 src/dev/{ => xycomDev}/devAiXy566Se.c | 0 src/dev/{ => xycomDev}/devBiXVme210.c | 0 src/dev/{ => xycomDev}/devBoXVme220.c | 0 src/dev/{ => xycomDev}/devMbbiDirectXVme210.c | 0 src/dev/{ => xycomDev}/devMbbiXVme210.c | 0 src/dev/{ => xycomDev}/devMbboDirectXVme220.c | 0 src/dev/{ => xycomDev}/devMbboXVme220.c | 0 src/dev/{ => xycomDev}/devWfXy566Sc.c | 0 src/dev/{ => xycomDev}/devXy240.c | 0 src/vxWorks/dev/apsDev/devApsEg.c | 2062 +++++++++++++ src/vxWorks/dev/apsDev/devApsEr.c | 1157 ++++++++ src/vxWorks/dev/apsDev/devApsEr.h | 74 + src/vxWorks/dev/atDev/devAt5Vxi.c | 584 ++++ src/vxWorks/dev/atDev/devAt8Fp.c | 251 ++ .../dev/compumotorDev/devSmCompumotor1830.c | 82 + src/vxWorks/dev/gpibDev/devCommonGpib.c | 2638 +++++++++++++++++ src/vxWorks/dev/gpibDev/devCommonGpib.h | 348 +++ src/vxWorks/dev/joergerDev/devWfJoergerVtr1.c | 167 ++ 179 files changed, 11918 insertions(+), 6667 deletions(-) delete mode 100644 src/dev/Makefile.Vx create mode 100644 src/dev/apsDev/Makefile create mode 100644 src/dev/apsDev/Makefile.Vx rename src/dev/{ => apsDev}/devApsEg.c (99%) rename src/dev/{ => apsDev}/devApsEr.c (99%) rename src/dev/{ => apsDev}/devApsEr.h (100%) create mode 100644 src/dev/atDev/Makefile create mode 100644 src/dev/atDev/Makefile.Vx rename src/dev/{ => atDev}/devAt5Vxi.c (100%) rename src/dev/{ => atDev}/devAt8Fp.c (100%) create mode 100644 src/dev/avme9440Dev/Makefile create mode 100644 src/dev/avme9440Dev/Makefile.Vx rename src/dev/{ => avme9440Dev}/devAvme9440.c (100%) create mode 100644 src/dev/camacDev/CamacDevSup_doc.ps create mode 100644 src/dev/camacDev/Makefile create mode 100644 src/dev/camacDev/Makefile.Vx rename src/dev/{ => camacDev}/devAaiCamac.c (100%) rename src/dev/{ => camacDev}/devAaoCamac.c (100%) rename src/dev/{ => camacDev}/devAiCamac.c (100%) rename src/dev/{ => camacDev}/devAoCamac.c (100%) rename src/dev/{ => camacDev}/devBiCamac.c (100%) rename src/dev/{ => camacDev}/devBoCamac.c (100%) rename src/dev/{ => camacDev}/devCamac.h (100%) rename src/dev/{ => camacDev}/devLiCamac.c (100%) rename src/dev/{ => camacDev}/devLoCamac.c (100%) rename src/dev/{ => camacDev}/devMbbiCamac.c (100%) rename src/dev/{ => camacDev}/devMbbiDirectCamac.c (100%) rename src/dev/{ => camacDev}/devMbboCamac.c (100%) rename src/dev/{ => camacDev}/devMbboDirectCamac.c (100%) rename src/dev/{ => camacDev}/devWfCamac.c (100%) create mode 100644 src/dev/cometDev/Makefile create mode 100644 src/dev/cometDev/Makefile.Vx rename src/dev/{ => cometDev}/devWfComet.c (100%) create mode 100644 src/dev/compumotorDev/Makefile create mode 100644 src/dev/compumotorDev/Makefile.Vx rename src/dev/{ => compumotorDev}/devSmCompumotor1830.c (100%) delete mode 100644 src/dev/devAB1771IFE.c delete mode 100644 src/dev/devAB1771IL.c delete mode 100644 src/dev/devAB1771IR.c delete mode 100644 src/dev/devAB1771IXE.c delete mode 100644 src/dev/devAB1771OFE.c delete mode 100644 src/dev/devABBINARY.c delete mode 100644 src/dev/devABSLCDCM.c delete mode 100644 src/dev/devABStatus.c delete mode 100644 src/dev/devAiCan.c delete mode 100644 src/dev/devAoCan.c delete mode 100644 src/dev/devBiCan.c delete mode 100644 src/dev/devBoCan.c delete mode 100644 src/dev/devMbbiCan.c delete mode 100644 src/dev/devMbbiDirectCan.c delete mode 100644 src/dev/devMbboCan.c delete mode 100644 src/dev/devMbboDirectCan.c delete mode 100644 src/dev/devSmAB1746HSTP1.c create mode 100644 src/dev/dvxDev/Makefile create mode 100644 src/dev/dvxDev/Makefile.Vx rename src/dev/{ => dvxDev}/devAiDvx2502.c (100%) rename src/dev/{ => dvxDev}/devWfDvx2502.c (100%) create mode 100644 src/dev/gpibDev/Makefile create mode 100644 src/dev/gpibDev/Makefile.Vx rename src/dev/{ => gpibDev}/devCommonGpib.c (99%) rename src/dev/{ => gpibDev}/devCommonGpib.h (100%) create mode 100644 src/dev/hpe1368Dev/Makefile create mode 100644 src/dev/hpe1368Dev/Makefile.Vx rename src/dev/{ => hpe1368Dev}/devHpe1368a.c (100%) create mode 100644 src/dev/joergerDev/Makefile create mode 100644 src/dev/joergerDev/Makefile.Vx rename src/dev/{ => joergerDev}/devWfJoergerVtr1.c (100%) create mode 100644 src/dev/kscV215Dev/Makefile create mode 100644 src/dev/kscV215Dev/Makefile.Vx rename src/dev/{ => kscV215Dev}/devAiKscV215.c (100%) create mode 100644 src/dev/mizarDev/Makefile create mode 100644 src/dev/mizarDev/Makefile.Vx rename src/dev/{ => mizarDev}/devMz8310.c (100%) rename src/dev/{ => mizarDev}/devTimerMz8310.c (100%) create mode 100644 src/dev/mpvDev/Makefile create mode 100644 src/dev/mpvDev/Makefile.Vx rename src/dev/{ => mpvDev}/devBiMpv910.c (100%) rename src/dev/{ => mpvDev}/devBoMpv902.c (100%) rename src/dev/{ => mpvDev}/devMbbiDirectMpv910.c (100%) rename src/dev/{ => mpvDev}/devMbbiMpv910.c (100%) rename src/dev/{ => mpvDev}/devMbboDirectMpv902.c (100%) rename src/dev/{ => mpvDev}/devMbboMpv902.c (100%) create mode 100644 src/dev/omsDev/Makefile create mode 100644 src/dev/omsDev/Makefile.Vx rename src/dev/{ => omsDev}/devSmOms6Axis.c (100%) create mode 100644 src/dev/pentekDev/Makefile create mode 100644 src/dev/pentekDev/Makefile.Vx rename src/dev/{ => pentekDev}/devWfPentek4261.c (100%) create mode 100644 src/dev/softDev/Makefile create mode 100644 src/dev/softDev/Makefile.Vx rename src/dev/{ => softDev}/devAiSoft.c (100%) rename src/dev/{ => softDev}/devAiSoftRaw.c (100%) rename src/dev/{ => softDev}/devAoSoft.c (100%) rename src/dev/{ => softDev}/devAoSoftRaw.c (100%) rename src/dev/{ => softDev}/devBiSoft.c (100%) rename src/dev/{ => softDev}/devBiSoftRaw.c (100%) rename src/dev/{ => softDev}/devBoSoft.c (100%) rename src/dev/{ => softDev}/devBoSoftRaw.c (100%) rename src/dev/{ => softDev}/devEventSoft.c (100%) rename src/dev/{ => softDev}/devHistogramSoft.c (100%) rename src/dev/{ => softDev}/devLiSoft.c (100%) rename src/dev/{ => softDev}/devLoSoft.c (100%) rename src/dev/{ => softDev}/devMbbiDirectSoft.c (100%) rename src/dev/{ => softDev}/devMbbiDirectSoftRaw.c (100%) rename src/dev/{ => softDev}/devMbbiSoft.c (100%) rename src/dev/{ => softDev}/devMbbiSoftRaw.c (100%) rename src/dev/{ => softDev}/devMbboDirectSoft.c (100%) rename src/dev/{ => softDev}/devMbboDirectSoftRaw.c (100%) rename src/dev/{ => softDev}/devMbboSoft.c (100%) rename src/dev/{ => softDev}/devMbboSoftRaw.c (100%) rename src/dev/{ => softDev}/devPtSoft.c (100%) rename src/dev/{ => softDev}/devSASoft.c (100%) rename src/dev/{ => softDev}/devSiSoft.c (100%) rename src/dev/{ => softDev}/devSoSoft.c (100%) rename src/dev/{ => softDev}/devWfSoft.c (100%) create mode 100644 src/dev/symbDev/Makefile create mode 100644 src/dev/symbDev/Makefile.Vx create mode 100644 src/dev/symbDev/README rename src/dev/{ => symbDev}/devAiSymb.c (69%) rename src/dev/{ => symbDev}/devAoSymb.c (66%) create mode 100644 src/dev/symbDev/devBiSymb.c create mode 100644 src/dev/symbDev/devBoSymb.c rename src/dev/{ => symbDev}/devLiSymb.c (67%) rename src/dev/{ => symbDev}/devLoSymb.c (65%) create mode 100644 src/dev/symbDev/devMbbiSymb.c create mode 100644 src/dev/symbDev/devMbbiSymbRaw.c create mode 100644 src/dev/symbDev/devMbboSymb.c create mode 100644 src/dev/symbDev/devMbboSymbRaw.c rename src/dev/{ => symbDev}/devSiSymb.c (67%) rename src/dev/{ => symbDev}/devSoSymb.c (66%) create mode 100644 src/dev/symbDev/devSymb.h create mode 100644 src/dev/symbDev/devSymbFind.c create mode 100644 src/dev/symbDev/devSymbTest.c create mode 100644 src/dev/symbDev/devWfSymb.c create mode 100644 src/dev/symbDev/symb.db create mode 100644 src/dev/symbDev/symb.dbd create mode 100644 src/dev/testDev/Makefile create mode 100644 src/dev/testDev/Makefile.Vx rename src/dev/{ => testDev}/devAiTestAsyn.c (100%) rename src/dev/{ => testDev}/devAoTestAsyn.c (100%) rename src/dev/{ => testDev}/devBiTestAsyn.c (100%) rename src/dev/{ => testDev}/devBoTestAsyn.c (100%) rename src/dev/{ => testDev}/devEventTestIoEvent.c (100%) rename src/dev/{ => testDev}/devHistogramTestAsyn.c (100%) rename src/dev/{ => testDev}/devMbbiTestAsyn.c (100%) rename src/dev/{ => testDev}/devMbboTestAsyn.c (100%) rename src/dev/{ => testDev}/devSiTestAsyn.c (100%) rename src/dev/{ => testDev}/devSoTestAsyn.c (100%) rename src/dev/{ => testDev}/devWfTestAsyn.c (100%) create mode 100644 src/dev/vmiDev/Makefile create mode 100644 src/dev/vmiDev/Makefile.Vx rename src/dev/{ => vmiDev}/devAoVmiVme4100.c (100%) rename src/dev/{ => vmiDev}/devVmic2534.c (100%) create mode 100644 src/dev/vxStatsDev/Makefile create mode 100644 src/dev/vxStatsDev/Makefile.Vx rename src/dev/{ => vxStatsDev}/devVXStats.c (100%) create mode 100644 src/dev/xycomDev/Makefile create mode 100644 src/dev/xycomDev/Makefile.Vx rename src/dev/{ => xycomDev}/devAiXy566Di.c (100%) rename src/dev/{ => xycomDev}/devAiXy566DiL.c (100%) rename src/dev/{ => xycomDev}/devAiXy566Se.c (100%) rename src/dev/{ => xycomDev}/devBiXVme210.c (100%) rename src/dev/{ => xycomDev}/devBoXVme220.c (100%) rename src/dev/{ => xycomDev}/devMbbiDirectXVme210.c (100%) rename src/dev/{ => xycomDev}/devMbbiXVme210.c (100%) rename src/dev/{ => xycomDev}/devMbboDirectXVme220.c (100%) rename src/dev/{ => xycomDev}/devMbboXVme220.c (100%) rename src/dev/{ => xycomDev}/devWfXy566Sc.c (100%) rename src/dev/{ => xycomDev}/devXy240.c (100%) create mode 100644 src/vxWorks/dev/apsDev/devApsEg.c create mode 100644 src/vxWorks/dev/apsDev/devApsEr.c create mode 100644 src/vxWorks/dev/apsDev/devApsEr.h create mode 100644 src/vxWorks/dev/atDev/devAt5Vxi.c create mode 100644 src/vxWorks/dev/atDev/devAt8Fp.c create mode 100644 src/vxWorks/dev/compumotorDev/devSmCompumotor1830.c create mode 100644 src/vxWorks/dev/gpibDev/devCommonGpib.c create mode 100644 src/vxWorks/dev/gpibDev/devCommonGpib.h create mode 100644 src/vxWorks/dev/joergerDev/devWfJoergerVtr1.c diff --git a/src/dev/Makefile b/src/dev/Makefile index 8cca632b9..2208e1fb5 100644 --- a/src/dev/Makefile +++ b/src/dev/Makefile @@ -3,5 +3,7 @@ TOP=../.. include $(TOP)/config/CONFIG_BASE -include $(TOP)/config/RULES_ARCHS +DIRS = $(wildcard *Dev) + +include $(TOP)/config/RULES_DIRS diff --git a/src/dev/Makefile.Vx b/src/dev/Makefile.Vx deleted file mode 100644 index 5c19e262d..000000000 --- a/src/dev/Makefile.Vx +++ /dev/null @@ -1,127 +0,0 @@ -TOP = ../../.. -include $(TOP)/config/CONFIG_BASE - -USR_INCLUDES = -I../../drv/ansi -I../../drv/old - -INC += devApsEr.h -INC += devCamac.h -INC += devCommonGpib.h - - -# SRCS.c += ../devAaiCamac.c -# SRCS.c += ../devAiCamac.c -SRCS.c += ../devAiDvx2502.c -SRCS.c += ../devAiKscV215.c -SRCS.c += ../devAiSoft.c -SRCS.c += ../devAiSoftRaw.c -SRCS.c += ../devVXStats.c -SRCS.c += ../devAiSymb.c -SRCS.c += ../devAiTestAsyn.c -SRCS.c += ../devAiXy566Di.c -SRCS.c += ../devAiXy566DiL.c -SRCS.c += ../devAiXy566Se.c -# SRCS.c += ../devAaoCamac.c -# SRCS.c += ../devAoCamac.c -SRCS.c += ../devAoSoft.c -SRCS.c += ../devAoSoftRaw.c -SRCS.c += ../devAoSymb.c -SRCS.c += ../devAoTestAsyn.c -SRCS.c += ../devAoVmiVme4100.c -SRCS.c += ../devApsEg.c -SRCS.c += ../devApsEr.c -SRCS.c += ../devAt5Vxi.c -SRCS.c += ../devAt8Fp.c -SRCS.c += ../devAvme9440.c -# SRCS.c += ../devBiCamac.c -SRCS.c += ../devBiMpv910.c -SRCS.c += ../devBiSoft.c -SRCS.c += ../devBiSoftRaw.c -SRCS.c += ../devBiTestAsyn.c -SRCS.c += ../devBiXVme210.c -# SRCS.c += ../devBoCamac.c -SRCS.c += ../devBoMpv902.c -SRCS.c += ../devBoSoft.c -SRCS.c += ../devBoSoftRaw.c -SRCS.c += ../devBoTestAsyn.c -SRCS.c += ../devBoXVme220.c -SRCS.c += ../devCommonGpib.c -SRCS.c += ../devEventSoft.c -SRCS.c += ../devEventTestIoEvent.c -SRCS.c += ../devHistogramSoft.c -SRCS.c += ../devHistogramTestAsyn.c -SRCS.c += ../devHpe1368a.c -# SRCS.c += ../devLiCamac.c -SRCS.c += ../devLiSoft.c -SRCS.c += ../devLiSymb.c -# SRCS.c += ../devLoCamac.c -SRCS.c += ../devLoSoft.c -SRCS.c += ../devLoSymb.c -# SRCS.c += ../devMbbiCamac.c -# SRCS.c += ../devMbbiDirectCamac.c -SRCS.c += ../devMbbiDirectMpv910.c -SRCS.c += ../devMbbiDirectSoft.c -SRCS.c += ../devMbbiDirectSoftRaw.c -SRCS.c += ../devMbbiDirectXVme210.c -SRCS.c += ../devMbbiMpv910.c -SRCS.c += ../devMbbiSoft.c -SRCS.c += ../devMbbiSoftRaw.c -SRCS.c += ../devMbbiTestAsyn.c -SRCS.c += ../devMbbiXVme210.c -# SRCS.c += ../devMbboCamac.c -# SRCS.c += ../devMbboDirectCamac.c -SRCS.c += ../devMbboDirectMpv902.c -SRCS.c += ../devMbboDirectSoft.c -SRCS.c += ../devMbboDirectSoftRaw.c -SRCS.c += ../devMbboDirectXVme220.c -SRCS.c += ../devMbboMpv902.c -SRCS.c += ../devMbboSoft.c -SRCS.c += ../devMbboSoftRaw.c -SRCS.c += ../devMbboTestAsyn.c -SRCS.c += ../devMbboXVme220.c -SRCS.c += ../devMz8310.c -SRCS.c += ../devPtSoft.c -SRCS.c += ../devSASoft.c -SRCS.c += ../devSiSoft.c -SRCS.c += ../devSiSymb.c -SRCS.c += ../devSiTestAsyn.c -SRCS.c += ../devSmCompumotor1830.c -SRCS.c += ../devSmOms6Axis.c -SRCS.c += ../devSmAB1746HSTP1.c -SRCS.c += ../devSoSoft.c -SRCS.c += ../devSoSymb.c -SRCS.c += ../devSoTestAsyn.c -SRCS.c += ../devTimerMz8310.c -# SRCS.c += ../devWfCamac.c -SRCS.c += ../devWfComet.c -SRCS.c += ../devWfDvx2502.c -SRCS.c += ../devWfJoergerVtr1.c -SRCS.c += ../devWfSoft.c -SRCS.c += ../devWfTestAsyn.c -SRCS.c += ../devWfXy566Sc.c -SRCS.c += ../devWfPentek4261.c -SRCS.c += ../devXy240.c - -SRCS.c += ../devAB1771IFE.c -SRCS.c += ../devAB1771IL.c -SRCS.c += ../devAB1771IR.c -SRCS.c += ../devAB1771IXE.c -SRCS.c += ../devAB1771OFE.c -SRCS.c += ../devABSLCDCM.c -SRCS.c += ../devABBINARY.c -SRCS.c += ../devABStatus.c -SRCS.c += ../devVmic2534.c - -# SRCS.c += ../devAiCan.c -# SRCS.c += ../devAoCan.c -# SRCS.c += ../devBiCan.c -# SRCS.c += ../devBoCan.c -# SRCS.c += ../devMbbiCan.c -# SRCS.c += ../devMbboCan.c -# SRCS.c += ../devMbbiDirectCan.c -# SRCS.c += ../devMbboDirectCan.c - -PROD = $(SRCS.c:../%.c=%.o) - -include $(TOP)/config/RULES.Vx - - diff --git a/src/dev/apsDev/Makefile b/src/dev/apsDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/apsDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/apsDev/Makefile.Vx b/src/dev/apsDev/Makefile.Vx new file mode 100644 index 000000000..7329df028 --- /dev/null +++ b/src/dev/apsDev/Makefile.Vx @@ -0,0 +1,13 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +INC += devApsEr.h + +SRCS.c += ../devApsEg.c +SRCS.c += ../devApsEr.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devApsEg.c b/src/dev/apsDev/devApsEg.c similarity index 99% rename from src/dev/devApsEg.c rename to src/dev/apsDev/devApsEg.c index 3e58dfea9..61e42a341 100644 --- a/src/dev/devApsEg.c +++ b/src/dev/apsDev/devApsEg.c @@ -899,7 +899,7 @@ STATIC long EgProcEgRec(struct egRecord *pRec) if (pRec->vme != 0) { if (pRec->tpro > 10) - printf(", VME-%d", pRec->vme); + printf(", VME-%ld", pRec->vme); EgGenerateVmeEvent(pLink, pRec->vme); pRec->vme = 0; } @@ -1164,7 +1164,7 @@ STATIC long EgProcEgEventRec(struct egeventRecord *pRec) break; } if (pRec->tpro) - printf("EgProcEgEventRec(%s) dpos=%d\n", pRec->name, pRec->dpos); + printf("EgProcEgEventRec(%s) dpos=%ld\n", pRec->name, pRec->dpos); pRec->ldly = pRec->dely; if (pRec->ram == egeventRAM_RAM_2) diff --git a/src/dev/devApsEr.c b/src/dev/apsDev/devApsEr.c similarity index 99% rename from src/dev/devApsEr.c rename to src/dev/apsDev/devApsEr.c index 03c296e54..80ba6a59c 100644 --- a/src/dev/devApsEr.c +++ b/src/dev/apsDev/devApsEr.c @@ -506,7 +506,7 @@ STATIC long ErEventProc(struct ereventRecord *pRec) if (pRec->enm != pRec->lenm) { if (pRec->tpro > 10) - printf("ErEventProc(%s) event number changed %d-%d\n", pRec->name, pRec->lenm, pRec->enm); + printf("ErEventProc(%s) event number changed %ld-%ld\n", pRec->name, pRec->lenm, pRec->enm); /* Transfer the event info to new position */ if ((pRec->lenm < 256) && (pRec->lenm >= 0)) pLink->ErEventTab[pRec->lenm] = 0; diff --git a/src/dev/devApsEr.h b/src/dev/apsDev/devApsEr.h similarity index 100% rename from src/dev/devApsEr.h rename to src/dev/apsDev/devApsEr.h diff --git a/src/dev/atDev/Makefile b/src/dev/atDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/atDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/atDev/Makefile.Vx b/src/dev/atDev/Makefile.Vx new file mode 100644 index 000000000..a0defbaca --- /dev/null +++ b/src/dev/atDev/Makefile.Vx @@ -0,0 +1,11 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devAt5Vxi.c +SRCS.c += ../devAt8Fp.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAt5Vxi.c b/src/dev/atDev/devAt5Vxi.c similarity index 100% rename from src/dev/devAt5Vxi.c rename to src/dev/atDev/devAt5Vxi.c diff --git a/src/dev/devAt8Fp.c b/src/dev/atDev/devAt8Fp.c similarity index 100% rename from src/dev/devAt8Fp.c rename to src/dev/atDev/devAt8Fp.c diff --git a/src/dev/avme9440Dev/Makefile b/src/dev/avme9440Dev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/avme9440Dev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/avme9440Dev/Makefile.Vx b/src/dev/avme9440Dev/Makefile.Vx new file mode 100644 index 000000000..5ae3bcd9b --- /dev/null +++ b/src/dev/avme9440Dev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devAvme9440.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAvme9440.c b/src/dev/avme9440Dev/devAvme9440.c similarity index 100% rename from src/dev/devAvme9440.c rename to src/dev/avme9440Dev/devAvme9440.c diff --git a/src/dev/camacDev/CamacDevSup_doc.ps b/src/dev/camacDev/CamacDevSup_doc.ps new file mode 100644 index 000000000..1af846600 --- /dev/null +++ b/src/dev/camacDev/CamacDevSup_doc.ps @@ -0,0 +1,2402 @@ +%!PS-Adobe-3.0 +%%BoundingBox: (atend) +%%Pages: (atend) +%%PageOrder: (atend) +%%DocumentFonts: (atend) +%%Creator: Frame 4.0 +%%DocumentData: Clean7Bit +%%EndComments +%%BeginProlog +% +% Frame ps_prolog 4.0, for use with Frame 4.0 products +% This ps_prolog file is Copyright (c) 1986-1993 Frame Technology +% Corporation. All rights reserved. This ps_prolog file may be +% freely copied and distributed in conjunction with documents created +% using FrameMaker, FrameBuilder and FrameViewer as long as this +% copyright notice is preserved. +% +% Frame products normally print colors as their true color on a color printer +% or as shades of gray, based on luminance, on a black-and white printer. The +% following flag, if set to True, forces all non-white colors to print as pure +% black. This has no effect on bitmap images. +/FMPrintAllColorsAsBlack false def +% +% Frame products can either set their own line screens or use a printer's +% default settings. Three flags below control this separately for no +% separations, spot separations and process separations. If a flag +% is true, then the default printer settings will not be changed. If it is +% false, Frame products will use their own settings from a table based on +% the printer's resolution. +/FMUseDefaultNoSeparationScreen true def +/FMUseDefaultSpotSeparationScreen true def +/FMUseDefaultProcessSeparationScreen false def +% +% For any given PostScript printer resolution, Frame products have two sets of +% screen angles and frequencies for printing process separations, which are +% recomended by Adobe. The following variable chooses the higher frequencies +% when set to true or the lower frequencies when set to false. This is only +% effective if the appropriate FMUseDefault...SeparationScreen flag is false. +/FMUseHighFrequencyScreens true def +% +% PostScript Level 2 printers contain an "Accurate Screens" feature which can +% improve process separation rendering at the expense of compute time. This +% flag is ignored by PostScript Level 1 printers. +/FMUseAcccurateScreens true def +% +% The following PostScript procedure defines the spot function that Frame +% products will use for process separations. You may un-comment-out one of +% the alternative functions below, or use your own. +% +% Dot function +/FMSpotFunction {abs exch abs 2 copy add 1 gt + {1 sub dup mul exch 1 sub dup mul add 1 sub } + {dup mul exch dup mul add 1 exch sub }ifelse } def +% +% Line function +% /FMSpotFunction { pop } def +% +% Elipse function +% /FMSpotFunction { dup 5 mul 8 div mul exch dup mul exch add +% sqrt 1 exch sub } def +% +% +/FMversion (4.0) def +/FMLevel1 /languagelevel where {pop languagelevel} {1} ifelse 2 lt def +/FMPColor + FMLevel1 { + false + /colorimage where {pop pop true} if + } { + true + } ifelse +def +/FrameDict 400 dict def +systemdict /errordict known not {/errordict 10 dict def + errordict /rangecheck {stop} put} if +% The readline in PS 23.0 doesn't recognize cr's as nl's on AppleTalk +FrameDict /tmprangecheck errordict /rangecheck get put +errordict /rangecheck {FrameDict /bug true put} put +FrameDict /bug false put +mark +% Some PS machines read past the CR, so keep the following 3 lines together! +currentfile 5 string readline +00 +0000000000 +cleartomark +errordict /rangecheck FrameDict /tmprangecheck get put +FrameDict /bug get { + /readline { + /gstring exch def + /gfile exch def + /gindex 0 def + { + gfile read pop + dup 10 eq {exit} if + dup 13 eq {exit} if + gstring exch gindex exch put + /gindex gindex 1 add def + } loop + pop + gstring 0 gindex getinterval true + } bind def + } if +/FMshowpage /showpage load def +/FMquit /quit load def +/FMFAILURE { + dup = flush + FMshowpage + /Helvetica findfont 12 scalefont setfont + 72 200 moveto + show FMshowpage + FMquit + } def +/FMVERSION { + FMversion ne { + (Frame product version does not match ps_prolog!) FMFAILURE + } if + } def +/FMBADEPSF { + (PostScript Lang. Ref. Man., 2nd Ed., H.2.4 says EPS must not call X ) + dup dup (X) search pop exch pop exch pop length + 4 -1 roll + putinterval + FMFAILURE + } def +/FMLOCAL { + FrameDict begin + 0 def + end + } def +/concatprocs + { + /proc2 exch cvlit def/proc1 exch cvlit def/newproc proc1 length proc2 length add array def + newproc 0 proc1 putinterval newproc proc1 length proc2 putinterval newproc cvx +}def +FrameDict begin +/FMnone 0 def +/FMcyan 1 def +/FMmagenta 2 def +/FMyellow 3 def +/FMblack 4 def +/FMcustom 5 def +/FrameNegative false def +/FrameSepIs FMnone def +/FrameSepBlack 0 def +/FrameSepYellow 0 def +/FrameSepMagenta 0 def +/FrameSepCyan 0 def +/FrameSepRed 1 def +/FrameSepGreen 1 def +/FrameSepBlue 1 def +/FrameCurGray 1 def +/FrameCurPat null def +/FrameCurColors [ 0 0 0 1 0 0 0 ] def +/FrameColorEpsilon .001 def +/eqepsilon { + sub dup 0 lt {neg} if + FrameColorEpsilon le +} bind def +/FrameCmpColorsCMYK { + 2 copy 0 get exch 0 get eqepsilon { + 2 copy 1 get exch 1 get eqepsilon { + 2 copy 2 get exch 2 get eqepsilon { + 3 get exch 3 get eqepsilon + } {pop pop false} ifelse + }{pop pop false} ifelse + } {pop pop false} ifelse +} bind def +/FrameCmpColorsRGB { + 2 copy 4 get exch 0 get eqepsilon { + 2 copy 5 get exch 1 get eqepsilon { + 6 get exch 2 get eqepsilon + }{pop pop false} ifelse + } {pop pop false} ifelse +} bind def +/RGBtoCMYK { + 1 exch sub + 3 1 roll + 1 exch sub + 3 1 roll + 1 exch sub + 3 1 roll + 3 copy + 2 copy + le { pop } { exch pop } ifelse + 2 copy + le { pop } { exch pop } ifelse + dup dup dup + 6 1 roll + 4 1 roll + 7 1 roll + sub + 6 1 roll + sub + 5 1 roll + sub + 4 1 roll +} bind def +/CMYKtoRGB { + dup dup 4 -1 roll add + 5 1 roll 3 -1 roll add + 4 1 roll add + 1 exch sub dup 0 lt {pop 0} if 3 1 roll + 1 exch sub dup 0 lt {pop 0} if exch + 1 exch sub dup 0 lt {pop 0} if exch +} bind def +/FrameSepInit { + 1.0 RealSetgray +} bind def +/FrameSetSepColor { + /FrameSepBlue exch def + /FrameSepGreen exch def + /FrameSepRed exch def + /FrameSepBlack exch def + /FrameSepYellow exch def + /FrameSepMagenta exch def + /FrameSepCyan exch def + /FrameSepIs FMcustom def + setCurrentScreen +} bind def +/FrameSetCyan { + /FrameSepBlue 1.0 def + /FrameSepGreen 1.0 def + /FrameSepRed 0.0 def + /FrameSepBlack 0.0 def + /FrameSepYellow 0.0 def + /FrameSepMagenta 0.0 def + /FrameSepCyan 1.0 def + /FrameSepIs FMcyan def + setCurrentScreen +} bind def + +/FrameSetMagenta { + /FrameSepBlue 1.0 def + /FrameSepGreen 0.0 def + /FrameSepRed 1.0 def + /FrameSepBlack 0.0 def + /FrameSepYellow 0.0 def + /FrameSepMagenta 1.0 def + /FrameSepCyan 0.0 def + /FrameSepIs FMmagenta def + setCurrentScreen +} bind def + +/FrameSetYellow { + /FrameSepBlue 0.0 def + /FrameSepGreen 1.0 def + /FrameSepRed 1.0 def + /FrameSepBlack 0.0 def + /FrameSepYellow 1.0 def + /FrameSepMagenta 0.0 def + /FrameSepCyan 0.0 def + /FrameSepIs FMyellow def + setCurrentScreen +} bind def + +/FrameSetBlack { + /FrameSepBlue 0.0 def + /FrameSepGreen 0.0 def + /FrameSepRed 0.0 def + /FrameSepBlack 1.0 def + /FrameSepYellow 0.0 def + /FrameSepMagenta 0.0 def + /FrameSepCyan 0.0 def + /FrameSepIs FMblack def + setCurrentScreen +} bind def + +/FrameNoSep { + /FrameSepIs FMnone def + setCurrentScreen +} bind def +/FrameSetSepColors { + FrameDict begin + [ exch 1 add 1 roll ] + /FrameSepColors + exch def end + } bind def +/FrameColorInSepListCMYK { + FrameSepColors { + exch dup 3 -1 roll + FrameCmpColorsCMYK + { pop true exit } if + } forall + dup true ne {pop false} if + } bind def +/FrameColorInSepListRGB { + FrameSepColors { + exch dup 3 -1 roll + FrameCmpColorsRGB + { pop true exit } if + } forall + dup true ne {pop false} if + } bind def +/RealSetgray /setgray load def +/RealSetrgbcolor /setrgbcolor load def +/RealSethsbcolor /sethsbcolor load def +end +/setgray { + FrameDict begin + FrameSepIs FMnone eq + { RealSetgray } + { + FrameSepIs FMblack eq + { RealSetgray } + { FrameSepIs FMcustom eq + FrameSepRed 0 eq and + FrameSepGreen 0 eq and + FrameSepBlue 0 eq and { + RealSetgray + } { + 1 RealSetgray pop + } ifelse + } ifelse + } ifelse + end +} bind def +/setrgbcolor { + FrameDict begin + FrameSepIs FMnone eq + { RealSetrgbcolor } + { + 3 copy [ 4 1 roll ] + FrameColorInSepListRGB + { + FrameSepBlue eq exch + FrameSepGreen eq and exch + FrameSepRed eq and + { 0 } { 1 } ifelse + } + { + FMPColor { + RealSetrgbcolor + currentcmykcolor + } { + RGBtoCMYK + } ifelse + FrameSepIs FMblack eq + {1.0 exch sub 4 1 roll pop pop pop} { + FrameSepIs FMyellow eq + {pop 1.0 exch sub 3 1 roll pop pop} { + FrameSepIs FMmagenta eq + {pop pop 1.0 exch sub exch pop } { + FrameSepIs FMcyan eq + {pop pop pop 1.0 exch sub } + {pop pop pop pop 1} ifelse } ifelse } ifelse } ifelse + } ifelse + RealSetgray + } + ifelse + end +} bind def +/sethsbcolor { + FrameDict begin + FrameSepIs FMnone eq + { RealSethsbcolor } + { + RealSethsbcolor + currentrgbcolor + setrgbcolor + } + ifelse + end +} bind def +FrameDict begin +/setcmykcolor where { + pop /RealSetcmykcolor /setcmykcolor load def +} { + /RealSetcmykcolor { + 4 1 roll + 3 { 3 index add 0 max 1 min 1 exch sub 3 1 roll} repeat + setrgbcolor pop + } bind def +} ifelse +userdict /setcmykcolor { + FrameDict begin + FrameSepIs FMnone eq + { RealSetcmykcolor } + { + 4 copy [ 5 1 roll ] + FrameColorInSepListCMYK + { + FrameSepBlack eq exch + FrameSepYellow eq and exch + FrameSepMagenta eq and exch + FrameSepCyan eq and + { 0 } { 1 } ifelse + } + { + FrameSepIs FMblack eq + {1.0 exch sub 4 1 roll pop pop pop} { + FrameSepIs FMyellow eq + {pop 1.0 exch sub 3 1 roll pop pop} { + FrameSepIs FMmagenta eq + {pop pop 1.0 exch sub exch pop } { + FrameSepIs FMcyan eq + {pop pop pop 1.0 exch sub } + {pop pop pop pop 1} ifelse } ifelse } ifelse } ifelse + } ifelse + RealSetgray + } + ifelse + end + } bind put +FMLevel1 not { + + /patProcDict 5 dict dup begin + <0f1e3c78f0e1c387> { 3 setlinewidth -1 -1 moveto 9 9 lineto stroke + 4 -4 moveto 12 4 lineto stroke + -4 4 moveto 4 12 lineto stroke} bind def + <0f87c3e1f0783c1e> { 3 setlinewidth -1 9 moveto 9 -1 lineto stroke + -4 4 moveto 4 -4 lineto stroke + 4 12 moveto 12 4 lineto stroke} bind def + <8142241818244281> { 1 setlinewidth -1 9 moveto 9 -1 lineto stroke + -1 -1 moveto 9 9 lineto stroke } bind def + <03060c183060c081> { 1 setlinewidth -1 -1 moveto 9 9 lineto stroke + 4 -4 moveto 12 4 lineto stroke + -4 4 moveto 4 12 lineto stroke} bind def + <8040201008040201> { 1 setlinewidth -1 9 moveto 9 -1 lineto stroke + -4 4 moveto 4 -4 lineto stroke + 4 12 moveto 12 4 lineto stroke} bind def + end def + /patDict 15 dict dup begin + /PatternType 1 def + /PaintType 2 def + /TilingType 3 def + /BBox [ 0 0 8 8 ] def + /XStep 8 def + /YStep 8 def + /PaintProc { + begin + patProcDict bstring known { + patProcDict bstring get exec + } { + 8 8 true [1 0 0 -1 0 8] bstring imagemask + } ifelse + end + } bind def + end def +} if +/combineColor { + FrameSepIs FMnone eq + { + graymode FMLevel1 or not { + + [/Pattern [/DeviceCMYK]] setcolorspace + FrameCurColors 0 4 getinterval aload pop FrameCurPat setcolor + } { + FrameCurColors 3 get 1.0 ge { + FrameCurGray RealSetgray + } { + FMPColor graymode and { + 0 1 3 { + FrameCurColors exch get + 1 FrameCurGray sub mul + } for + RealSetcmykcolor + } { + 4 1 6 { + FrameCurColors exch get + graymode { + 1 exch sub 1 FrameCurGray sub mul 1 exch sub + } { + 1.0 lt {FrameCurGray} {1} ifelse + } ifelse + } for + RealSetrgbcolor + } ifelse + } ifelse + } ifelse + } { + FrameCurColors 0 4 getinterval aload + FrameColorInSepListCMYK { + FrameSepBlack eq exch + FrameSepYellow eq and exch + FrameSepMagenta eq and exch + FrameSepCyan eq and + FrameSepIs FMcustom eq and + { FrameCurGray } { 1 } ifelse + } { + FrameSepIs FMblack eq + {FrameCurGray 1.0 exch sub mul 1.0 exch sub 4 1 roll pop pop pop} { + FrameSepIs FMyellow eq + {pop FrameCurGray 1.0 exch sub mul 1.0 exch sub 3 1 roll pop pop} { + FrameSepIs FMmagenta eq + {pop pop FrameCurGray 1.0 exch sub mul 1.0 exch sub exch pop } { + FrameSepIs FMcyan eq + {pop pop pop FrameCurGray 1.0 exch sub mul 1.0 exch sub } + {pop pop pop pop 1} ifelse } ifelse } ifelse } ifelse + } ifelse + graymode FMLevel1 or not { + + [/Pattern [/DeviceGray]] setcolorspace + FrameCurPat setcolor + } { + graymode not FMLevel1 and { + + dup 1 lt {pop FrameCurGray} if + } if + RealSetgray + } ifelse + } ifelse +} bind def +/savematrix { + orgmatrix currentmatrix pop + } bind def +/restorematrix { + orgmatrix setmatrix + } bind def +/dmatrix matrix def +/dpi 72 0 dmatrix defaultmatrix dtransform + dup mul exch dup mul add sqrt def + +/freq dpi dup 72 div round dup 0 eq {pop 1} if 8 mul div def +/sangle 1 0 dmatrix defaultmatrix dtransform exch atan def +/dpiranges [ 2540 2400 1693 1270 1200 635 600 0 ] def +/CMLowFreqs [ 100.402 94.8683 89.2289 100.402 94.8683 66.9349 63.2456 47.4342 ] def +/YLowFreqs [ 95.25 90.0 84.65 95.25 90.0 70.5556 66.6667 50.0 ] def +/KLowFreqs [ 89.8026 84.8528 79.8088 89.8026 84.8528 74.8355 70.7107 53.033 ] def +/CLowAngles [ 71.5651 71.5651 71.5651 71.5651 71.5651 71.5651 71.5651 71.5651 ] def +/MLowAngles [ 18.4349 18.4349 18.4349 18.4349 18.4349 18.4349 18.4349 18.4349 ] def +/YLowTDot [ true true false true true false false false ] def +/CMHighFreqs [ 133.87 126.491 133.843 108.503 102.523 100.402 94.8683 63.2456 ] def +/YHighFreqs [ 127.0 120.0 126.975 115.455 109.091 95.25 90.0 60.0 ] def +/KHighFreqs [ 119.737 113.137 119.713 128.289 121.218 89.8026 84.8528 63.6395 ] def +/CHighAngles [ 71.5651 71.5651 71.5651 70.0169 70.0169 71.5651 71.5651 71.5651 ] def +/MHighAngles [ 18.4349 18.4349 18.4349 19.9831 19.9831 18.4349 18.4349 18.4349 ] def +/YHighTDot [ false false true false false true true false ] def +/PatFreq [ 10.5833 10.0 9.4055 10.5833 10.0 10.5833 10.0 9.375 ] def +/screenIndex { + 0 1 dpiranges length 1 sub { dup dpiranges exch get 1 sub dpi le {exit} {pop} ifelse } for +} bind def +/getCyanScreen { + FMUseHighFrequencyScreens { CHighAngles CMHighFreqs} {CLowAngles CMLowFreqs} ifelse + screenIndex dup 3 1 roll get 3 1 roll get /FMSpotFunction load +} bind def +/getMagentaScreen { + FMUseHighFrequencyScreens { MHighAngles CMHighFreqs } {MLowAngles CMLowFreqs} ifelse + screenIndex dup 3 1 roll get 3 1 roll get /FMSpotFunction load +} bind def +/getYellowScreen { + FMUseHighFrequencyScreens { YHighTDot YHighFreqs} { YLowTDot YLowFreqs } ifelse + screenIndex dup 3 1 roll get 3 1 roll get { 3 div + {2 { 1 add 2 div 3 mul dup floor sub 2 mul 1 sub exch} repeat + FMSpotFunction } } {/FMSpotFunction load } ifelse + 0.0 exch +} bind def +/getBlackScreen { + FMUseHighFrequencyScreens { KHighFreqs } { KLowFreqs } ifelse + screenIndex get 45.0 /FMSpotFunction load +} bind def +/getSpotScreen { + getBlackScreen +} bind def +/getCompositeScreen { + getBlackScreen +} bind def +/FMSetScreen + FMLevel1 { /setscreen load + }{ { + 8 dict begin + /HalftoneType 1 def + /SpotFunction exch def + /Angle exch def + /Frequency exch def + /AccurateScreens FMUseAcccurateScreens def + currentdict end sethalftone + } bind } ifelse +def +/setDefaultScreen { + FMPColor { + orgrxfer cvx orggxfer cvx orgbxfer cvx orgxfer cvx setcolortransfer + } + { + orgxfer cvx settransfer + } ifelse + orgfreq organgle orgproc cvx setscreen +} bind def +/setCurrentScreen { + FrameSepIs FMnone eq { + FMUseDefaultNoSeparationScreen { + setDefaultScreen + } { + getCompositeScreen FMSetScreen + } ifelse + } { + FrameSepIs FMcustom eq { + FMUseDefaultSpotSeparationScreen { + setDefaultScreen + } { + getSpotScreen FMSetScreen + } ifelse + } { + FMUseDefaultProcessSeparationScreen { + setDefaultScreen + } { + FrameSepIs FMcyan eq { + getCyanScreen FMSetScreen + } { + FrameSepIs FMmagenta eq { + getMagentaScreen FMSetScreen + } { + FrameSepIs FMyellow eq { + getYellowScreen FMSetScreen + } { + getBlackScreen FMSetScreen + } ifelse + } ifelse + } ifelse + } ifelse + } ifelse + } ifelse +} bind def +end + /gstring FMLOCAL + /gfile FMLOCAL + /gindex FMLOCAL + /orgrxfer FMLOCAL + /orggxfer FMLOCAL + /orgbxfer FMLOCAL + /orgxfer FMLOCAL + /orgproc FMLOCAL + /orgrproc FMLOCAL + /orggproc FMLOCAL + /orgbproc FMLOCAL + /organgle FMLOCAL + /orgrangle FMLOCAL + /orggangle FMLOCAL + /orgbangle FMLOCAL + /orgfreq FMLOCAL + /orgrfreq FMLOCAL + /orggfreq FMLOCAL + /orgbfreq FMLOCAL + /yscale FMLOCAL + /xscale FMLOCAL + /edown FMLOCAL + /manualfeed FMLOCAL + /paperheight FMLOCAL + /paperwidth FMLOCAL +/FMDOCUMENT { + array /FMfonts exch def + /#copies exch def + FrameDict begin + 0 ne /manualfeed exch def + /paperheight exch def + /paperwidth exch def + 0 ne /FrameNegative exch def + 0 ne /edown exch def + /yscale exch def + /xscale exch def + FMLevel1 { + manualfeed {setmanualfeed} if + /FMdicttop countdictstack 1 add def + /FMoptop count def + setpapername + manualfeed {true} {papersize} ifelse + {manualpapersize} {false} ifelse + {desperatepapersize} {false} ifelse + { (Can't select requested paper size for Frame print job!) FMFAILURE } if + count -1 FMoptop {pop pop} for + countdictstack -1 FMdicttop {pop end} for + } + {{1 dict dup /PageSize [paperwidth paperheight]put setpagedevice}stopped + { (Can't select requested paper size for Frame print job!) FMFAILURE } if + {1 dict dup /ManualFeed manualfeed put setpagedevice } stopped pop } + ifelse + + FMPColor { + currentcolorscreen + cvlit /orgproc exch def + /organgle exch def + /orgfreq exch def + cvlit /orgbproc exch def + /orgbangle exch def + /orgbfreq exch def + cvlit /orggproc exch def + /orggangle exch def + /orggfreq exch def + cvlit /orgrproc exch def + /orgrangle exch def + /orgrfreq exch def + currentcolortransfer + FrameNegative { + 1 1 4 { + pop { 1 exch sub } concatprocs 4 1 roll + } for + 4 copy + setcolortransfer + } if + cvlit /orgxfer exch def + cvlit /orgbxfer exch def + cvlit /orggxfer exch def + cvlit /orgrxfer exch def + } { + currentscreen + cvlit /orgproc exch def + /organgle exch def + /orgfreq exch def + + currenttransfer + FrameNegative { + { 1 exch sub } concatprocs + dup settransfer + } if + cvlit /orgxfer exch def + } ifelse + end +} def +/pagesave FMLOCAL +/orgmatrix FMLOCAL +/landscape FMLOCAL +/pwid FMLOCAL +/FMBEGINPAGE { + FrameDict begin + /pagesave save def + 3.86 setmiterlimit + /landscape exch 0 ne def + landscape { + 90 rotate 0 exch dup /pwid exch def neg translate pop + }{ + pop /pwid exch def + } ifelse + edown { [-1 0 0 1 pwid 0] concat } if + 0 0 moveto paperwidth 0 lineto paperwidth paperheight lineto + 0 paperheight lineto 0 0 lineto 1 setgray fill + xscale yscale scale + /orgmatrix matrix def + gsave +} def +/FMENDPAGE { + grestore + pagesave restore + end + showpage + } def +/FMFONTDEFINE { + FrameDict begin + findfont + ReEncode + 1 index exch + definefont + FMfonts 3 1 roll + put + end + } def +/FMFILLS { + FrameDict begin dup + array /fillvals exch def + dict /patCache exch def + end + } def +/FMFILL { + FrameDict begin + fillvals 3 1 roll put + end + } def +/FMNORMALIZEGRAPHICS { + newpath + 0.0 0.0 moveto + 1 setlinewidth + 0 setlinecap + 0 0 0 sethsbcolor + 0 setgray + } bind def + /fx FMLOCAL + /fy FMLOCAL + /fh FMLOCAL + /fw FMLOCAL + /llx FMLOCAL + /lly FMLOCAL + /urx FMLOCAL + /ury FMLOCAL +/FMBEGINEPSF { + end + /FMEPSF save def + /showpage {} def +% See Adobe's "PostScript Language Reference Manual, 2nd Edition", page 714. +% "...the following operators MUST NOT be used in an EPS file:" (emphasis ours) + /banddevice {(banddevice) FMBADEPSF} def + /clear {(clear) FMBADEPSF} def + /cleardictstack {(cleardictstack) FMBADEPSF} def + /copypage {(copypage) FMBADEPSF} def + /erasepage {(erasepage) FMBADEPSF} def + /exitserver {(exitserver) FMBADEPSF} def + /framedevice {(framedevice) FMBADEPSF} def + /grestoreall {(grestoreall) FMBADEPSF} def + /initclip {(initclip) FMBADEPSF} def + /initgraphics {(initgraphics) FMBADEPSF} def + /initmatrix {(initmatrix) FMBADEPSF} def + /quit {(quit) FMBADEPSF} def + /renderbands {(renderbands) FMBADEPSF} def + /setglobal {(setglobal) FMBADEPSF} def + /setpagedevice {(setpagedevice) FMBADEPSF} def + /setshared {(setshared) FMBADEPSF} def + /startjob {(startjob) FMBADEPSF} def + /lettertray {(lettertray) FMBADEPSF} def + /letter {(letter) FMBADEPSF} def + /lettersmall {(lettersmall) FMBADEPSF} def + /11x17tray {(11x17tray) FMBADEPSF} def + /11x17 {(11x17) FMBADEPSF} def + /ledgertray {(ledgertray) FMBADEPSF} def + /ledger {(ledger) FMBADEPSF} def + /legaltray {(legaltray) FMBADEPSF} def + /legal {(legal) FMBADEPSF} def + /statementtray {(statementtray) FMBADEPSF} def + /statement {(statement) FMBADEPSF} def + /executivetray {(executivetray) FMBADEPSF} def + /executive {(executive) FMBADEPSF} def + /a3tray {(a3tray) FMBADEPSF} def + /a3 {(a3) FMBADEPSF} def + /a4tray {(a4tray) FMBADEPSF} def + /a4 {(a4) FMBADEPSF} def + /a4small {(a4small) FMBADEPSF} def + /b4tray {(b4tray) FMBADEPSF} def + /b4 {(b4) FMBADEPSF} def + /b5tray {(b5tray) FMBADEPSF} def + /b5 {(b5) FMBADEPSF} def + FMNORMALIZEGRAPHICS + [/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall + fx fw 2 div add fy fh 2 div add translate + rotate + fw 2 div neg fh 2 div neg translate + fw urx llx sub div fh ury lly sub div scale + llx neg lly neg translate + /FMdicttop countdictstack 1 add def + /FMoptop count def + } bind def +/FMENDEPSF { + count -1 FMoptop {pop pop} for + countdictstack -1 FMdicttop {pop end} for + FMEPSF restore + FrameDict begin + } bind def +FrameDict begin +/setmanualfeed { +%%BeginFeature *ManualFeed True + statusdict /manualfeed true put +%%EndFeature + } bind def +/max {2 copy lt {exch} if pop} bind def +/min {2 copy gt {exch} if pop} bind def +/inch {72 mul} def +/pagedimen { + paperheight sub abs 16 lt exch + paperwidth sub abs 16 lt and + {/papername exch def} {pop} ifelse + } bind def + /papersizedict FMLOCAL +/setpapername { + /papersizedict 14 dict def + papersizedict begin + /papername /unknown def + /Letter 8.5 inch 11.0 inch pagedimen + /LetterSmall 7.68 inch 10.16 inch pagedimen + /Tabloid 11.0 inch 17.0 inch pagedimen + /Ledger 17.0 inch 11.0 inch pagedimen + /Legal 8.5 inch 14.0 inch pagedimen + /Statement 5.5 inch 8.5 inch pagedimen + /Executive 7.5 inch 10.0 inch pagedimen + /A3 11.69 inch 16.5 inch pagedimen + /A4 8.26 inch 11.69 inch pagedimen + /A4Small 7.47 inch 10.85 inch pagedimen + /B4 10.125 inch 14.33 inch pagedimen + /B5 7.16 inch 10.125 inch pagedimen + end + } bind def +/papersize { + papersizedict begin + /Letter {lettertray letter} def + /LetterSmall {lettertray lettersmall} def + /Tabloid {11x17tray 11x17} def + /Ledger {ledgertray ledger} def + /Legal {legaltray legal} def + /Statement {statementtray statement} def + /Executive {executivetray executive} def + /A3 {a3tray a3} def + /A4 {a4tray a4} def + /A4Small {a4tray a4small} def + /B4 {b4tray b4} def + /B5 {b5tray b5} def + /unknown {unknown} def + papersizedict dup papername known {papername} {/unknown} ifelse get + end + statusdict begin stopped end + } bind def +/manualpapersize { + papersizedict begin + /Letter {letter} def + /LetterSmall {lettersmall} def + /Tabloid {11x17} def + /Ledger {ledger} def + /Legal {legal} def + /Statement {statement} def + /Executive {executive} def + /A3 {a3} def + /A4 {a4} def + /A4Small {a4small} def + /B4 {b4} def + /B5 {b5} def + /unknown {unknown} def + papersizedict dup papername known {papername} {/unknown} ifelse get + end + stopped + } bind def +/desperatepapersize { + statusdict /setpageparams known + { + paperwidth paperheight 0 1 + statusdict begin + {setpageparams} stopped + end + } {true} ifelse + } bind def +/DiacriticEncoding [ +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl +/numbersign /dollar /percent /ampersand /quotesingle /parenleft +/parenright /asterisk /plus /comma /hyphen /period /slash /zero /one +/two /three /four /five /six /seven /eight /nine /colon /semicolon +/less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K +/L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash +/bracketright /asciicircum /underscore /grave /a /b /c /d /e /f /g /h +/i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar +/braceright /asciitilde /.notdef /Adieresis /Aring /Ccedilla /Eacute +/Ntilde /Odieresis /Udieresis /aacute /agrave /acircumflex /adieresis +/atilde /aring /ccedilla /eacute /egrave /ecircumflex /edieresis +/iacute /igrave /icircumflex /idieresis /ntilde /oacute /ograve +/ocircumflex /odieresis /otilde /uacute /ugrave /ucircumflex +/udieresis /dagger /.notdef /cent /sterling /section /bullet +/paragraph /germandbls /registered /copyright /trademark /acute +/dieresis /.notdef /AE /Oslash /.notdef /.notdef /.notdef /.notdef +/yen /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/ordfeminine /ordmasculine /.notdef /ae /oslash /questiondown +/exclamdown /logicalnot /.notdef /florin /.notdef /.notdef +/guillemotleft /guillemotright /ellipsis /.notdef /Agrave /Atilde +/Otilde /OE /oe /endash /emdash /quotedblleft /quotedblright +/quoteleft /quoteright /.notdef /.notdef /ydieresis /Ydieresis +/fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl +/periodcentered /quotesinglbase /quotedblbase /perthousand +/Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute +/Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve +/Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron +/breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron +] def +/ReEncode { + dup + length + dict begin + { + 1 index /FID ne + {def} + {pop pop} ifelse + } forall + 0 eq {/Encoding DiacriticEncoding def} if + currentdict + end + } bind def +FMPColor + + { + /BEGINBITMAPCOLOR { + BITMAPCOLOR} def + /BEGINBITMAPCOLORc { + BITMAPCOLORc} def + /BEGINBITMAPTRUECOLOR { + BITMAPTRUECOLOR } def + /BEGINBITMAPTRUECOLORc { + BITMAPTRUECOLORc } def + } + + { + /BEGINBITMAPCOLOR { + BITMAPGRAY} def + /BEGINBITMAPCOLORc { + BITMAPGRAYc} def + /BEGINBITMAPTRUECOLOR { + BITMAPTRUEGRAY } def + /BEGINBITMAPTRUECOLORc { + BITMAPTRUEGRAYc } def + } +ifelse +/K { + FMPrintAllColorsAsBlack { + dup 1 eq 2 index 1 eq and 3 index 1 eq and not + {7 {pop} repeat 0 0 0 1 0 0 0} if + } if + FrameCurColors astore + pop combineColor +} bind def +/graymode true def + /bwidth FMLOCAL + /bpside FMLOCAL + /bstring FMLOCAL + /onbits FMLOCAL + /offbits FMLOCAL + /xindex FMLOCAL + /yindex FMLOCAL + /x FMLOCAL + /y FMLOCAL +/setPatternMode { + FMLevel1 { + /bwidth exch def + /bpside exch def + /bstring exch def + /onbits 0 def /offbits 0 def + freq sangle landscape {90 add} if + {/y exch def + /x exch def + /xindex x 1 add 2 div bpside mul cvi def + /yindex y 1 add 2 div bpside mul cvi def + bstring yindex bwidth mul xindex 8 idiv add get + 1 7 xindex 8 mod sub bitshift and 0 ne FrameNegative {not} if + {/onbits onbits 1 add def 1} + {/offbits offbits 1 add def 0} + ifelse + } + setscreen + offbits offbits onbits add div FrameNegative {1.0 exch sub} if + /FrameCurGray exch def + } { + pop pop + dup patCache exch known { + patCache exch get + } { + dup + patDict /bstring 3 -1 roll put + patDict + 9 PatFreq screenIndex get div dup matrix scale + makepattern + dup + patCache 4 -1 roll 3 -1 roll put + } ifelse + /FrameCurGray 0 def + /FrameCurPat exch def + } ifelse + /graymode false def + combineColor +} bind def +/setGrayScaleMode { + graymode not { + /graymode true def + FMLevel1 { + setCurrentScreen + } if + } if + /FrameCurGray exch def + combineColor +} bind def +/normalize { + transform round exch round exch itransform + } bind def +/dnormalize { + dtransform round exch round exch idtransform + } bind def +/lnormalize { + 0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop + } bind def +/H { + lnormalize setlinewidth + } bind def +/Z { + setlinecap + } bind def + +/PFill { + graymode FMLevel1 or not { + gsave 1 setgray eofill grestore + } if +} bind def +/PStroke { + graymode FMLevel1 or not { + gsave 1 setgray stroke grestore + } if + stroke +} bind def + /fillvals FMLOCAL +/X { + fillvals exch get + dup type /stringtype eq + {8 1 setPatternMode} + {setGrayScaleMode} + ifelse + } bind def +/V { + PFill gsave eofill grestore + } bind def +/Vclip { + clip + } bind def +/Vstrk { + currentlinewidth exch setlinewidth PStroke setlinewidth + } bind def +/N { + PStroke + } bind def +/Nclip { + strokepath clip newpath + } bind def +/Nstrk { + currentlinewidth exch setlinewidth PStroke setlinewidth + } bind def +/M {newpath moveto} bind def +/E {lineto} bind def +/D {curveto} bind def +/O {closepath} bind def + /n FMLOCAL +/L { + /n exch def + newpath + normalize + moveto + 2 1 n {pop normalize lineto} for + } bind def +/Y { + L + closepath + } bind def + /x1 FMLOCAL + /x2 FMLOCAL + /y1 FMLOCAL + /y2 FMLOCAL +/R { + /y2 exch def + /x2 exch def + /y1 exch def + /x1 exch def + x1 y1 + x2 y1 + x2 y2 + x1 y2 + 4 Y + } bind def + /rad FMLOCAL +/rarc + {rad + arcto + } bind def +/RR { + /rad exch def + normalize + /y2 exch def + /x2 exch def + normalize + /y1 exch def + /x1 exch def + mark + newpath + { + x1 y1 rad add moveto + x1 y2 x2 y2 rarc + x2 y2 x2 y1 rarc + x2 y1 x1 y1 rarc + x1 y1 x1 y2 rarc + closepath + } stopped {x1 y1 x2 y2 R} if + cleartomark + } bind def +/RRR { + /rad exch def + normalize /y4 exch def /x4 exch def + normalize /y3 exch def /x3 exch def + normalize /y2 exch def /x2 exch def + normalize /y1 exch def /x1 exch def + newpath + normalize moveto + mark + { + x2 y2 x3 y3 rarc + x3 y3 x4 y4 rarc + x4 y4 x1 y1 rarc + x1 y1 x2 y2 rarc + closepath + } stopped + {x1 y1 x2 y2 x3 y3 x4 y4 newpath moveto lineto lineto lineto closepath} if + cleartomark + } bind def +/C { + grestore + gsave + R + clip + setCurrentScreen +} bind def +/CP { + grestore + gsave + Y + clip + setCurrentScreen +} bind def + /FMpointsize FMLOCAL +/F { + FMfonts exch get + FMpointsize scalefont + setfont + } bind def +/Q { + /FMpointsize exch def + F + } bind def +/T { + moveto show + } bind def +/RF { + rotate + 0 ne {-1 1 scale} if + } bind def +/TF { + gsave + moveto + RF + show + grestore + } bind def +/P { + moveto + 0 32 3 2 roll widthshow + } bind def +/PF { + gsave + moveto + RF + 0 32 3 2 roll widthshow + grestore + } bind def +/S { + moveto + 0 exch ashow + } bind def +/SF { + gsave + moveto + RF + 0 exch ashow + grestore + } bind def +/B { + moveto + 0 32 4 2 roll 0 exch awidthshow + } bind def +/BF { + gsave + moveto + RF + 0 32 4 2 roll 0 exch awidthshow + grestore + } bind def +/G { + gsave + newpath + normalize translate 0.0 0.0 moveto + dnormalize scale + 0.0 0.0 1.0 5 3 roll arc + closepath + PFill fill + grestore + } bind def +/Gstrk { + savematrix + newpath + 2 index 2 div add exch 3 index 2 div sub exch + normalize 2 index 2 div sub exch 3 index 2 div add exch + translate + scale + 0.0 0.0 1.0 5 3 roll arc + restorematrix + currentlinewidth exch setlinewidth PStroke setlinewidth + } bind def +/Gclip { + newpath + savematrix + normalize translate 0.0 0.0 moveto + dnormalize scale + 0.0 0.0 1.0 5 3 roll arc + closepath + clip newpath + restorematrix + } bind def +/GG { + gsave + newpath + normalize translate 0.0 0.0 moveto + rotate + dnormalize scale + 0.0 0.0 1.0 5 3 roll arc + closepath + PFill + fill + grestore + } bind def +/GGclip { + savematrix + newpath + normalize translate 0.0 0.0 moveto + rotate + dnormalize scale + 0.0 0.0 1.0 5 3 roll arc + closepath + clip newpath + restorematrix + } bind def +/GGstrk { + savematrix + newpath + normalize translate 0.0 0.0 moveto + rotate + dnormalize scale + 0.0 0.0 1.0 5 3 roll arc + closepath + restorematrix + currentlinewidth exch setlinewidth PStroke setlinewidth + } bind def +/A { + gsave + savematrix + newpath + 2 index 2 div add exch 3 index 2 div sub exch + normalize 2 index 2 div sub exch 3 index 2 div add exch + translate + scale + 0.0 0.0 1.0 5 3 roll arc + restorematrix + PStroke + grestore + } bind def +/Aclip { + newpath + savematrix + normalize translate 0.0 0.0 moveto + dnormalize scale + 0.0 0.0 1.0 5 3 roll arc + closepath + strokepath clip newpath + restorematrix +} bind def +/Astrk { + Gstrk +} bind def +/AA { + gsave + savematrix + newpath + + 3 index 2 div add exch 4 index 2 div sub exch + + normalize 3 index 2 div sub exch 4 index 2 div add exch + translate + rotate + scale + 0.0 0.0 1.0 5 3 roll arc + restorematrix + PStroke + grestore + } bind def +/AAclip { + savematrix + newpath + normalize translate 0.0 0.0 moveto + rotate + dnormalize scale + 0.0 0.0 1.0 5 3 roll arc + closepath + strokepath clip newpath + restorematrix +} bind def +/AAstrk { + GGstrk +} bind def + /x FMLOCAL + /y FMLOCAL + /w FMLOCAL + /h FMLOCAL + /xx FMLOCAL + /yy FMLOCAL + /ww FMLOCAL + /hh FMLOCAL + /FMsaveobject FMLOCAL + /FMoptop FMLOCAL + /FMdicttop FMLOCAL +/BEGINPRINTCODE { + /FMdicttop countdictstack 1 add def + /FMoptop count 7 sub def + /FMsaveobject save def + userdict begin + /showpage {} def + FMNORMALIZEGRAPHICS + 3 index neg 3 index neg translate + } bind def +/ENDPRINTCODE { + count -1 FMoptop {pop pop} for + countdictstack -1 FMdicttop {pop end} for + FMsaveobject restore + } bind def +/gn { + 0 + { 46 mul + cf read pop + 32 sub + dup 46 lt {exit} if + 46 sub add + } loop + add + } bind def + /str FMLOCAL +/cfs { + /str sl string def + 0 1 sl 1 sub {str exch val put} for + str def + } bind def +/ic [ + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223 + 0 + {0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx} + {10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx} + {19 hx} {gn hx} {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} + {13} {14} {15} {16} {17} {18} {19} {gn} {0 wh} {1 wh} {2 wh} {3 wh} + {4 wh} {5 wh} {6 wh} {7 wh} {8 wh} {9 wh} {10 wh} {11 wh} {12 wh} + {13 wh} {14 wh} {gn wh} {0 bl} {1 bl} {2 bl} {3 bl} {4 bl} {5 bl} {6 bl} + {7 bl} {8 bl} {9 bl} {10 bl} {11 bl} {12 bl} {13 bl} {14 bl} {gn bl} + {0 fl} {1 fl} {2 fl} {3 fl} {4 fl} {5 fl} {6 fl} {7 fl} {8 fl} {9 fl} + {10 fl} {11 fl} {12 fl} {13 fl} {14 fl} {gn fl} + ] def + /sl FMLOCAL + /val FMLOCAL + /ws FMLOCAL + /im FMLOCAL + /bs FMLOCAL + /cs FMLOCAL + /len FMLOCAL + /pos FMLOCAL +/ms { + /sl exch def + /val 255 def + /ws cfs + /im cfs + /val 0 def + /bs cfs + /cs cfs + } bind def +400 ms +/ip { + is + 0 + cf cs readline pop + { ic exch get exec + add + } forall + pop + + } bind def +/rip { + + + bis ris copy pop + is + 0 + cf cs readline pop + { ic exch get exec + add + } forall + pop pop + ris gis copy pop + dup is exch + + cf cs readline pop + { ic exch get exec + add + } forall + pop pop + gis bis copy pop + dup add is exch + + cf cs readline pop + { ic exch get exec + add + } forall + pop + + } bind def +/wh { + /len exch def + /pos exch def + ws 0 len getinterval im pos len getinterval copy pop + pos len + } bind def +/bl { + /len exch def + /pos exch def + bs 0 len getinterval im pos len getinterval copy pop + pos len + } bind def +/s1 1 string def +/fl { + /len exch def + /pos exch def + /val cf s1 readhexstring pop 0 get def + pos 1 pos len add 1 sub {im exch val put} for + pos len + } bind def +/hx { + 3 copy getinterval + cf exch readhexstring pop pop + } bind def + /h FMLOCAL + /w FMLOCAL + /d FMLOCAL + /lb FMLOCAL + /bitmapsave FMLOCAL + /is FMLOCAL + /cf FMLOCAL +/wbytes { + dup dup + 24 eq { pop pop 3 mul } + { 8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse } ifelse + } bind def +/BEGINBITMAPBWc { + 1 {} COMMONBITMAPc + } bind def +/BEGINBITMAPGRAYc { + 8 {} COMMONBITMAPc + } bind def +/BEGINBITMAP2BITc { + 2 {} COMMONBITMAPc + } bind def +/COMMONBITMAPc { + + /r exch def + /d exch def + gsave + + 3 index 2 div add exch + 4 index 2 div add exch + translate + rotate + 1 index 2 div neg + 1 index 2 div neg + translate + scale + /h exch def /w exch def + /lb w d wbytes def + sl lb lt {lb ms} if + /bitmapsave save def + r + /is im 0 lb getinterval def + ws 0 lb getinterval is copy pop + /cf currentfile def + w h d [w 0 0 h neg 0 h] + {ip} image + bitmapsave restore + grestore + } bind def +/BEGINBITMAPBW { + 1 {} COMMONBITMAP + } bind def +/BEGINBITMAPGRAY { + 8 {} COMMONBITMAP + } bind def +/BEGINBITMAP2BIT { + 2 {} COMMONBITMAP + } bind def +/COMMONBITMAP { + /r exch def + /d exch def + gsave + + 3 index 2 div add exch + 4 index 2 div add exch + translate + rotate + 1 index 2 div neg + 1 index 2 div neg + translate + scale + /h exch def /w exch def + /bitmapsave save def + r + /is w d wbytes string def + /cf currentfile def + w h d [w 0 0 h neg 0 h] + {cf is readhexstring pop} image + bitmapsave restore + grestore + } bind def +/ngrayt 256 array def +/nredt 256 array def +/nbluet 256 array def +/ngreent 256 array def + /gryt FMLOCAL + /blut FMLOCAL + /grnt FMLOCAL + /redt FMLOCAL + /indx FMLOCAL + /cynu FMLOCAL + /magu FMLOCAL + /yelu FMLOCAL + /k FMLOCAL + /u FMLOCAL +FMLevel1 { +/colorsetup { + currentcolortransfer + /gryt exch def + /blut exch def + /grnt exch def + /redt exch def + 0 1 255 { + /indx exch def + /cynu 1 red indx get 255 div sub def + /magu 1 green indx get 255 div sub def + /yelu 1 blue indx get 255 div sub def + /k cynu magu min yelu min def + /u k currentundercolorremoval exec def +% /u 0 def + nredt indx 1 0 cynu u sub max sub redt exec put + ngreent indx 1 0 magu u sub max sub grnt exec put + nbluet indx 1 0 yelu u sub max sub blut exec put + ngrayt indx 1 k currentblackgeneration exec sub gryt exec put + } for + {255 mul cvi nredt exch get} + {255 mul cvi ngreent exch get} + {255 mul cvi nbluet exch get} + {255 mul cvi ngrayt exch get} + setcolortransfer + {pop 0} setundercolorremoval + {} setblackgeneration + } bind def +} +{ +/colorSetup2 { + [ /Indexed /DeviceRGB 255 + {dup red exch get 255 div + exch dup green exch get 255 div + exch blue exch get 255 div} + ] setcolorspace +} bind def +} ifelse + /tran FMLOCAL +/fakecolorsetup { + /tran 256 string def + 0 1 255 {/indx exch def + tran indx + red indx get 77 mul + green indx get 151 mul + blue indx get 28 mul + add add 256 idiv put} for + currenttransfer + {255 mul cvi tran exch get 255.0 div} + exch concatprocs settransfer +} bind def +/BITMAPCOLOR { + /d 8 def + gsave + + 3 index 2 div add exch + 4 index 2 div add exch + translate + rotate + 1 index 2 div neg + 1 index 2 div neg + translate + scale + /h exch def /w exch def + /bitmapsave save def + FMLevel1 { + colorsetup + /is w d wbytes string def + /cf currentfile def + w h d [w 0 0 h neg 0 h] + {cf is readhexstring pop} {is} {is} true 3 colorimage + } { + colorSetup2 + /is w d wbytes string def + /cf currentfile def + 7 dict dup begin + /ImageType 1 def + /Width w def + /Height h def + /ImageMatrix [w 0 0 h neg 0 h] def + /DataSource {cf is readhexstring pop} bind def + /BitsPerComponent d def + /Decode [0 255] def + end image + } ifelse + bitmapsave restore + grestore + } bind def +/BITMAPCOLORc { + /d 8 def + gsave + + 3 index 2 div add exch + 4 index 2 div add exch + translate + rotate + 1 index 2 div neg + 1 index 2 div neg + translate + scale + /h exch def /w exch def + /lb w d wbytes def + sl lb lt {lb ms} if + /bitmapsave save def + FMLevel1 { + colorsetup + /is im 0 lb getinterval def + ws 0 lb getinterval is copy pop + /cf currentfile def + w h d [w 0 0 h neg 0 h] + {ip} {is} {is} true 3 colorimage + } { + colorSetup2 + /is im 0 lb getinterval def + ws 0 lb getinterval is copy pop + /cf currentfile def + 7 dict dup begin + /ImageType 1 def + /Width w def + /Height h def + /ImageMatrix [w 0 0 h neg 0 h] def + /DataSource {ip} bind def + /BitsPerComponent d def + /Decode [0 255] def + end image + } ifelse + bitmapsave restore + grestore + } bind def +/BITMAPTRUECOLORc { + /d 24 def + gsave + + 3 index 2 div add exch + 4 index 2 div add exch + translate + rotate + 1 index 2 div neg + 1 index 2 div neg + translate + scale + /h exch def /w exch def + /lb w d wbytes def + sl lb lt {lb ms} if + /bitmapsave save def + + /is im 0 lb getinterval def + /ris im 0 w getinterval def + /gis im w w getinterval def + /bis im w 2 mul w getinterval def + + ws 0 lb getinterval is copy pop + /cf currentfile def + w h 8 [w 0 0 h neg 0 h] + {w rip pop ris} {gis} {bis} true 3 colorimage + bitmapsave restore + grestore + } bind def +/BITMAPTRUECOLOR { + gsave + + 3 index 2 div add exch + 4 index 2 div add exch + translate + rotate + 1 index 2 div neg + 1 index 2 div neg + translate + scale + /h exch def /w exch def + /bitmapsave save def + /is w string def + /gis w string def + /bis w string def + /cf currentfile def + w h 8 [w 0 0 h neg 0 h] + { cf is readhexstring pop } + { cf gis readhexstring pop } + { cf bis readhexstring pop } + true 3 colorimage + bitmapsave restore + grestore + } bind def +/BITMAPTRUEGRAYc { + /d 24 def + gsave + + 3 index 2 div add exch + 4 index 2 div add exch + translate + rotate + 1 index 2 div neg + 1 index 2 div neg + translate + scale + /h exch def /w exch def + /lb w d wbytes def + sl lb lt {lb ms} if + /bitmapsave save def + + /is im 0 lb getinterval def + /ris im 0 w getinterval def + /gis im w w getinterval def + /bis im w 2 mul w getinterval def + ws 0 lb getinterval is copy pop + /cf currentfile def + w h 8 [w 0 0 h neg 0 h] + {w rip pop ris gis bis w gray} image + bitmapsave restore + grestore + } bind def +/ww FMLOCAL +/r FMLOCAL +/g FMLOCAL +/b FMLOCAL +/i FMLOCAL +/gray { + /ww exch def + /b exch def + /g exch def + /r exch def + 0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul + b i get .114 mul add add r i 3 -1 roll floor cvi put } for + r + } bind def +/BITMAPTRUEGRAY { + gsave + + 3 index 2 div add exch + 4 index 2 div add exch + translate + rotate + 1 index 2 div neg + 1 index 2 div neg + translate + scale + /h exch def /w exch def + /bitmapsave save def + /is w string def + /gis w string def + /bis w string def + /cf currentfile def + w h 8 [w 0 0 h neg 0 h] + { cf is readhexstring pop + cf gis readhexstring pop + cf bis readhexstring pop w gray} image + bitmapsave restore + grestore + } bind def +/BITMAPGRAY { + 8 {fakecolorsetup} COMMONBITMAP + } bind def +/BITMAPGRAYc { + 8 {fakecolorsetup} COMMONBITMAPc + } bind def +/ENDBITMAP { + } bind def +end + /ALDsave FMLOCAL + /ALDmatrix matrix def ALDmatrix currentmatrix pop +/StartALD { + /ALDsave save def + savematrix + ALDmatrix setmatrix + } bind def +/InALD { + restorematrix + } bind def +/DoneALD { + ALDsave restore + } bind def +/I { setdash } bind def +/J { [] 0 setdash } bind def +%%EndProlog +%%BeginSetup +(4.0) FMVERSION +1 1 0 0 612 792 0 1 12 FMDOCUMENT +0 0 /Times-Roman FMFONTDEFINE +1 0 /Times-Bold FMFONTDEFINE +2 0 /Times-Italic FMFONTDEFINE +3 0 /Helvetica-Bold FMFONTDEFINE +4 1 /Symbol FMFONTDEFINE +32 FMFILLS +0 0 FMFILL +1 0.1 FMFILL +2 0.3 FMFILL +3 0.5 FMFILL +4 0.7 FMFILL +5 0.9 FMFILL +6 0.97 FMFILL +7 1 FMFILL +8 <0f1e3c78f0e1c387> FMFILL +9 <0f87c3e1f0783c1e> FMFILL +10 FMFILL +11 FMFILL +12 <8142241818244281> FMFILL +13 <03060c183060c081> FMFILL +14 <8040201008040201> FMFILL +16 1 FMFILL +17 0.9 FMFILL +18 0.7 FMFILL +19 0.5 FMFILL +20 0.3 FMFILL +21 0.1 FMFILL +22 0.03 FMFILL +23 0 FMFILL +24 FMFILL +25 FMFILL +26 <3333333333333333> FMFILL +27 <0000ffff0000ffff> FMFILL +28 <7ebddbe7e7dbbd7e> FMFILL +29 FMFILL +30 <7fbfdfeff7fbfdfe> FMFILL +%%EndSetup +%%Page: "5" 1 +%%BeginPaperSize: Letter +%%EndPaperSize +612 792 0 FMBEGINPAGE +[0 0 0 1 0 0 0] +[ 0 1 1 0 1 0 0] +[ 1 0 1 0 0 1 0] +[ 1 1 0 0 0 0 1] +[ 1 0 0 0 0 1 1] +[ 0 1 0 0 1 0 1] +[ 0 0 1 0 1 1 0] + 7 FrameSetSepColors +FrameNoSep +0 0 0 1 0 0 0 K +J +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +108 54 540 54 2 L +0.25 H +2 Z +0 X +0 0 0 1 0 0 0 K +N +0 8 Q +(EPICS General Purpose CAMAC Device Support) 108 42.5 T +(August 2, 1994) 299.44 42.5 T +(5) 536 42.5 T +1 16 Q +(4.0 Futur) 108 709.33 T +(e W) 175.71 709.33 T +(ork) 201.94 709.33 T +0 12 Q +(When the usage of LAM and CTST) 108 682 T +(A) 279.01 682 T +(T call become available in the camacLib library) 286.34 682 T +(, the) 515.17 682 T +-0.17 (asynchronous device support can be implemented and the error handling can be improved) 108 668 P +(in the current CAMAC device support implementation. Some of ideas planned to be) 108 654 T +(implemented are:) 108 640 T +(1\051 optional appending an additional CAMAC function code into the P) 108 614 T +(ARAM \336eld of the) 442.21 614 T +(CAMAC address for the purpose of initialization of a CAMAC module.) 108 600 T +(2\051 optionally using hex number speci\336cation in the P) 108 574 T +(ARAM \336eld.) 360.89 574 T +(3\051 registering power) 108 548 T +(-on callbacks to automatically re-initialize modules after a crate) 205.07 548 T +(power cycle.) 108 534 T +(4\051 Support for all \337avours of block read by aai, aao and waveform record types.) 108 508 T +(5\051 support for asynchronous processing \050IOEVENT processing on a LAM\051.) 108 482 T +(6\051 error detecting and reporting.) 108 456 T +1 16 Q +(5.0 Refer) 108 415.33 T +(ences) 173.9 415.33 T +0 12 Q +([1] <> Marty W) 108 374 T +(ise, CEBAF) 362.69 374 T +([2] <> IEEE Std 758-1979) 108 348 T +([3] <>) 317.63 322 T +FMENDPAGE +%%EndPage: "5" 1 +%%Page: "4" 2 +612 792 0 FMBEGINPAGE +[0 0 0 1 0 0 0] +[ 0 1 1 0 1 0 0] +[ 1 0 1 0 0 1 0] +[ 1 1 0 0 0 0 1] +[ 1 0 0 0 0 1 1] +[ 0 1 0 0 1 0 1] +[ 0 0 1 0 1 1 0] + 7 FrameSetSepColors +FrameNoSep +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +108 54 540 54 2 L +0.25 H +2 Z +0 X +0 0 0 1 0 0 0 K +N +0 8 Q +(EPICS General Purpose CAMAC Device Support) 108 42.5 T +(August 2, 1994) 299.44 42.5 T +(4) 536 42.5 T +1 14 Q +(2.5 r) 108 710.67 T +(ead_XX\050\051 / write_XX\050\051 --- The Record Speci\336c I/O Function) 141.96 710.67 T +0 12 Q +-0.26 (The read_XX\050\051 or write_XX\050\051 function is called every time when the record is processed.) 108 684 P +-0.22 (It is record type speci\336c. In general, it performs a single or multiple CAMAC action via a) 108 670 P +(camacLib call.) 108 656 T +1 16 Q +(3.0 Installing The CAMAC Device Support Modules) 108 615.33 T +0 12 Q +(T) 108 588 T +(o make use of a CAMAC device support module in your current EPICS release, do the) 114.49 588 T +(following steps \050assumes you already have all the record support routines in your current) 108 574 T +(release\051. Refer to chapter 7 of <<) 108 560 T +2 F +(EPICS: IOC Application Developer) 267.14 560 T +(\325) 439.9 560 T +(s Guide) 442.34 560 T +0 F +(>> for how) 479.34 560 T +(to add a new type of record into a system.) 108 546 T +(Step 1: Copy .c, .h, .ascii source \336les into appropriate subdirectories) 108 520 T +(Copy dev*Camac.c to /share/src/dev) 135 500 T +(Copy devCamac.h to /share/epicsH) 135 480 T +(Step 2: Add entries in /share/ascii/devSup.ascii \336le:) 108 460 T +( \322ai\323 \322CAMAC_IO\323 \322devAiCamac\323 \322Camac\323) 135 440 T +( \322ao\323 \322CAMAC_IO\323 \322devAoCamac\323 \322Camac\323) 135 420 T +( ......) 135 400 T +(Step 3: Make new SDR) 108 380 T +( cd /share/sdr; make) 135 360 T +(Step 4: Add entries in /Vx/share/dev/Imake\336le) 108 340 T +($\050SRC\051/devAiCamac.c \134) 135 320 T +($\050SRC\051/devAoCamac.c \134) 135 300 T +( ....) 135 280 T +(devAiCamac.o \134) 135 260 T +(devAoCamac.o \134) 135 240 T +( ....) 135 220 T +(MakeObjectFromSrc\050devAiCamac\051) 135 200 T +(MakeObjectFromSrc\050devAoCamac\051) 135 180 T +(....) 135 160 T +(Step 5: Build the new make\336le of Camac Device Support for ) 108 140 T +(cd /Vx//dev; Buildit) 135 120 T +(Step 6: cd /Vx/; make _db _rec _dev iocCore) 108 100 T +FMENDPAGE +%%EndPage: "4" 2 +%%Page: "3" 3 +612 792 0 FMBEGINPAGE +[0 0 0 1 0 0 0] +[ 0 1 1 0 1 0 0] +[ 1 0 1 0 0 1 0] +[ 1 1 0 0 0 0 1] +[ 1 0 0 0 0 1 1] +[ 0 1 0 0 1 0 1] +[ 0 0 1 0 1 1 0] + 7 FrameSetSepColors +FrameNoSep +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +108 54 540 54 2 L +0.25 H +2 Z +0 X +0 0 0 1 0 0 0 K +N +0 8 Q +(EPICS General Purpose CAMAC Device Support) 108 42.5 T +(August 2, 1994) 299.44 42.5 T +(3) 536 42.5 T +3 9 Q +(NULL }) 216 714 T +(/* pointer to special_linconv */) 288 714 T +0 12 Q +(In this implementation, only three functions are implemented in each device support) 108 693 T +(module: a general init function, a record speci\336c function and a record speci\336c I/O func-) 108 679 T +(tion.) 108 665 T +1 14 Q +(2.3 init\050\051 --- The General Initialization Function) 108 631.67 T +0 12 Q +(The init\050\051 function only is used as a dummy function for debug purposes in the current) 108 605 T +(implementation. It is called twice at ioc initialization time.) 108 591 T +1 14 Q +(2.4 init_r) 108 557.67 T +(ecord\050\051 --- The Record Speci\336c Initialization Function) 165.69 557.67 T +0 12 Q +(The init_record\050\051 function is called by the record support init_record function during the) 108 531 T +(record initialization time. In this CAMAC device support implementation, it does follow-) 108 517 T +(ing things:) 108 503 T +(1.) 108 483 T +(Checks if the device type of the current record is CAMAC_IO. If not, it reports illegal) 121.75 483 T +(I/O \336eld error) 121.75 469 T +(.) 187.73 469 T +(2.) 108 449 T +(Retrieves b, c, n, a, f parameters directly from the pcamacio structure) 121.75 449 T +(3.) 108 429 T +-0.47 (Retrieves the Param from pcamacio->parm by using the routine sscanf to retrieve either) 121.75 429 P +(hex or integer values. \050Note: atoi will translate hex values into 0, since it expects dec-) 121.75 415 T +(imal. The routine sscanf is much less ef) 121.75 401 T +(\336cient than atoi, but since this is only used at) 314.5 401 T +(record initialization time it should be worth the loss in ef) 121.75 387 T +(\336ciency to keep the users of) 394.18 387 T +-0.26 (records from having to remember that 24 bits of 1\325) 121.75 373 P +-0.26 (s is 16777215 in decimal. It is much) 362.35 373 P +(easier to read the parameter when using 0xf) 121.75 359 T +(f) 331.13 359 T +(f) 334.91 359 T +(f) 338.69 359 T +(f) 342.47 359 T +(f or 0x1000000.\051) 346.25 359 T +(4.) 108 327.97 T +-0.28 (For Analog records and longs if Param is of the form) 121.75 327.97 P +-0.28 (, it is set to) 414.45 327.97 P +-0.28 (. Then cal-) 488.9 327.97 P +(culates the engineering conversion slope,) 121.75 312 T +(ESLP = \050EFUL - ELOW\051/ P) 121.75 298 T +(ARAM.) 257.07 298 T +(4.1) 108 272.97 T +-0.34 (. Sets the bit-mask) 123 272.97 P +-0.34 (For Longs and Analog records sets the bit-mask to) 213.32 272.97 P +-0.34 ( where n) 496.7 272.97 P +(is the least value satisfying the inequality: For Binaries\050bi and bo\051 sets the record) 121.75 258.97 T +(MASK \336eld to 1 shifted to the left by Param bits.) 121.75 222.97 T +(4.2) 108 208.97 T +(. For Multibit binaries sets the record SHFT \336eld to Param, and shifts the record\325) 123 208.97 T +(s) 513.97 208.97 T +-0.22 (MASK \336eld to the left by Param bits. \050The record support code has already calculated) 121.75 194.97 P +(an initial value for the MASK \336eld using NOBT) 121.75 180.97 T +(.\051) 353.51 180.97 T +(5.) 108 160.97 T +-0.07 ( Mallocs an array to hold a pointer to the CAMAC register de\336ned by a call to cdreg\050\051,) 121.75 160.97 P +(a CAMAC function code and the bit-mask for passing to the record speci\336c I/O func-) 121.75 146.97 T +(tion.) 121.75 132.97 T +376.34 327.97 414.45 347 C +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 9 Q +0 X +0 0 0 1 0 0 0 K +(2) 380.14 330.28 T +2 7 Q +(n) 384.98 335.75 T +0 9 Q +(1) 397.47 330.28 T +(\320) 390.72 330.28 T +0 -208 1000 792 C +465.69 322 488.9 347 C +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 9 Q +0 X +0 0 0 1 0 0 0 K +(2) 476.23 330.28 T +2 7 Q +(n) 481.08 335.75 T +0 -208 1000 792 C +458.58 272.97 496.7 292 C +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 9 Q +0 X +0 0 0 1 0 0 0 K +(2) 462.38 275.28 T +2 7 Q +(n) 467.22 280.75 T +0 9 Q +(1) 479.72 275.28 T +(\320) 472.97 275.28 T +0 -208 1000 792 C +108 63 540 720 C +259.5 232.97 388.5 254.97 C +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 9 Q +0 X +0 0 0 1 0 0 0 K +(2) 293.8 240.97 T +2 7 Q +(n) 298.64 246.44 T +2 9 Q +(P) 311.58 240.97 T +(a) 317.61 240.97 T +(r) 322.64 240.97 T +(a) 326.67 240.97 T +(m) 331.7 240.97 T +4 F +(\263) 304.39 240.97 T +108 63 540 720 C +0 -208 1000 792 C +FMENDPAGE +%%EndPage: "3" 3 +%%Page: "2" 4 +612 792 0 FMBEGINPAGE +[0 0 0 1 0 0 0] +[ 0 1 1 0 1 0 0] +[ 1 0 1 0 0 1 0] +[ 1 1 0 0 0 0 1] +[ 1 0 0 0 0 1 1] +[ 0 1 0 0 1 0 1] +[ 0 0 1 0 1 1 0] + 7 FrameSetSepColors +FrameNoSep +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +108 54 540 54 2 L +0.25 H +2 Z +0 X +0 0 0 1 0 0 0 K +N +0 8 Q +(EPICS General Purpose CAMAC Device Support) 108 42.5 T +(August 2, 1994) 299.44 42.5 T +(2) 536 42.5 T +1 12 Q +(2.1.1 Examples of Legal Camac Addr) 108 712 T +(esses and r) 301.78 712 T +(elated \336elds) 356.89 712 T +0 F +(1.) 108 692 T +(For an analog input record \050ai\051 an example address is:) 121.75 692 T +(#B0 C1 N3 A0 F16 @0xf) 121.75 678 T +(f) 245.59 678 T +(f) 249.37 678 T +(f) 253.15 678 T +(for records whose values are in engineering units rather than bits the following \336elds) 121.75 664 T +(are also important:) 121.75 650 T +(LINR LINEAR) 121.75 636 T +(EGUF 10.0) 121.75 622 T +(EGUL -10.0) 121.75 608 T +(In this example A0 F16 is a command to read the card at branch 0 crate controller 1) 121.75 594 T +(slot 3. The parameter 0xf) 121.75 580 T +(f) 242.5 580 T +(f) 246.28 580 T +(f speci\336es that the bit mask will be the \336rst 16 bits in the) 250.06 580 T +(word, and that the linearization slope will be calculated in the device driver by the) 121.75 566 T +(equation.) 121.75 552 T +(ESLP = \05010.0 - \050-10.0\051 \051/ 0x10000.) 121.75 538 T +(2.) 108 518 T +(For a multibit binary output \050mbbo\051 an example address is:) 121.75 518 T +(OUT #B0 C1 N4 A1 F19 @2) 121.75 504 T +-0.26 (In the case of multibit binary records the NOBT \336eld is important, if it is 0 nothing will) 121.75 490 P +(be written:.) 121.75 476 T +(NOBT 4) 121.75 462 T +-0.03 (In this example the A1 F19 is a command to the Jorway 201 card in Branch 0, Crate) 121.75 448 P +(controller 1, slot 4 to selectively set lights. NOBT 4 means that a block of 4 bits will) 121.75 434 T +(be selectively set. The parameter 2 means that the block will start at bit 2 \050the 3rd bit\051) 121.75 420 T +(in the word.) 121.75 406 T +1 14 Q +(2.2 The Requir) 108 372.67 T +(ed DSET T) 201.09 372.67 T +(able Entries) 266.7 372.67 T +0 12 Q +(DSET tables \050Device Support Entry T) 108 346 T +(ables\051 are what EPICS uses to interact with device) 290.14 346 T +(support routines from record support routines. There must be one for each type of record) 108 332 T +(supported by the device support. Refer <<) 108 318 T +2 F +(EPICS: IOC Application Developer) 310.5 318 T +(\325) 483.25 318 T +(s Guide) 485.7 318 T +0 F +(>>) 522.7 318 T +(for detailed information on DSET) 108 304 T +(. A typical DSET table used in a CAMAC device sup-) 269.76 304 T +(port mdule for an input record looks like this:) 108 290 T +3 9 Q +(devXXCamac = {) 180 269 T +(6,) 216 257 T +(/* number of EPICS elements in the DSET table */) 288 257 T +(NULL,) 216 245 T +(/* pointer to report function */) 288 245 T +(init,) 216 233 T +(/* pointer to general init function */) 288 233 T +(init_record) 216 221 T +(/* pointer to record speci\336c init function */) 288 221 T +(NULL,) 216 209 T +(/* pointer to get i/o interrupt information function */) 288 209 T +(read_XX,) 216 197 T +(/* pointer to record-speci\336c I/O function */) 288 197 T +(NULL }) 216 185 T +(/* pointer to special_linconv */) 288 185 T +0 12 Q +(Similarly) 108 168 T +(, a typical DSET used for a output record device support is like this:) 151.9 168 T +3 9 Q +(devXXCamac = {) 180 147 T +(6,) 216 135 T +(/* number of EPICS elements in the DSET table */) 288 135 T +(NULL,) 216 123 T +(/* pointer to report function */) 288 123 T +(init,) 216 111 T +(/* pointer to general init function */) 288 111 T +(init_record) 216 99 T +(/* pointer to record speci\336c init function */) 288 99 T +(NULL,) 216 87 T +(/* pointer to get i/o interrupt information function */) 288 87 T +(write_XX,) 216 75 T +(/* pointer to record-speci\336c I/O function */) 288 75 T +FMENDPAGE +%%EndPage: "2" 4 +%%Page: "1" 5 +612 792 0 FMBEGINPAGE +[0 0 0 1 0 0 0] +[ 0 1 1 0 1 0 0] +[ 1 0 1 0 0 1 0] +[ 1 1 0 0 0 0 1] +[ 1 0 0 0 0 1 1] +[ 0 1 0 0 1 0 1] +[ 0 0 1 0 1 1 0] + 7 FrameSetSepColors +FrameNoSep +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +0 0 0 1 0 0 0 K +108 54 540 54 2 L +0.25 H +2 Z +0 X +0 0 0 1 0 0 0 K +N +0 8 Q +(EPICS General Purpose CAMAC Device Support) 108 42.5 T +(August 2, 1994) 299.44 42.5 T +(1) 536 42.5 T +1 18 Q +(EPICS General Purpose CAMAC Device Support) 132.26 708 T +0 12 Q +(Continuous Electron Beam Accelerator Facility) 209.68 675 T +(Southeastern Universities Research Association) 209.18 665 T +(Johnny T) 223.75 639 T +(ang, Chip W) 267.91 639 T +(atson, David Barker) 327.94 639 T +2 F +(May 1) 291.28 623 T +(1, 1994) 320.72 623 T +(Modi\336ed by Rozelle W) 219.34 607 T +(right, August 2, 1994) 326.99 607 T +(AOT) 161.93 591 T +(-8, Los Alamos National Laboratory) 183.71 591 T +(, Los Alamos, New Mexico) 358.07 591 T +1 16 Q +(1.0 Intr) 108 548.33 T +(oduction) 163.26 548.33 T +0 12 Q +(The EPICS general purpose CAMAC device support is a set of modules used to provide) 108 521 T +-0.46 (access to CAMAC modules via EPICS database records. The device support uses standard) 108 507 P +(CAMAC library calls based on IEEE std 758-1979. This library has been implemented at) 108 493 T +(CEBAF for serial highway interface. The design and the functions of the device support) 108 479 T +(modules, and how to install them into a system, are described in this documentation.) 108 465 T +1 16 Q +(2.0 The CAMAC Device Support Routines) 108 424.33 T +0 12 Q +-0.03 (Thirteen types of records currently have the CAMAC device support: ai, ao, aai, aao, bi,) 108 397 P +-0.26 (bo, li, lo, mbbi, mbbo, mbbidirect, mbbodirect and waveform. A CAMAC device support) 108 383 P +(module consists of DSET table entries and a set of function routines. Presently) 108 369 T +(, only syn-) 484.85 369 T +(chronous device support has been implemented.) 108 355 T +1 14 Q +-0.06 (2.1 Specifying Camac Device Support and Addr) 108 321.67 P +-0.06 (ess in Database Records) 396.68 321.67 P +0 12 Q +(There are two device related record \336elds to be used to specify CAMAC device support) 108 295 T +(and CAMAC address:) 108 281 T +(DTYP) 108 255 T +(Camac) 180 255 T +(INP or OUT) 108 243 T +(#Ba Cb Nc Ad Fe @param) 180 243 T +-0.13 (where a is the Branch number) 108 225 P +-0.13 (, b is the Crate number) 250.49 225 P +-0.13 (, c is the Station number) 358.67 225 P +-0.13 (, d is the Sub-) 474.19 225 P +(address and e is the Function code.) 108 211 T +(The contents of param depend on the record type. In the case of records which expect all) 108 185 T +(bits read to be used \050i.e. ai, ao, aai, aao, li,lo records\051, the parameter is used for determin-) 108 171 T +-0.09 (ing the maximum number of legal bits that can be read from or written to the Camac mod-) 108 157 P +(ule and is used to create a bit mask, which is anded with the Camac data. In the case of) 108 143 T +(analog records ai, ao, aai, and aao it is also used for calculations of engineering conver-) 108 129 T +(sion slope. In the case of binary records bi, bo, mbbi, mbbo, mbbidirect, mbbodirect it) 108 115 T +(represents the bit position of the \336rst bit to be read or written. By convention bit 0 corre-) 108 101 T +(sponds to the least signi\336cant bit.) 108 87 T +FMENDPAGE +%%EndPage: "1" 5 +%%Trailer +%%BoundingBox: 0 0 612 792 +%%PageOrder: Descend +%%Pages: 5 +%%DocumentFonts: Times-Roman +%%+ Times-Bold +%%+ Times-Italic +%%+ Helvetica-Bold +%%+ Symbol +%%EOF diff --git a/src/dev/camacDev/Makefile b/src/dev/camacDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/camacDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/camacDev/Makefile.Vx b/src/dev/camacDev/Makefile.Vx new file mode 100644 index 000000000..2830023b7 --- /dev/null +++ b/src/dev/camacDev/Makefile.Vx @@ -0,0 +1,25 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +INC += devCamac.h + + +# SRCS.c += ../devAaiCamac.c +# SRCS.c += ../devAiCamac.c +# SRCS.c += ../devAaoCamac.c +# SRCS.c += ../devAoCamac.c +# SRCS.c += ../devBiCamac.c +# SRCS.c += ../devBoCamac.c +# SRCS.c += ../devLiCamac.c +# SRCS.c += ../devLoCamac.c +# SRCS.c += ../devMbbiCamac.c +# SRCS.c += ../devMbbiDirectCamac.c +# SRCS.c += ../devMbboCamac.c +# SRCS.c += ../devMbboDirectCamac.c +# SRCS.c += ../devWfCamac.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAaiCamac.c b/src/dev/camacDev/devAaiCamac.c similarity index 100% rename from src/dev/devAaiCamac.c rename to src/dev/camacDev/devAaiCamac.c diff --git a/src/dev/devAaoCamac.c b/src/dev/camacDev/devAaoCamac.c similarity index 100% rename from src/dev/devAaoCamac.c rename to src/dev/camacDev/devAaoCamac.c diff --git a/src/dev/devAiCamac.c b/src/dev/camacDev/devAiCamac.c similarity index 100% rename from src/dev/devAiCamac.c rename to src/dev/camacDev/devAiCamac.c diff --git a/src/dev/devAoCamac.c b/src/dev/camacDev/devAoCamac.c similarity index 100% rename from src/dev/devAoCamac.c rename to src/dev/camacDev/devAoCamac.c diff --git a/src/dev/devBiCamac.c b/src/dev/camacDev/devBiCamac.c similarity index 100% rename from src/dev/devBiCamac.c rename to src/dev/camacDev/devBiCamac.c diff --git a/src/dev/devBoCamac.c b/src/dev/camacDev/devBoCamac.c similarity index 100% rename from src/dev/devBoCamac.c rename to src/dev/camacDev/devBoCamac.c diff --git a/src/dev/devCamac.h b/src/dev/camacDev/devCamac.h similarity index 100% rename from src/dev/devCamac.h rename to src/dev/camacDev/devCamac.h diff --git a/src/dev/devLiCamac.c b/src/dev/camacDev/devLiCamac.c similarity index 100% rename from src/dev/devLiCamac.c rename to src/dev/camacDev/devLiCamac.c diff --git a/src/dev/devLoCamac.c b/src/dev/camacDev/devLoCamac.c similarity index 100% rename from src/dev/devLoCamac.c rename to src/dev/camacDev/devLoCamac.c diff --git a/src/dev/devMbbiCamac.c b/src/dev/camacDev/devMbbiCamac.c similarity index 100% rename from src/dev/devMbbiCamac.c rename to src/dev/camacDev/devMbbiCamac.c diff --git a/src/dev/devMbbiDirectCamac.c b/src/dev/camacDev/devMbbiDirectCamac.c similarity index 100% rename from src/dev/devMbbiDirectCamac.c rename to src/dev/camacDev/devMbbiDirectCamac.c diff --git a/src/dev/devMbboCamac.c b/src/dev/camacDev/devMbboCamac.c similarity index 100% rename from src/dev/devMbboCamac.c rename to src/dev/camacDev/devMbboCamac.c diff --git a/src/dev/devMbboDirectCamac.c b/src/dev/camacDev/devMbboDirectCamac.c similarity index 100% rename from src/dev/devMbboDirectCamac.c rename to src/dev/camacDev/devMbboDirectCamac.c diff --git a/src/dev/devWfCamac.c b/src/dev/camacDev/devWfCamac.c similarity index 100% rename from src/dev/devWfCamac.c rename to src/dev/camacDev/devWfCamac.c diff --git a/src/dev/cometDev/Makefile b/src/dev/cometDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/cometDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/cometDev/Makefile.Vx b/src/dev/cometDev/Makefile.Vx new file mode 100644 index 000000000..4efb5959e --- /dev/null +++ b/src/dev/cometDev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devWfComet.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devWfComet.c b/src/dev/cometDev/devWfComet.c similarity index 100% rename from src/dev/devWfComet.c rename to src/dev/cometDev/devWfComet.c diff --git a/src/dev/compumotorDev/Makefile b/src/dev/compumotorDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/compumotorDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/compumotorDev/Makefile.Vx b/src/dev/compumotorDev/Makefile.Vx new file mode 100644 index 000000000..21e95b73f --- /dev/null +++ b/src/dev/compumotorDev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devSmCompumotor1830.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devSmCompumotor1830.c b/src/dev/compumotorDev/devSmCompumotor1830.c similarity index 100% rename from src/dev/devSmCompumotor1830.c rename to src/dev/compumotorDev/devSmCompumotor1830.c diff --git a/src/dev/devAB1771IFE.c b/src/dev/devAB1771IFE.c deleted file mode 100644 index 99128a378..000000000 --- a/src/dev/devAB1771IFE.c +++ /dev/null @@ -1,267 +0,0 @@ -/* devAB1771IFE.c */ -/* - * Original Author: Bob Dalesio - * Current Author: Bob Dalesio, Marty Kraimer - * Date: 3/6/91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 12-01-94 lrd combine the device support that was resident - * in the driver and device support to - significantly reduce the amount of code - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Create the dsets*/ -LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt); -LOCAL long init_1771IfeDiff(struct aiRecord *prec); -LOCAL long init_1771Ife0to5V(struct aiRecord *prec); -LOCAL long init_1771IfeMa(struct aiRecord *prec); -LOCAL long init_1771IfeSe(struct aiRecord *prec); -LOCAL long linconv_1771Ife(struct aiRecord *prec, int after); -LOCAL long read_1771Ife(struct aiRecord *prec); - -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv;} ABAIDSET; - -ABAIDSET devAiAb1771Ife={6, 0, 0, init_1771IfeDiff, - ioinfo_ai, read_1771Ife, linconv_1771Ife}; -ABAIDSET devAiAb1771Ife0to5V={6, 0, 0, init_1771Ife0to5V, - ioinfo_ai, read_1771Ife, linconv_1771Ife}; -ABAIDSET devAiAb1771IfeMa={6, 0, 0, init_1771IfeMa, - ioinfo_ai, read_1771Ife, linconv_1771Ife}; -ABAIDSET devAiAb1771IfeSe={6, 0, 0, init_1771IfeSe, - ioinfo_ai, read_1771Ife, linconv_1771Ife}; - -#define IFE_SCAN_RATE 1 -#define IFE_INITMSG_LENGTH 37 -#define IFE_DIFF_READMSG_LENGTH 12 -#define IFE_SE_READMSG_LENGTH 20 - -struct ab1771Ife_read { - unsigned short diag; /* diagnostic word */ - unsigned short urange; /* low byte - under range channels */ - unsigned short orange; /* low byte - over range channels */ - unsigned short sign; /* low byte - polarity 1 = negative */ - short data[16]; /* 16 data values (can be signed) */ -}; - -/* IFE Differential Initialization Message - from the IFE Manual */ -LOCAL short ab1771IfeDiff_initmsg[IFE_INITMSG_LENGTH] = { - 0xffff, 0xffff, /* -10 to 10 volts (signals 0 - 15) */ - 0x0700, /* signed magnitude - differential */ - 0xffff, 0x0000, /* scaled 0 - 4095 (12 bits) */ - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095 -}; -/* 1771 - IFE 0 to 5 Volt */ -LOCAL short ab1771Ife0to5v_initmsg[IFE_INITMSG_LENGTH] = { - 0x5555, 0x5555, /* 0 to 5 volts (signals 0 - 15) */ - 0x0700, /* signed magnitude - differential */ - 0x0000, 0x0000, /* scaled 0 - 4095 (12 bits) */ - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095 -}; -/* 1771 - IFE MilliAmp */ -LOCAL short ab1771IfeMa_initmsg[IFE_INITMSG_LENGTH] = { - 0x0000, 0x0000, /* 4 - 20 Ma (signals 0 - 15) */ - 0x0700, /* signed magnitude - differential */ - 0x0000, 0x0000, /* scaled 0 - 4095 (12 bits) */ - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095 -}; -/* 1771 - IFE Single Ended (-10 to 10 Volts) */ -LOCAL short ab1771IfeSe_initmsg[IFE_INITMSG_LENGTH] = { - 0xffff, 0xffff, /* 0 to 5 volts (signals 0 - 15) */ - 0x0600, /* signed magnitude - differential */ - 0xffff, 0x0000, /* scaled 0 - 4095 (12 bits) */ - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095 -}; - -typedef struct { - void *drvPvt; - IOSCANPVT ioscanpvt; - unsigned short read_msg_len; - unsigned short *pread_msg; -} devPvt; - -LOCAL void devCallback(void * drvPvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - if(!pdevPvt) return; - scanIoRequest(pdevPvt->ioscanpvt); -} - -LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)prec->dpvt; - if(!pdevPvt) return(0); - *ppvt = pdevPvt->ioscanpvt; - return(0); -} - -LOCAL long read_1771Ife(struct aiRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt= (devPvt *)prec->dpvt; - abStatus drvStatus; - struct ab1771Ife_read *pdata; - - if(!pdevPvt) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - } - pabio = (struct abio *)&(prec->inp.value); - drvStatus = (*pabDrv->getStatus)(pdevPvt->drvPvt); - pdata = (struct ab1771Ife_read *)pdevPvt->pread_msg; - if(drvStatus != abSuccess) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - } - prec->rval = pdata->data[pabio->signal]; - if( (pdata->orange & (1 << pabio->signal)) - || (pdata->urange & (1 << pabio->signal)) ) - recGblSetSevr(prec,HW_LIMIT_ALARM,INVALID_ALARM); - return(0); -} - -LOCAL long linconv_1771Ife(struct aiRecord *prec, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/4095.0; - return(0); -} - -LOCAL long init_1771Ife(struct aiRecord *prec, const char *card_type, - unsigned short *pinit_msg, unsigned short read_size) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - - /* ai.inp must be an AB_IO */ - if (prec->inp.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, - "devAiAb1771Ife (init_record) Illegal INP field"); - return(S_db_badField); - } - - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/4095.0; - /* pointer to the data addess structure */ - pabio = (struct abio *)&(prec->inp.value); - - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeAi,card_type,devCallback,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - scanIoInit(&pdevPvt->ioscanpvt); - pdevPvt->read_msg_len = read_size; - pdevPvt->pread_msg = calloc(read_size,sizeof(unsigned short)); - drvStatus = (*pabDrv->startScan)(drvPvt,IFE_SCAN_RATE, - pinit_msg,IFE_INITMSG_LENGTH,pdevPvt->pread_msg ,read_size); - if(drvStatus!=abSuccess) { - status = S_db_badField; - recGblRecordError(S_db_badField,(void *)prec, - "devAiAb1771Ife (init_record) startScan"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAiAb1771Ife (init_record) registerCard"); - break; - } - return(status); -} - -LOCAL long init_1771IfeDiff(struct aiRecord *prec) -{ - return(init_1771Ife(prec,"IFEDIFF",&ab1771IfeDiff_initmsg[0], - IFE_DIFF_READMSG_LENGTH)); -} - -LOCAL long init_1771Ife0to5V(struct aiRecord *prec) -{ - return(init_1771Ife(prec,"IFE0to5V",&ab1771Ife0to5v_initmsg[0], - IFE_DIFF_READMSG_LENGTH)); -} - -LOCAL long init_1771IfeMa(struct aiRecord *prec) -{ - return(init_1771Ife(prec,"IFEMA",&ab1771IfeMa_initmsg[0], - IFE_DIFF_READMSG_LENGTH)); -} - -LOCAL long init_1771IfeSe(struct aiRecord *prec) -{ - return(init_1771Ife(prec,"IFESE",&ab1771IfeSe_initmsg[0], - IFE_SE_READMSG_LENGTH)); -} diff --git a/src/dev/devAB1771IL.c b/src/dev/devAB1771IL.c deleted file mode 100644 index ba7464f17..000000000 --- a/src/dev/devAB1771IL.c +++ /dev/null @@ -1,195 +0,0 @@ -/* devAB1771IL.c */ -/* - * Original Author: Bob Dalesio - * Current Author: Bob Dalesio, Marty Kraimer - * Date: 3/6/91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 12-01-94 lrd combine the device support that was resident - * in the driver and device support to - significantly reduce the amount of code - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Create the dsets*/ -LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt); -LOCAL long init_1771Il(struct aiRecord *prec); -LOCAL long linconv_1771Il(struct aiRecord *prec, int after); -LOCAL long read_1771Il(struct aiRecord *prec); - -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv;} ABAIDSET; - -ABAIDSET devAiAb1771Il={6, 0, 0, init_1771Il, - ioinfo_ai, read_1771Il, linconv_1771Il}; - -#define IL_SCAN_RATE 4 -#define IL_INITMSG_LENGTH 19 -#define IL_READMSG_LENGTH 12 - -#define IL_RANGE 0xffff /* volt inp for all channels -10 - 10V */ -#define IL_DATA_FORMAT 0x600 /* signed magnitude binary */ -struct ab1771il_read { - unsigned short diag; /* diagnostic word */ - unsigned short urange; /* low byte - under range channels */ - unsigned short orange; /* low byte - over range channels */ - unsigned short sign; /* low byte - polarity 1 = negative */ - short data[8]; /* 8 data values (can be signed) */ -}; - -typedef struct { - void *drvPvt; - IOSCANPVT ioscanpvt; - unsigned short read_msg[IL_READMSG_LENGTH]; - unsigned short *pinit_msg; -} devPvt; - -LOCAL unsigned short initMsg[IL_INITMSG_LENGTH] = { - IL_RANGE,IL_DATA_FORMAT,0x0ff, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095, - 0, 0x4095, 0, 0x4095, 0, 0x4095, 0, 0x4095 -}; - -LOCAL void devCallback(void * drvPvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - if(!pdevPvt) return; - scanIoRequest(pdevPvt->ioscanpvt); -} - -LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)prec->dpvt; - if(!pdevPvt) return(0); - *ppvt = pdevPvt->ioscanpvt; - return(0); -} - -LOCAL long read_1771Il(struct aiRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt= (devPvt *)prec->dpvt; - abStatus drvStatus; - struct ab1771il_read *pdata; - - if(!pdevPvt) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - } - pabio = (struct abio *)&(prec->inp.value); - drvStatus = (*pabDrv->getStatus)(pdevPvt->drvPvt); - pdata = (struct ab1771il_read *)&pdevPvt->read_msg[0]; - if(drvStatus != abSuccess) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - } - prec->rval = pdata->data[pabio->signal]; - if((pdata->urange&(1<signal)) - || (pdata->orange&(1<signal)) ) - recGblSetSevr(prec,HW_LIMIT_ALARM,INVALID_ALARM); - return(0); -} - -static long linconv_1771Il(struct aiRecord *prec, int after) -{ - - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/4095.0; - return(0); -} - -LOCAL long init_1771Il(struct aiRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - - /* ai.inp must be an AB_IO */ - if (prec->inp.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, - "devAiAb1771Il (init_record) Illegal INP field"); - return(S_db_badField); - } - prec->eslo = (prec->eguf -prec->egul)/4095.0; - /* pointer to the data addess structure */ - pabio = (struct abio *)&(prec->inp.value); - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeAi,"IL",devCallback,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - scanIoInit(&pdevPvt->ioscanpvt); - pdevPvt->pinit_msg = initMsg; - drvStatus = (*pabDrv->startScan)(drvPvt,IL_SCAN_RATE, - pdevPvt->pinit_msg,IL_INITMSG_LENGTH, - &pdevPvt->read_msg[0],IL_READMSG_LENGTH); - if(drvStatus != abSuccess) { - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAiAb1771Il (init_record) startScan"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAiAb1771Il (init_record) registerCard"); - break; - } - return(status); -} diff --git a/src/dev/devAB1771IR.c b/src/dev/devAB1771IR.c deleted file mode 100644 index 9e573ea9a..000000000 --- a/src/dev/devAB1771IR.c +++ /dev/null @@ -1,216 +0,0 @@ -/* devAB1771IR.c */ -/* - * Original Author: Bob Dalesio - * Current Author: Bob Dalesio, Marty Kraimer - * Date: 3/6/91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 12-01-94 lrd combine the device support that was resident - * in the driver and device support to - significantly reduce the amount of code - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Create the dsets*/ -LOCAL long init_1771Ir(struct aiRecord *prec, const char *card_type, - unsigned short config); -LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt); -LOCAL long init_1771IrPlatinum(struct aiRecord *prec); -LOCAL long init_1771IrCopper(struct aiRecord *prec); -LOCAL long read_1771Ir(struct aiRecord *prec); - -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv;} ABAIDSET; - -ABAIDSET devAiAb1771IrPlatinum={6, 0, 0, init_1771IrPlatinum, - ioinfo_ai, read_1771Ir, 0}; -ABAIDSET devAiAb1771IrCopper={6, 0, 0, init_1771IrCopper, - ioinfo_ai, read_1771Ir, 0}; - -#define IR_SCAN_RATE 5 -#define IR_INITMSG_LENGTH 1 -#define IR_READMSG_LENGTH 8 - -/*Register definitions*/ -#define IR_UNITS_DEGF 0x40 -#define IR_UNITS_OHMS 0x80 -#define IR_COPPER 0x100 -#define IR_SIGNED 0x400 - - -struct ab1771Ir_read { - unsigned short status; /* status and over/under range */ - unsigned short pol_over; /* polarity and overflow */ - short data[6]; /* current values */ -}; - -typedef struct { - void *drvPvt; - IOSCANPVT ioscanpvt; - unsigned short read_msg[IR_READMSG_LENGTH]; - unsigned short write_msg; -} devPvt; - -LOCAL void devCallback(void * drvPvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - if(!pdevPvt) return; - scanIoRequest(pdevPvt->ioscanpvt); -} - -LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)prec->dpvt; - if(!pdevPvt) return(0); - *ppvt = pdevPvt->ioscanpvt; - return(0); -} - -LOCAL long read_1771Ir(struct aiRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt= (devPvt *)prec->dpvt; - abStatus drvStatus; - struct ab1771Ir_read *pdata; - - if(!pdevPvt) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - } - pabio = (struct abio *)&(prec->inp.value); - drvStatus = (*pabDrv->getStatus)(pdevPvt->drvPvt); - pdata = (struct ab1771Ir_read *)&pdevPvt->read_msg; - if(drvStatus != abSuccess) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - }else{ - unsigned short mask; - short value; - unsigned short signal = pabio->signal; - - value = (short)pdata->data[signal]; - if(pdata->pol_over& (0x100<rval = value; - mask = (1 << pabio->signal); - if((pdata->status & (1<status & (0x100<inp.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, - "devAiAb1771Ir (init_record) Illegal INP field"); - return(S_db_badField); - } - prec->linr = 0; - pabio = (struct abio *)&(prec->inp.value); - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeAi,card_type,devCallback,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - scanIoInit(&pdevPvt->ioscanpvt); - if(pabio->parm[0]=='C') { - strcpy(prec->egu,"degC"); - } else if(pabio->parm[0]=='O') { - config |= IR_UNITS_OHMS; - strcpy(prec->egu,"ohms"); - } else { - config |= IR_UNITS_DEGF; - strcpy(prec->egu,"degF"); - } - config |= IR_SIGNED; - pdevPvt->write_msg = config; - drvStatus = (*pabDrv->startScan)(drvPvt,IR_SCAN_RATE, - &pdevPvt->write_msg,IR_INITMSG_LENGTH, - pdevPvt->read_msg,IR_READMSG_LENGTH); - if(drvStatus != abSuccess) { - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAiAb1771Ir (init_record) startScan"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAiAb1771Ir (init_record) registerCard"); - break; - } - return(status); -} - -LOCAL long init_1771IrPlatinum(struct aiRecord *prec) -{ - return(init_1771Ir(prec,"IRPLATINUM",0)); -} - -LOCAL long init_1771IrCopper(struct aiRecord *prec) -{ - return(init_1771Ir(prec,"IRCOPPER",IR_COPPER)); -} diff --git a/src/dev/devAB1771IXE.c b/src/dev/devAB1771IXE.c deleted file mode 100644 index eb2410168..000000000 --- a/src/dev/devAB1771IXE.c +++ /dev/null @@ -1,268 +0,0 @@ -/* devAB1771IXE.c */ -/* - * Original Author: Bob Dalesio - * Current Author: Bob Dalesio, Marty Kraimer - * Date: 3/6/91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 12-01-94 lrd combine the device support that was resident - * in the driver and device support to - significantly reduce the amount of code - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Create the dsets*/ -LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt); -LOCAL long init_1771Ixe(struct aiRecord *prec); -LOCAL long linconv_1771Ixe(struct aiRecord *prec, int after); -LOCAL long read_1771Ixe(struct aiRecord *prec); - -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv;} ABAIDSET; - -ABAIDSET devAiAb1771Ixe={6, 0, 0, init_1771Ixe, - ioinfo_ai, read_1771Ixe, linconv_1771Ixe}; - -#define IXE_HALFSEC_RATE 5 -#define IXE_1SEC_RATE 10 -#define IXE_INITMSG_LENGTH 19 -#define IXE_READMSG_LENGTH 12 -#define IXE_NUM_CVTTYPES 14 - -typedef struct { - void *drvPvt; - IOSCANPVT ioscanpvt; - unsigned short init_msg[IXE_INITMSG_LENGTH]; - unsigned short read_msg[IXE_READMSG_LENGTH]; - unsigned short indCvt; -} devPvt; - -/* xxxxxxxxxxxxxTTT - Thermocouple Types */ -#define IXE_MILLI 0x0000 /* Millivolt input */ -#define IXE_E 0x0001 /* "E" Thermocouple */ -#define IXE_J 0x0002 /* "J" Thermocouple */ -#define IXE_K 0x0003 /* "K" Thermocouple */ -#define IXE_T 0x0004 /* "T" Thermocouple */ -#define IXE_R 0x0005 /* "R" Thermocouple */ -#define IXE_S 0x0006 /* "S" Thermocouple */ -/* xxxxxxxCxxxxxxxx - Conversion into degrees F or C */ -#define IXE_DEGC 0x0000 -#define IXE_DEGF 0x0100 -/* xxxxxFFxxxxxxxxx - Data Format */ -#define IXE_SIGNED 0x0400 /* signed magnitude " " */ -/* SSSSSxxxxxxxxxxx - Scan Rate */ -#define IXE_HALFSEC 0x2800 /* sample time = 0.5 seconds */ -#define IXE_1SEC 0x5000 /* sample time = 1.0 seconds */ -#define IXE_2SECS 0xa000 /* sample time = 2.0 seconds */ -#define IXE_3SECS 0xf000 /* sample time = 3.0 seconds */ - -#define IXE_STATUS 0xff -struct ab1771Ixe_read { - unsigned short pol_stat; /* status - polarity word */ - unsigned short out_of_range; /* under - over range channels */ - unsigned short alarms; /* inputs outside alarm limits */ - short data[8]; /* current values */ - unsigned short cjcw; /* cold junction cal word */ -}; - -/*NOTE: The following degfinitions assumes that the allowed convert types -are defined as follows: -K_DGF=2, K_DGC=3, J_DGF=4, J_DGC=5, E_DGF=6, E_DGC=7, T_DGF=8, -T_DGC=9, R_DGF=10, R_DGC=11, S_DGF=12, S_DGC=13, -THIS IS A REAL KLUDGE. WE SHOULD FIND A BETTER WAY */ -LOCAL unsigned short ixe_cvt[IXE_NUM_CVTTYPES] = { - IXE_MILLI | IXE_SIGNED | IXE_HALFSEC, - IXE_MILLI | IXE_SIGNED | IXE_HALFSEC, - IXE_K | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC, - IXE_K | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC, - IXE_J | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC, - IXE_J | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC, - IXE_E | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC, - IXE_E | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC, - IXE_T | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC, - IXE_T | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC, - IXE_R | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC, - IXE_R | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC, - IXE_S | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC, - IXE_S | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC -}; -LOCAL const char* cardName[IXE_NUM_CVTTYPES] = { - "IXE_MV","IXE_MV","IXE_KDEGF","IXE_KDEGC", - "IXE_JDEGF","IXE_JDEGC","IXE_EDEGF","IXE_EDEGC", - "IXE_TDEGF","IXE_TDEGC","IXE_RDEGF","IXE_RDEGC", - "IXS_TDEGF","IXE_SDEGC" -}; -LOCAL unsigned short scanRate[IXE_NUM_CVTTYPES] = { - IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE, - IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE, - IXE_HALFSEC_RATE,IXE_HALFSEC_RATE, - IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE,IXE_HALFSEC_RATE -}; - -LOCAL void devCallback(void * drvPvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - if(!pdevPvt) return; - scanIoRequest(pdevPvt->ioscanpvt); -} - -LOCAL long ioinfo_ai(int cmd,struct aiRecord *prec,IOSCANPVT *ppvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)prec->dpvt; - if(!pdevPvt) return(0); - *ppvt = pdevPvt->ioscanpvt; - return(0); -} - -LOCAL long read_1771Ixe(struct aiRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt= (devPvt *)prec->dpvt; - abStatus drvStatus; - struct ab1771Ixe_read *pdata; - long status; - unsigned short indCvt; - short rval; - - if(!pdevPvt) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - } - indCvt = pdevPvt->indCvt; - pabio = (struct abio *)&(prec->inp.value); - drvStatus = (*pabDrv->getStatus)(pdevPvt->drvPvt); - pdata = (struct ab1771Ixe_read *)&pdevPvt->read_msg[0]; - if(drvStatus != abSuccess) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - } - rval = pdata->data[pabio->signal]; - if((pdata->pol_stat&(0x100<signal))) rval = -rval; - if((pdata->out_of_range&(1<signal)) - || (pdata->out_of_range&(0x100<signal)) ) { - recGblSetSevr(prec,HW_LIMIT_ALARM,INVALID_ALARM); - } - if(indCvt!=0) { - prec->val = prec->rval = rval; - prec->udf = FALSE; - status=2; /*don't convert*/ - } else { - prec->rval = rval + 10000; - status = 0; - } - return(status); -} - -static long linconv_1771Ixe(struct aiRecord *prec, int after) -{ - - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/20000.0; - return(0); -} - -LOCAL long init_1771Ixe(struct aiRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - unsigned short indCvt; - - /* ai.inp must be an AB_IO */ - if (prec->inp.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, - "devAiAb1771Ixe (init_record) Illegal INP field"); - return(S_db_badField); - } - /*If conversion type is 2,...,IXE_NUM_CVTTYPES Ixe performs the conversion*/ - /* THIS SHOULD BE CHANGED */ - if(prec->linr>=2 && prec->linr linr; - prec->linr = 0; - } else { - indCvt = 0; - } - prec->eslo = (prec->eguf -prec->egul)/20000.0; - /* pointer to the data addess structure */ - pabio = (struct abio *)&(prec->inp.value); - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeAi,cardName[indCvt],devCallback,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - pdevPvt->indCvt = indCvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - scanIoInit(&pdevPvt->ioscanpvt); - pdevPvt->init_msg[0] = ixe_cvt[indCvt]; - drvStatus = (*pabDrv->startScan)(drvPvt,scanRate[indCvt], - &pdevPvt->init_msg[0],IXE_INITMSG_LENGTH, - &pdevPvt->read_msg[0],IXE_READMSG_LENGTH); - if(drvStatus != abSuccess) { - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAiAb1771Ixe (init_record) startScan"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAiAb1771Ixe (init_record) registerCard"); - break; - } - return(status); -} diff --git a/src/dev/devAB1771OFE.c b/src/dev/devAB1771OFE.c deleted file mode 100644 index fc8c45c12..000000000 --- a/src/dev/devAB1771OFE.c +++ /dev/null @@ -1,196 +0,0 @@ -/* devAB1771OFE.c */ -/* - * Original Author: Bob Dalesio - * Current Author: Bob Dalesio, Marty Kraimer - * Date: 3/6/91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 12-01-94 lrd combine the device support that was resident in the driver and - * device support to significantly reduce the amount of code - * ... - */ - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Create the dsets*/ -LOCAL long init_1771Ofe(struct aoRecord *pao); -LOCAL long write_1771Ofe(struct aoRecord *pao); -LOCAL long linconv_1771Ofe(struct aoRecord *pao, int after); -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_ao; - DEVSUPFUN special_linconv; -}ABAODSET; - -ABAODSET devAoAb1771Ofe={ 6, NULL, NULL, init_1771Ofe, NULL, - write_1771Ofe, linconv_1771Ofe}; - -#define UPDATE_RATE 100 -#define READ_MSG_LEN 5 -#define WRITE_MSG_LEN 5 - - -/* defines and structures for analog outputs */ -/* configuration word 5 for the OFE module */ -/* FxxxHHHHLLLLPPPP */ -/* F - Data Format */ -/* 0x0 specifies BCD */ -/* 0x1 specifies Binary */ -/* HHHH - Max Scaling Polarity */ -/* LLLL - Min Scaling Polarity */ -/* PPPP - Value Polarity */ -#define OFE_BINARY 0x8000 /* talk binary instead of BCD */ -#define OFE_SCALING 0x0000 /* all positive */ - -typedef struct { - void *drvPvt; - unsigned short read_msg[READ_MSG_LEN]; - unsigned short write_msg[WRITE_MSG_LEN]; -}devPvt; - -LOCAL long init_1771Ofe(struct aoRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - int failed; - int i; - - if (prec->out.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, - "devAoAb1771Ofe (init_record) Illegal INP field"); - return(S_db_badField); - } - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/4095.0; - /* pointer to the data addess structure */ - pabio = (struct abio *)&(prec->out.value); - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeAo,"OFE",NULL,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - drvStatus = (*pabDrv->getStatus)(drvPvt); - if(drvStatus==abSuccess) { - prec->rval = (unsigned short)pdevPvt->read_msg[pabio->signal]; - } else { - status = 2; - } - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - pdevPvt->write_msg[4] = OFE_BINARY | OFE_SCALING; - drvStatus = (*pabDrv->startScan)(drvPvt,UPDATE_RATE, - pdevPvt->write_msg,WRITE_MSG_LEN, - pdevPvt->read_msg ,READ_MSG_LEN); - if(drvStatus!=abSuccess) { - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAoAb1771Ofe (init_record) startScan"); - break; - } - /*wait for up to 3 seconds*/ - for(failed=0; failed<30; failed++) { - taskDelay(vxTicksPerSecond/10); - drvStatus = (*pabDrv->getStatus)(drvPvt); - if(drvStatus==abSuccess) { - prec->rval=(unsigned short)pdevPvt->read_msg[pabio->signal]; - for(i=0;i<4;i++) { - pdevPvt->write_msg[i] = pdevPvt->read_msg[i]; - } - write_1771Ofe(prec); - status = 2; - break; - } - } - status = 0; - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec, - "devAoAb1771Ofe (init_record) registerCard"); - break; - } - return(status); -} - -LOCAL long write_1771Ofe(struct aoRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - abStatus drvStatus; - void *drvPvt; - - if(!pdevPvt) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); /*dont convert*/ - } - drvPvt = pdevPvt->drvPvt; - pabio = (struct abio *)&(prec->out.value); - pdevPvt->write_msg[pabio->signal] = prec->rval; - drvStatus = (*pabDrv->updateAo)(drvPvt); - if(drvStatus!=abSuccess) { - if(recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM) && errVerbose - && (prec->stat!=WRITE_ALARM || prec->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)prec,"abDrv(updateAo)"); - } - return(0); -} - - -LOCAL long linconv_1771Ofe(struct aoRecord *prec, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/4095.0; - return(0); -} diff --git a/src/dev/devABBINARY.c b/src/dev/devABBINARY.c deleted file mode 100644 index 7ddfed754..000000000 --- a/src/dev/devABBINARY.c +++ /dev/null @@ -1,617 +0,0 @@ -/* devABBINARY.c */ -/* - * Original Author: Bob Dalesio - * Current Author: Bob Dalesio, Marty Kraimer - * Date: 3/6/91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 12-01-94 lrd combine the device support that was resident in the driver and - * device support to significantly reduce the amount of code - * ... - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct { - void *drvPvt; - IOSCANPVT ioscanpvt; -}devPvt; - - -/* Create the dsets*/ -LOCAL long ioinfo(int cmd, struct dbCommon *prec, IOSCANPVT *ppvt); -LOCAL long read_bi(struct biRecord *prec); -LOCAL long init_bi08(struct biRecord *prec); -LOCAL long init_bi16(struct biRecord *prec); -LOCAL long init_bi32(struct biRecord *prec); -LOCAL long init_bi(struct biRecord *prec,abNumBits nBits); -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi;} ABBIDSET; - -ABBIDSET devBiAb= { 5, 0, 0, init_bi08, ioinfo, read_bi}; -ABBIDSET devBiAb16= { 5, 0, 0, init_bi16, ioinfo, read_bi}; -ABBIDSET devBiAb32= { 5, 0, 0, init_bi32, ioinfo, read_bi}; - -LOCAL long read_mbbi(struct mbbiRecord *prec); -LOCAL long init_mbbi08(struct mbbiRecord *prec); -LOCAL long init_mbbi16(struct mbbiRecord *prec); -LOCAL long init_mbbi32(struct mbbiRecord *prec); -LOCAL long init_mbbi(struct mbbiRecord *prec,abNumBits nBits); -ABBIDSET devMbbiAb= { 5, 0, 0, init_mbbi08, ioinfo, read_mbbi}; -ABBIDSET devMbbiAb16={ 5, 0, 0, init_mbbi16, ioinfo, read_mbbi}; -ABBIDSET devMbbiAb32={ 5, 0, 0, init_mbbi32, ioinfo, read_mbbi}; - -LOCAL long read_mbbiDirect(struct mbbiDirectRecord *prec); -LOCAL long init_mbbiDirect08(struct mbbiDirectRecord *prec); -LOCAL long init_mbbiDirect16(struct mbbiDirectRecord *prec); -LOCAL long init_mbbiDirect32(struct mbbiDirectRecord *prec); -LOCAL long init_mbbiDirect(struct mbbiDirectRecord *prec,abNumBits nBits); -ABBIDSET devMbbiDirectAb= { 5,0,0, init_mbbiDirect08,ioinfo, read_mbbiDirect}; -ABBIDSET devMbbiDirectAb16={ 5,0,0, init_mbbiDirect16,ioinfo, read_mbbiDirect}; -ABBIDSET devMbbiDirectAb32={ 5,0,0, init_mbbiDirect32,ioinfo, read_mbbiDirect}; - -LOCAL long write_bo(struct boRecord *prec); -LOCAL long init_bo08(struct boRecord *prec); -LOCAL long init_bo16(struct boRecord *prec); -LOCAL long init_bo32(struct boRecord *prec); -LOCAL long init_bo(struct boRecord *prec,abNumBits nBits); -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_bo; -} ABBODSET; - -ABBODSET devBoAb= { 5, 0, 0, init_bo08, 0, write_bo}; -ABBODSET devBoAb16= { 5, 0, 0, init_bo16, 0, write_bo}; -ABBODSET devBoAb32= { 5, 0, 0, init_bo32, 0, write_bo}; - -LOCAL long write_mbbo(struct mbboRecord *prec); -LOCAL long init_mbbo08(struct mbboRecord *prec); -LOCAL long init_mbbo16(struct mbboRecord *prec); -LOCAL long init_mbbo32(struct mbboRecord *prec); -LOCAL long init_mbbo(struct mbboRecord *prec,abNumBits nBits); -ABBODSET devMbboAb= { 5, 0, 0, init_mbbo08, 0, write_mbbo}; -ABBODSET devMbboAb16={ 5, 0, 0, init_mbbo16, 0, write_mbbo}; -ABBODSET devMbboAb32={ 5, 0, 0, init_mbbo32, 0, write_mbbo}; - -LOCAL long write_mbboDirect(struct mbboDirectRecord *prec); -LOCAL long init_mbboDirect08(struct mbboDirectRecord *prec); -LOCAL long init_mbboDirect16(struct mbboDirectRecord *prec); -LOCAL long init_mbboDirect32(struct mbboDirectRecord *prec); -LOCAL long init_mbboDirect(struct mbboDirectRecord *prec,abNumBits nBits); -ABBODSET devMbboDirectAb= { 5, 0, 0, init_mbboDirect08, 0, write_mbboDirect}; -ABBODSET devMbboDirectAb16={ 5, 0, 0, init_mbboDirect16, 0, write_mbboDirect}; -ABBODSET devMbboDirectAb32={ 5, 0, 0, init_mbboDirect32, 0, write_mbboDirect}; - -LOCAL void devCallback(void * drvPvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - if(!pdevPvt) return; - if(!pdevPvt->ioscanpvt) return; - scanIoRequest(pdevPvt->ioscanpvt); -} - -LOCAL long ioinfo(int cmd, struct dbCommon *prec, IOSCANPVT *ppvt) -{ - devPvt *pdevPvt; - - pdevPvt = prec->dpvt; - if(!pdevPvt) return(0); - *ppvt = pdevPvt->ioscanpvt; - return(0); -} -LOCAL long init_bi08(struct biRecord *prec) -{ - return(init_bi(prec, abBit8)); -} -LOCAL long init_bi16(struct biRecord *prec) -{ - return(init_bi(prec, abBit16)); -} -LOCAL long init_bi32(struct biRecord *prec) -{ - return(init_bi(prec, abBit32)); -} - -LOCAL long init_mbbi08(struct mbbiRecord *prec) -{ - return(init_mbbi(prec, abBit8)); -} -LOCAL long init_mbbi16(struct mbbiRecord *prec) -{ - return(init_mbbi(prec, abBit16)); -} -LOCAL long init_mbbi32(struct mbbiRecord *prec) -{ - return(init_mbbi(prec, abBit32)); -} - -LOCAL long init_mbbiDirect08(struct mbbiDirectRecord *prec) -{ - return(init_mbbiDirect(prec, abBit8)); -} -LOCAL long init_mbbiDirect16(struct mbbiDirectRecord *prec) -{ - return(init_mbbiDirect(prec, abBit16)); -} -LOCAL long init_mbbiDirect32(struct mbbiDirectRecord *prec) -{ - return(init_mbbiDirect(prec, abBit32)); -} - -LOCAL long init_bo08(struct boRecord *prec) -{ - return(init_bo(prec, abBit8)); -} -LOCAL long init_bo16(struct boRecord *prec) -{ - return(init_bo(prec, abBit16)); -} -LOCAL long init_bo32(struct boRecord *prec) -{ - return(init_bo(prec, abBit32)); -} - -LOCAL long init_mbbo08(struct mbboRecord *prec) -{ - return(init_mbbo(prec, abBit8)); -} -LOCAL long init_mbbo16(struct mbboRecord *prec) -{ - return(init_mbbo(prec, abBit16)); -} -LOCAL long init_mbbo32(struct mbboRecord *prec) -{ - return(init_mbbo(prec, abBit32)); -} - -LOCAL long init_mbboDirect08(struct mbboDirectRecord *prec) -{ - return(init_mbboDirect(prec, abBit8)); -} -LOCAL long init_mbboDirect16(struct mbboDirectRecord *prec) -{ - return(init_mbboDirect(prec, abBit16)); -} -LOCAL long init_mbboDirect32(struct mbboDirectRecord *prec) -{ - return(init_mbboDirect(prec, abBit32)); -} - -LOCAL long read_bi(struct biRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - void *drvPvt; - abStatus drvStatus; - unsigned long value; - - if(!pdevPvt) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->readBi)(drvPvt,&value,prec->mask); - if(drvStatus!=abSuccess) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - prec->rval = value; - return(0); -} -LOCAL long init_bi(struct biRecord *prec,abNumBits nBits) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - - if (prec->inp.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, - "init_record: bad INP field"); - return(S_db_badField); - } - pabio = (struct abio *)&(prec->inp.value); - prec->mask=1; - prec->mask <<= pabio->signal; - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeBi,"BINARY",devCallback,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - scanIoInit(&pdevPvt->ioscanpvt); - drvStatus = (*pabDrv->setNbits)(drvPvt,nBits); - if(drvStatus!=abSuccess) { - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record setNbits"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record registerCard"); - break; - } - return(status); -} - -LOCAL long read_mbbi(struct mbbiRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - void *drvPvt; - abStatus drvStatus; - unsigned long value; - - if(!pdevPvt) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->readBi)(drvPvt,&value,prec->mask); - if(drvStatus!=abSuccess) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - prec->rval = value; - return(0); -} -LOCAL long init_mbbi(struct mbbiRecord *prec,abNumBits nBits) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - - if (prec->inp.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field"); - return(S_db_badField); - } - pabio = (struct abio *)&(prec->inp.value); - prec->shft = prec->inp.value.abio.signal; - prec->mask <<= prec->shft; - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeBi,"BINARY",devCallback,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - scanIoInit(&pdevPvt->ioscanpvt); - drvStatus = (*pabDrv->setNbits)(drvPvt,nBits); - if(drvStatus!=abSuccess) { - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record setNbits"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record registerCard"); - break; - } - return(status); -} - -LOCAL long read_mbbiDirect(struct mbbiDirectRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - void *drvPvt; - abStatus drvStatus; - unsigned long value; - - if(!pdevPvt) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->readBi)(drvPvt,&value,prec->mask); - if(drvStatus!=abSuccess) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - prec->rval = value; - return(0); -} -LOCAL long init_mbbiDirect(struct mbbiDirectRecord *prec,abNumBits nBits) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - - if (prec->inp.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field"); - return(S_db_badField); - } - pabio = (struct abio *)&(prec->inp.value); - prec->shft = prec->inp.value.abio.signal; - prec->mask <<= prec->shft; - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeBi,"BINARY",devCallback,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - scanIoInit(&pdevPvt->ioscanpvt); - drvStatus = (*pabDrv->setNbits)(drvPvt,nBits); - if(drvStatus!=abSuccess) { - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record setNbits"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record registerCard"); - break; - } - return(status); -} - -LOCAL long write_bo(struct boRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - void *drvPvt; - abStatus drvStatus; - - if(!pdevPvt) { - recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM); - return(0); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->updateBo)(drvPvt,prec->rval,prec->mask); - if(drvStatus!=abSuccess) { - recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM); - } - return(0); -} -LOCAL long init_bo(struct boRecord *prec,abNumBits nBits) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - unsigned long value; - - if (prec->out.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field"); - return(S_db_badField); - } - pabio = (struct abio *)&(prec->out.value); - prec->mask = 1; - prec->mask <<= pabio->signal; - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeBo,"BINARY",NULL,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - drvStatus = (*pabDrv->setNbits)(drvPvt,nBits); - if(drvStatus!=abSuccess) { - recGblRecordError(S_db_badField,(void *)prec, - "init_record setNbits"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record registerCard"); - return(status); - } - drvStatus = (*pabDrv->readBo)(drvPvt,&value,prec->mask); - if(drvStatus==abSuccess) { - prec->rval = value; - status = 0; - } else { - status = 2; - } - return(status); -} - -LOCAL long write_mbbo(struct mbboRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - void *drvPvt; - abStatus drvStatus; - - if(!pdevPvt) { - recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM); - return(0); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->updateBo)(drvPvt,prec->rval,prec->mask); - if(drvStatus!=abSuccess) { - recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM); - } - return(0); -} -LOCAL long init_mbbo(struct mbboRecord *prec,abNumBits nBits) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - unsigned long value; - - if (prec->out.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field"); - return(S_db_badField); - } - pabio = (struct abio *)&(prec->out.value); - prec->shft = prec->out.value.abio.signal; - prec->mask <<= prec->shft; - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeBo,"BINARY",NULL,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - drvStatus = (*pabDrv->setNbits)(drvPvt,nBits); - if(drvStatus!=abSuccess) { - recGblRecordError(S_db_badField,(void *)prec, - "init_record setNbits"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record registerCard"); - return(status); - } - drvStatus = (*pabDrv->readBo)(drvPvt,&value,prec->mask); - if(drvStatus==abSuccess) { - prec->rval = value; - status = 0; - } else { - status = 2; - } - return(status); -} - -LOCAL long write_mbboDirect(struct mbboDirectRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - void *drvPvt; - abStatus drvStatus; - unsigned long value = prec->rval; - - if(!pdevPvt) { - recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM); - return(0); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->updateBo)(drvPvt,value,prec->mask); - if(drvStatus!=abSuccess) { - recGblSetSevr(prec,WRITE_ALARM,INVALID_ALARM); - } - return(0); -} -LOCAL long init_mbboDirect(struct mbboDirectRecord *prec,abNumBits nBits) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status=0; - void *drvPvt; - unsigned long value; - - if (prec->out.type != AB_IO){ - recGblRecordError(S_db_badField,(void *)prec, "Illegal INP field"); - return(S_db_badField); - } - pabio = (struct abio *)&(prec->out.value); - prec->shft = prec->out.value.abio.signal; - prec->mask <<= prec->shft; - drvStatus = (*pabDrv->registerCard)(pabio->link,pabio->adapter, - pabio->card,typeBo,"BINARY",NULL,&drvPvt); - switch(drvStatus) { - case abSuccess : - pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt); - prec->dpvt = pdevPvt; - break; - case abNewCard : - pdevPvt = calloc(1,sizeof(devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt)(drvPvt,(void *)pdevPvt); - drvStatus = (*pabDrv->setNbits)(drvPvt,nBits); - if(drvStatus!=abSuccess) { - recGblRecordError(S_db_badField,(void *)prec, - "init_record setNbits"); - } - break; - default: - status = S_db_badField; - recGblRecordError(status,(void *)prec,"init_record registerCard"); - return(status); - } - drvStatus = (*pabDrv->readBo)(drvPvt,&value,prec->mask); - if(drvStatus==abSuccess) { - prec->rval = value; - status = 0; - } else { - status = 2; - } - return(status); -} diff --git a/src/dev/devABSLCDCM.c b/src/dev/devABSLCDCM.c deleted file mode 100644 index 11a2c04b7..000000000 --- a/src/dev/devABSLCDCM.c +++ /dev/null @@ -1,584 +0,0 @@ -/* devABSLCDCM.c */ -/* - * Original Author: Ric Claus - * Current Author: Stephanie Allison - * Date: 1/25/96 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1996, the Regents of the University of California, - * the University of Chicago Board of Governors and The Board - * of Trustees of the Leland Stanford Junior University. - * All rights reserved. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * (W-31-109-ENG-38) at Argonne National Laboratory, and - * (DE-AC03-76SF00515) at the Stanford Linear Accelerator Center. - * - * Initial development by: - * The PEP-II Low Level RF Group - * Positron Electron Project upgrade - * Stanford Linear Accelerator Center - * - * Co-developed with: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * and: - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 1-25-96 rc Created from devABBINARY.c - * .02 6-03-96 saa Added ai/ao. - + .03 9-19-96 saa Changed routine names. Added linear conv. - + .04 4-28-97 saa Changed for signed 16 bit analog values. - */ - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct -{ - void *drvPvt; - IOSCANPVT ioscanpvt; -}devPvt; - - - -/* Create the dsets*/ -LOCAL long ioinfo (int cmd, struct dbCommon *prec, IOSCANPVT *ppvt); -LOCAL long read_li (struct longinRecord *prec); -LOCAL long init_li (struct longinRecord *prec); -typedef struct -{ - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_li; -} ABLIDSET; - -ABLIDSET devLiAbSlcDcm = {5, NULL, NULL, init_li, ioinfo, read_li}; - -LOCAL long write_lo (struct longoutRecord *prec); -LOCAL long init_lo (struct longoutRecord *prec); -typedef struct -{ - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_dl; -} ABLODSET; - -ABLODSET devLoAbSlcDcm = {5, NULL, NULL, init_lo, NULL, write_lo}; - -LOCAL long read_ai(struct aiRecord *prec); -LOCAL long init_ai(struct aiRecord *prec); -LOCAL long linconv_ai(struct aiRecord *prec, int after); -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv;} ABAIDSET; - -ABAIDSET devAiAbSlcDcm = {6, NULL, NULL, init_ai, ioinfo, read_ai, - linconv_ai}; - -LOCAL long read_signed_ai(struct aiRecord *prec); -LOCAL long init_signed_ai(struct aiRecord *prec); -ABAIDSET devAiAbSlcDcmSigned = {6, NULL, NULL, init_signed_ai, ioinfo, read_signed_ai, - linconv_ai}; - -LOCAL long write_ao(struct aoRecord *prec); -LOCAL long init_ao (struct aoRecord *prec); -LOCAL long linconv_ao(struct aoRecord *prec, int after); -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_ao; - DEVSUPFUN special_linconv;} ABAODSET; - -ABAODSET devAoAbSlcDcm = {6, NULL, NULL, init_ao, NULL, write_ao, - linconv_ao}; - - -LOCAL void devCallback (void * drvPvt) -{ - devPvt *pdevPvt; - - pdevPvt = (devPvt *) (*pabDrv->getUserPvt) (drvPvt); - if (!pdevPvt) return; - if (!pdevPvt->ioscanpvt) return; - scanIoRequest (pdevPvt->ioscanpvt); -} - -LOCAL long ioinfo (int cmd, - struct dbCommon *prec, - IOSCANPVT *ppvt) -{ - devPvt *pdevPvt; - - pdevPvt = prec->dpvt; - if (!pdevPvt) return(0); - *ppvt = pdevPvt->ioscanpvt; - return (0); -} - - - -LOCAL long read_li (struct longinRecord *prec) -{ - devPvt *pdevPvt = (devPvt *) prec->dpvt; - void *drvPvt; - abStatus drvStatus; - short value[2]; - - if (!pdevPvt) - { - recGblSetSevr (prec, READ_ALARM, INVALID_ALARM); - return (2); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->readBi) (drvPvt, (unsigned long *)value, 0x0000ffff); - if (drvStatus != abSuccess) - { - recGblSetSevr (prec, READ_ALARM, INVALID_ALARM); - return (2); - } - prec->val = (long)value[1]; - - return(0); -} - - - -LOCAL long init_li (struct longinRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status = 0; - void *drvPvt; - - if (prec->inp.type != AB_IO) - { - recGblRecordError (S_db_badField, (void *) prec, "init_li: Bad INP field"); - return (S_db_badField); - } - - pabio = (struct abio *) &(prec->inp.value); - drvStatus = (*pabDrv->registerCard) (pabio->link, pabio->adapter, pabio->card, - typeBi, "BINARY", devCallback, &drvPvt); - switch (drvStatus) - { - case abSuccess : - pdevPvt = (devPvt *) (*pabDrv->getUserPvt) (drvPvt); - prec->dpvt = pdevPvt; - break; - - case abNewCard : - pdevPvt = calloc (1, sizeof (devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt) (drvPvt, (void *) pdevPvt); - scanIoInit (&pdevPvt->ioscanpvt); - drvStatus = (*pabDrv->setNbits) (drvPvt, abBit16); - if (drvStatus != abSuccess) - { - status = S_db_badField; - recGblRecordError (status, (void *) prec, "init_li: setNbits"); - } - break; - - default: - status = S_db_badField; - recGblRecordError (status, (void *)prec, "init_li: registerCard"); - break; - } - - return (status); -} - - - -LOCAL long write_lo (struct longoutRecord *prec) -{ - devPvt *pdevPvt = (devPvt *) prec->dpvt; - void *drvPvt; - abStatus drvStatus; - - if (!pdevPvt) - { - recGblSetSevr (prec, WRITE_ALARM, INVALID_ALARM); - return (0); - } - - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->updateBo) (drvPvt, prec->val, 0x0000ffff); - if (drvStatus != abSuccess) - { - recGblSetSevr (prec, WRITE_ALARM, INVALID_ALARM); - } - - return(0); -} - - - -LOCAL long init_lo (struct longoutRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status = 0; - void *drvPvt; - short value[2]; - - if (prec->out.type != AB_IO) - { - recGblRecordError (S_db_badField, (void *) prec, "init_lo: Bad OUT field"); - return (S_db_badField); - } - - pabio = (struct abio *) &(prec->out.value); - drvStatus = (*pabDrv->registerCard) (pabio->link, pabio->adapter, pabio->card, - typeBo, "BINARY", NULL, &drvPvt); - switch (drvStatus) - { - case abSuccess : - pdevPvt = (devPvt *) (*pabDrv->getUserPvt) (drvPvt); - prec->dpvt = pdevPvt; - break; - - case abNewCard : - pdevPvt = calloc (1, sizeof (devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt) (drvPvt, (void *) pdevPvt); - drvStatus = (*pabDrv->setNbits) (drvPvt, abBit16); - if (drvStatus != abSuccess) - { - status = S_db_badField; - recGblRecordError (status, (void *) prec, "init_lo: setNbits"); - return (status); - } - break; - - default: - status = S_db_badField; - printf ("init_lo: %s\n", abStatusMessage[drvStatus]); - recGblRecordError (status, (void *) prec, "init_lo: registerCard"); - return (status); - } - - drvStatus = (*pabDrv->readBo) (drvPvt, (unsigned long *)value, 0x0000ffff); - if (drvStatus == abSuccess) - { - prec->val = (long)value[1]; - status = 0; - } - else - { - status = 2; - } - - return (status); -} - - - -LOCAL long read_ai (struct aiRecord *prec) -{ - devPvt *pdevPvt = (devPvt *) prec->dpvt; - void *drvPvt; - abStatus drvStatus; - short value[2]; - - if (!pdevPvt) - { - recGblSetSevr (prec, READ_ALARM, INVALID_ALARM); - return (2); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->readBi) (drvPvt, (unsigned long *)value, 0x0000ffff); - if (drvStatus != abSuccess) - { - recGblSetSevr (prec, READ_ALARM, INVALID_ALARM); - return (2); - } - prec->rval = (long)value[1]; - - return(0); -} - -LOCAL long linconv_ai(struct aiRecord *prec, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/65535.0; - return(0); -} - - - -LOCAL long init_ai (struct aiRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status = 0; - void *drvPvt; - - if (prec->inp.type != AB_IO) - { - recGblRecordError (S_db_badField, (void *) prec, "init_ai: Bad INP field"); - return (S_db_badField); - } - - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/65535.0; - /* pointer to the data addess structure */ - pabio = (struct abio *) &(prec->inp.value); - drvStatus = (*pabDrv->registerCard) (pabio->link, pabio->adapter, pabio->card, - typeBi, "BINARY", devCallback, &drvPvt); - switch (drvStatus) - { - case abSuccess : - pdevPvt = (devPvt *) (*pabDrv->getUserPvt) (drvPvt); - prec->dpvt = pdevPvt; - break; - - case abNewCard : - pdevPvt = calloc (1, sizeof (devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt) (drvPvt, (void *) pdevPvt); - scanIoInit (&pdevPvt->ioscanpvt); - drvStatus = (*pabDrv->setNbits) (drvPvt, abBit16); - if (drvStatus != abSuccess) - { - status = S_db_badField; - recGblRecordError (status, (void *) prec, "init_ai: setNbits"); - } - break; - - default: - status = S_db_badField; - recGblRecordError (status, (void *)prec, "init_ai: registerCard"); - break; - } - - return (status); -} - - - -LOCAL long write_ao (struct aoRecord *prec) -{ - devPvt *pdevPvt = (devPvt *) prec->dpvt; - void *drvPvt; - abStatus drvStatus; - - if (!pdevPvt) - { - recGblSetSevr (prec, WRITE_ALARM, INVALID_ALARM); - return (0); - } - - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->updateBo) (drvPvt, prec->rval, 0x0000ffff); - if (drvStatus != abSuccess) - { - recGblSetSevr (prec, WRITE_ALARM, INVALID_ALARM); - } - - return(0); -} - -LOCAL long linconv_ao(struct aoRecord *prec, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/32767.0; - return(0); -} - - - -LOCAL long init_ao (struct aoRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status = 0; - void *drvPvt; - short value[2]; - - if (prec->out.type != AB_IO) - { - recGblRecordError (S_db_badField, (void *) prec, "init_ao: Bad OUT field"); - return (S_db_badField); - } - - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/32767.0; - /* pointer to the data addess structure */ - pabio = (struct abio *) &(prec->out.value); - drvStatus = (*pabDrv->registerCard) (pabio->link, pabio->adapter, pabio->card, - typeBo, "BINARY", NULL, &drvPvt); - switch (drvStatus) - { - case abSuccess : - pdevPvt = (devPvt *) (*pabDrv->getUserPvt) (drvPvt); - prec->dpvt = pdevPvt; - break; - - case abNewCard : - pdevPvt = calloc (1, sizeof (devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt) (drvPvt, (void *) pdevPvt); - drvStatus = (*pabDrv->setNbits) (drvPvt, abBit16); - if (drvStatus != abSuccess) - { - status = S_db_badField; - recGblRecordError (status, (void *) prec, "init_ao: setNbits"); - return (status); - } - break; - - default: - status = S_db_badField; - printf ("init_ao: %s\n", abStatusMessage[drvStatus]); - recGblRecordError (status, (void *) prec, "init_ao: registerCard"); - return (status); - } - - drvStatus = (*pabDrv->readBo) (drvPvt, (unsigned long *)value, 0x0000ffff); - if (drvStatus == abSuccess) - { - prec->rval = (long)value[1]; - status = 0; - } - else - { - status = 2; - } - - return (status); -} - - - -LOCAL long read_signed_ai (struct aiRecord *prec) -{ - devPvt *pdevPvt = (devPvt *) prec->dpvt; - void *drvPvt; - abStatus drvStatus; - unsigned short value[2]; - - if (!pdevPvt) - { - recGblSetSevr (prec, READ_ALARM, INVALID_ALARM); - return (2); - } - drvPvt = pdevPvt->drvPvt; - drvStatus = (*pabDrv->readBi) (drvPvt, (unsigned long *)value, 0x0000ffff); - if (drvStatus != abSuccess) - { - recGblSetSevr (prec, READ_ALARM, INVALID_ALARM); - return (2); - } - prec->rval = ((long)value[1])^0x8000; - - return(0); -} - - - -LOCAL long init_signed_ai (struct aiRecord *prec) -{ - struct abio *pabio; - devPvt *pdevPvt; - abStatus drvStatus; - long status = 0; - void *drvPvt; - - if (prec->inp.type != AB_IO) - { - recGblRecordError (S_db_badField, (void *) prec, "init_signed_ai: Bad INP field"); - return (S_db_badField); - } - - /* set linear conversion slope*/ - prec->eslo = (prec->eguf -prec->egul)/65535.0; - /* pointer to the data addess structure */ - pabio = (struct abio *) &(prec->inp.value); - drvStatus = (*pabDrv->registerCard) (pabio->link, pabio->adapter, pabio->card, - typeBi, "BINARY", devCallback, &drvPvt); - switch (drvStatus) - { - case abSuccess : - pdevPvt = (devPvt *) (*pabDrv->getUserPvt) (drvPvt); - prec->dpvt = pdevPvt; - break; - - case abNewCard : - pdevPvt = calloc (1, sizeof (devPvt)); - pdevPvt->drvPvt = drvPvt; - prec->dpvt = pdevPvt; - (*pabDrv->setUserPvt) (drvPvt, (void *) pdevPvt); - scanIoInit (&pdevPvt->ioscanpvt); - drvStatus = (*pabDrv->setNbits) (drvPvt, abBit16); - if (drvStatus != abSuccess) - { - status = S_db_badField; - recGblRecordError (status, (void *) prec, "init_signed_ai: setNbits"); - } - break; - - default: - status = S_db_badField; - recGblRecordError (status, (void *)prec, "init_signed_ai: registerCard"); - break; - } - - return (status); -} - - diff --git a/src/dev/devABStatus.c b/src/dev/devABStatus.c deleted file mode 100644 index 696569654..000000000 --- a/src/dev/devABStatus.c +++ /dev/null @@ -1,116 +0,0 @@ -/* devABStatus.c */ -/* - * Original Authors: Marty Kraimer (nagging by Ned Arnold,Bob dalesio) - * Date: 3/6/91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 04-20-95 mrk Initial version - * ... - */ - - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct { - void *drvPvt; - IOSCANPVT ioscanpvt; -}devPvt; - - -/* Create the dsets*/ -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi;} ABBIDSET; - -LOCAL long init_common(struct mbbiRecord *prec); -LOCAL long read_adapter_status(struct mbbiRecord *prec); -LOCAL long read_card_status(struct mbbiRecord *prec); -ABBIDSET devMbbiAbAdapterStat= { 5, 0, 0, init_common, 0, read_adapter_status}; -ABBIDSET devMbbiAbCardStat= { 5, 0, 0, init_common, 0, read_card_status}; - -LOCAL long init_common(struct mbbiRecord *prec) -{ - unsigned long *pstate_values; - char *pstate_string; - unsigned short *palarm_sevr; - short i; - - if(abFailure>=16) { - epicsPrintf("devMbbiAbLinkStat. > 16 error status values\n"); - taskSuspend(0); - return(0); - } - pstate_values = &(prec->zrvl); - pstate_string = prec->zrst; - palarm_sevr = &prec->zrsv; - /*Following code assumes that abFailure is last status value*/ - for(i=0; i<=abFailure; i++ ,pstate_string += sizeof(prec->zrst)){ - pstate_values[i] = 1<zrst)-1); - if(i>0) palarm_sevr[i] = MAJOR_ALARM; - } - return(0); -} - -LOCAL long read_adapter_status(struct mbbiRecord *prec) -{ - abStatus status; - struct abio *pabio; - - pabio = (struct abio *)&(prec->inp.value); - status = (*pabDrv->adapterStatus)(pabio->link,pabio->adapter); - prec->rval = 1 << status;; - return(0); -} -LOCAL long read_card_status(struct mbbiRecord *prec) -{ - abStatus status; - struct abio *pabio; - - pabio = (struct abio *)&(prec->inp.value); - status = (*pabDrv->cardStatus)(pabio->link,pabio->adapter,pabio->card); - prec->rval = 1 << status;; - return(0); -} diff --git a/src/dev/devAiCan.c b/src/dev/devAiCan.c deleted file mode 100644 index db24becc9..000000000 --- a/src/dev/devAiCan.c +++ /dev/null @@ -1,344 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - devAiCan.c - -Description: - CANBUS Analogue Input device support - -Author: - Andrew Johnson -Created: - 8 August 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define CONVERT 0 -#define DO_NOT_CONVERT 2 - - -typedef struct { - CALLBACK callback; /* This *must* be first member */ - WDOG_ID wdId; - IOSCANPVT ioscanpvt; - struct aiRecord *prec; - canIo_t inp; - ulong_t mask; - ulong_t sign; - long data; - int status; -} aiCanPrivate_t; - -LOCAL long init_ai(struct aiRecord *prec); -LOCAL long get_ioint_info(int cmd, struct aiRecord *prec, IOSCANPVT *ppvt); -LOCAL long read_ai(struct aiRecord *prec); -LOCAL long special_linconv(struct aiRecord *prec, int after); -LOCAL void aiProcess(aiCanPrivate_t *pcanAi); -LOCAL void aiMessage(aiCanPrivate_t *pcanAi, canMessage_t *pmessage); -LOCAL void aiSignal(aiCanPrivate_t *pcanAi, int status); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} devAiCan = { - 6, - NULL, - NULL, - init_ai, - get_ioint_info, - read_ai, - special_linconv -}; - - -LOCAL long init_ai ( - struct aiRecord *prec -) { - aiCanPrivate_t *pcanAi; - int status; - ulong_t fsd; - - if (prec->inp.type != INST_IO) { - recGblRecordError(S_db_badField, (void *) prec, - "devAiCan (init_record) Illegal INP field"); - return S_db_badField; - } - - pcanAi = (aiCanPrivate_t *) malloc(sizeof(aiCanPrivate_t)); - if (pcanAi == NULL) { - return S_dev_noMemory; - } - prec->dpvt = pcanAi; - pcanAi->prec = prec; - pcanAi->ioscanpvt = NULL; - pcanAi->status = NO_ALARM; - - /* Convert the address string into members of the canIo structure */ - status = canIoParse(prec->inp.value.instio.string, &pcanAi->inp); - if (status) { - recGblRecordError(S_can_badAddress, (void *) prec, - "devAiCan (init_record) bad CAN address"); - return S_can_badAddress; - } - - #ifdef DEBUG - printf("aiCan %s: Init bus=%s, id=%#x, off=%d, parm=%d\n", - prec->name, pcanAi->inp.busName, pcanAi->inp.identifier, - pcanAi->inp.offset, pcanAi->inp.parameter); - #endif - - /* For ai records, the final parameter specifies the raw input size. - eg 0xff or 0x100 specify an 8-bit unsigned value. -ve numbers - specify a signed value, eg -4095 means a 12-bit signed value. - The range does not have to be a power of two, eg 99 is legal. */ - - fsd = abs(pcanAi->inp.parameter); - if (fsd > 0) { - if ((fsd & (fsd-1)) == 0) { - fsd--; - } - - /* Make a mask to contain only the valid input bits based on fsd */ - pcanAi->mask = 1; - while (pcanAi->mask < fsd) { - pcanAi->mask <<= 1; - } - pcanAi->mask--; - - if (pcanAi->inp.parameter < 0) { - /* signed: rval = sign-extend(data & mask) */ - pcanAi->sign = (pcanAi->mask >> 1) + 1; - } else { - /* unsigned: rval = data & mask */ - pcanAi->sign = 0; - } - - if (prec->linr == 1) { - prec->roff = pcanAi->sign; - prec->eslo = (prec->eguf - prec->egul) / fsd; - } else { - prec->roff = 0; - } - } else { - pcanAi->mask = pcanAi->sign = 0; - } - - #ifdef DEBUG - printf(" fsd=%d, eslo=%g, roff = %d, mask=%#x, sign=%d\n", - fsd, prec->eslo, prec->roff, pcanAi->mask, pcanAi->sign); - #endif - - /* Create a callback for asynchronous processing */ - callbackSetCallback(aiProcess, &pcanAi->callback); - callbackSetPriority(prec->prio, &pcanAi->callback); - - /* and a watchdog for CANbus RTR timeouts */ - pcanAi->wdId = wdCreate(); - if (pcanAi->wdId == NULL) { - return S_dev_noMemory; - } - - /* Register the message and signal handlers with the Canbus driver */ - canMessage(pcanAi->inp.canBusID, pcanAi->inp.identifier, - (canMsgCallback_t *) aiMessage, pcanAi); - canSignal(pcanAi->inp.canBusID, (canSigCallback_t *) aiSignal, pcanAi); - - return OK; -} - -LOCAL long get_ioint_info ( - int cmd, - struct aiRecord *prec, - IOSCANPVT *ppvt -) { - aiCanPrivate_t *pcanAi = (aiCanPrivate_t *) prec->dpvt; - - if (pcanAi->ioscanpvt == NULL) { - scanIoInit(&pcanAi->ioscanpvt); - } - - #ifdef DEBUG - printf("canAi %s: get_ioint_info %d\n", prec->name, cmd); - #endif - - *ppvt = pcanAi->ioscanpvt; - return OK; -} - -LOCAL long read_ai ( - struct aiRecord *prec -) { - aiCanPrivate_t *pcanAi = (aiCanPrivate_t *) prec->dpvt; - - if (pcanAi->inp.canBusID == NULL) { - return DO_NOT_CONVERT; - } - - #ifdef DEBUG - printf("canAi %s: read_ai status=%#x\n", prec->name, pcanAi->status); - #endif - - switch (pcanAi->status) { - case TIMEOUT_ALARM: - case COMM_ALARM: - recGblSetSevr(prec, pcanAi->status, MAJOR_ALARM); - pcanAi->status = NO_ALARM; - return DO_NOT_CONVERT; - case READ_ALARM: - recGblSetSevr(prec, COMM_ALARM, MINOR_ALARM); - pcanAi->status = NO_ALARM; - return DO_NOT_CONVERT; - - case NO_ALARM: - if (prec->pact || prec->scan == SCAN_IO_EVENT) { - #ifdef DEBUG - printf("canAi %s: message id=%#x, data=%#x\n", - prec->name, pcanAi->inp.identifier, pcanAi->data); - #endif - - prec->rval = pcanAi->data & pcanAi->mask; - if (pcanAi->sign & prec->rval) { - prec->rval |= ~pcanAi->mask; - } - return CONVERT; - } else { - canMessage_t message; - - message.identifier = pcanAi->inp.identifier; - message.rtr = RTR; - message.length = 0; - - #ifdef DEBUG - printf("canAi %s: RTR, id=%#x\n", - prec->name, pcanAi->inp.identifier); - #endif - - prec->pact = TRUE; - pcanAi->status = TIMEOUT_ALARM; - - callbackSetPriority(prec->prio, &pcanAi->callback); - wdStart(pcanAi->wdId, pcanAi->inp.timeout, - (FUNCPTR) callbackRequest, (int) pcanAi); - canWrite(pcanAi->inp.canBusID, &message, pcanAi->inp.timeout); - return 0; - } - default: - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - pcanAi->status = NO_ALARM; - return DO_NOT_CONVERT; - } -} - -LOCAL long special_linconv ( - struct aiRecord *prec, - int after -) { - if (after) { - if (prec->linr == 1) { - ulong_t fsd; - aiCanPrivate_t *pcanAi = (aiCanPrivate_t *) prec->dpvt; - - fsd = abs(pcanAi->inp.parameter); - if (fsd > 0) { - if ((fsd & (fsd-1)) == 0) { - fsd--; - } - prec->roff = pcanAi->sign; - prec->eslo = (prec->eguf - prec->egul) / fsd; - } - } else { - prec->roff = 0; - } - } - return 0; -} - -LOCAL void aiProcess ( - aiCanPrivate_t *pcanAi -) { - dbScanLock((struct dbCommon *) pcanAi->prec); - (*((struct rset *) pcanAi->prec->rset)->process)(pcanAi->prec); - dbScanUnlock((struct dbCommon *) pcanAi->prec); -} - -LOCAL void aiMessage ( - aiCanPrivate_t *pcanAi, - canMessage_t *pmessage -) { - if (pmessage->rtr == RTR) { - return; /* Ignore RTRs */ - } - - if (pcanAi->mask == 0) { - pcanAi->data = 0; - } else if (pcanAi->mask <= 0xff) { - pcanAi->data = pmessage->data[pcanAi->inp.offset+0]; - } else if (pcanAi->mask <= 0xffff) { - pcanAi->data = pmessage->data[pcanAi->inp.offset+0] << 8 | - pmessage->data[pcanAi->inp.offset+1]; - } else if (pcanAi->mask <= 0xffffff) { - pcanAi->data = pmessage->data[pcanAi->inp.offset+0] << 16 | - pmessage->data[pcanAi->inp.offset+1] << 8 | - pmessage->data[pcanAi->inp.offset+2]; - } else { - pcanAi->data = pmessage->data[pcanAi->inp.offset+0] << 24 | - pmessage->data[pcanAi->inp.offset+1] << 16 | - pmessage->data[pcanAi->inp.offset+2] << 8 | - pmessage->data[pcanAi->inp.offset+3]; - } - - if (pcanAi->prec->scan == SCAN_IO_EVENT) { - pcanAi->status = NO_ALARM; - scanIoRequest(pcanAi->ioscanpvt); - } else if (pcanAi->status == TIMEOUT_ALARM) { - pcanAi->status = NO_ALARM; - wdCancel(pcanAi->wdId); - callbackRequest(&pcanAi->callback); - } -} - -LOCAL void aiSignal ( - aiCanPrivate_t *pcanAi, - int status -) { - switch(status) { - case CAN_BUS_OK: - return; - case CAN_BUS_ERROR: - pcanAi->status = READ_ALARM; - break; - case CAN_BUS_OFF: - pcanAi->status = COMM_ALARM; - break; - } - callbackRequest(&pcanAi->callback); -} diff --git a/src/dev/devAoCan.c b/src/dev/devAoCan.c deleted file mode 100644 index 8bf81f106..000000000 --- a/src/dev/devAoCan.c +++ /dev/null @@ -1,319 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - devAoCan.c - -Description: - CANBUS Analogue Output device support - -Author: - Andrew Johnson -Created: - 9 August 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef struct { - CALLBACK callback; /* This *must* be first member */ - IOSCANPVT ioscanpvt; - struct aoRecord *prec; - canIo_t out; - ulong_t mask; - ulong_t sign; - long data; - int status; -} aoCanPrivate_t; - -LOCAL long init_ao(struct aoRecord *prec); -LOCAL long get_ioint_info(int cmd, struct aoRecord *prec, IOSCANPVT *ppvt); -LOCAL long write_ao(struct aoRecord *prec); -LOCAL long special_linconv(struct aoRecord *prec, int after); -LOCAL void aoProcess(aoCanPrivate_t *pcanAo); -LOCAL void aoMessage(aoCanPrivate_t *pcanAo, canMessage_t *pmessage); -LOCAL void aoSignal(aoCanPrivate_t *pcanAo, int status); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_ao; - DEVSUPFUN special_linconv; -} devAoCan = { - 6, - NULL, - NULL, - init_ao, - get_ioint_info, - write_ao, - special_linconv -}; - - -LOCAL long init_ao ( - struct aoRecord *prec -) { - aoCanPrivate_t *pcanAo; - int status, fsd; - - if (prec->out.type != INST_IO) { - recGblRecordError(S_db_badField, (void *) prec, - "devAoCan (init_record) Illegal INP field"); - return S_db_badField; - } - - pcanAo = (aoCanPrivate_t *) malloc(sizeof(aoCanPrivate_t)); - if (pcanAo == NULL) { - return S_dev_noMemory; - } - prec->dpvt = pcanAo; - pcanAo->prec = prec; - pcanAo->ioscanpvt = NULL; - pcanAo->status = NO_ALARM; - - /* Convert the parameter string into members of the canIo structure */ - status = canIoParse(prec->out.value.instio.string, &pcanAo->out); - if (status) { - recGblRecordError(S_can_badAddress, (void *) prec, - "devAoCan (init_record) bad CAN address"); - return S_can_badAddress; - } - - #ifdef DEBUG - printf("canAo %s: Init bus=%s, id=%#x, off=%d, parm=%d\n", - prec->name, pcanAo->out.busName, pcanAo->out.identifier, - pcanAo->out.offset, pcanAo->out.parameter); - #endif - - /* For ao records, the final parameter specifies the raw output size. - eg 0xfff or 0x1000 specify a 12-bit unsigned value. -ve numbers - specify a signed value, eg -256 means an 8-bit signed value. */ - fsd = abs(pcanAo->out.parameter); - if (fsd > 0) { - if ((fsd & (fsd-1)) == 0) { - fsd--; - } - - /* Make a mask to contain only the valid out bits based on fsd */ - pcanAo->mask = 1; - while (pcanAo->mask < fsd) { - pcanAo->mask <<= 1; - } - pcanAo->mask--; - - if (pcanAo->out.parameter < 0) { - /* signed data */ - pcanAo->sign = (pcanAo->mask >> 1) + 1; - } else { - pcanAo->sign = 0; - } - if (prec->linr == 1) { - prec->roff = pcanAo->sign; - prec->eslo = (prec->eguf - prec->egul) / fsd; - } else { - prec->roff = 0; - } - } else { - pcanAo->mask = pcanAo->sign = 0; - } - - #ifdef DEBUG - printf(" fsd=%d, eslo=%g, roff=%d, mask=%#x, sign=%d\n", - fsd, prec->eslo, prec->roff, pcanAo->mask, pcanAo->sign); - #endif - - /* Create a callback for error processing */ - callbackSetCallback(aoProcess, &pcanAo->callback); - callbackSetPriority(prec->prio, &pcanAo->callback); - - /* Register the message and signal handlers with the Canbus driver */ - canMessage(pcanAo->out.canBusID, pcanAo->out.identifier, - (canMsgCallback_t *) aoMessage, pcanAo); - canSignal(pcanAo->out.canBusID, (canSigCallback_t *) aoSignal, pcanAo); - - return OK; -} - -LOCAL long get_ioint_info ( - int cmd, - struct aoRecord *prec, - IOSCANPVT *ppvt -) { - aoCanPrivate_t *pcanAo = (aoCanPrivate_t *) prec->dpvt; - - if (pcanAo->ioscanpvt == NULL) { - scanIoInit(&pcanAo->ioscanpvt); - } - - #ifdef DEBUG - printf("aoCan %s: get_ioint_info %d\n", prec->name, cmd); - #endif - - *ppvt = pcanAo->ioscanpvt; - return OK; -} - -LOCAL long write_ao ( - struct aoRecord *prec -) { - aoCanPrivate_t *pcanAo = (aoCanPrivate_t *) prec->dpvt; - - if (pcanAo->out.canBusID == NULL) { - return ERROR; - } - - #ifdef DEBUG - printf("aoCan %s: write_ao status=%#x\n", prec->name, pcanAo->status); - #endif - - switch (pcanAo->status) { - case COMM_ALARM: - recGblSetSevr(prec, pcanAo->status, MAJOR_ALARM); - pcanAo->status = NO_ALARM; - return ERROR; - case READ_ALARM: - recGblSetSevr(prec, COMM_ALARM, MINOR_ALARM); - pcanAo->status = NO_ALARM; - return ERROR; - - case NO_ALARM: - { - canMessage_t message; - int status; - - message.identifier = pcanAo->out.identifier; - message.rtr = SEND; - - pcanAo->data = prec->rval & pcanAo->mask; - - if (pcanAo->mask == 0) { - message.length = 0; - } else if (pcanAo->mask <= 0xff) { - message.data[0] = (pcanAo->data ) & 0xff; - message.length = 1; - } else if (pcanAo->mask <= 0xffff) { - message.data[0] = (pcanAo->data >> 8) & 0xff; - message.data[1] = (pcanAo->data ) & 0xff; - message.length = 2; - } else if (pcanAo->mask <= 0xffffff) { - message.data[0] = (pcanAo->data >> 16) & 0xff; - message.data[1] = (pcanAo->data >> 8) & 0xff; - message.data[2] = (pcanAo->data ) & 0xff; - message.length = 3; - } else { - message.data[0] = (pcanAo->data >> 24) & 0xff; - message.data[1] = (pcanAo->data >> 16) & 0xff; - message.data[2] = (pcanAo->data >> 8) & 0xff; - message.data[3] = (pcanAo->data ) & 0xff; - message.length = 4; - } - - #ifdef DEBUG - printf("canAo %s: SEND id=%#x, length=%d, data=%#x\n", - prec->name, message.identifier, message.length, - pcanAo->data); - #endif - - status = canWrite(pcanAo->out.canBusID, &message, - pcanAo->out.timeout); - if (status) { - #ifdef DEBUG - printf("canAo %s: canWrite status=%#x\n", status); - #endif - - recGblSetSevr(prec, TIMEOUT_ALARM, MINOR_ALARM); - return ERROR; - } - return 0; - } - default: - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - pcanAo->status = NO_ALARM; - return ERROR; - } -} - -LOCAL long special_linconv ( - struct aoRecord *prec, - int after -) { - if (after) { - if (prec->linr == 1) { - ulong_t fsd; - aoCanPrivate_t *pcanAo = (aoCanPrivate_t *) prec->dpvt; - fsd = abs(pcanAo->out.parameter); - if (fsd > 0) { - if ((fsd & (fsd-1)) == 0) { - fsd--; - } - - prec->roff = pcanAo->sign; - prec->eslo = (prec->eguf - prec->egul) / fsd; - } - } else { - prec->roff = 0; - } - } - return 0; -} - -LOCAL void aoProcess ( - aoCanPrivate_t *pcanAo -) { - dbScanLock((struct dbCommon *) pcanAo->prec); - (*((struct rset *) pcanAo->prec->rset)->process)(pcanAo->prec); - dbScanUnlock((struct dbCommon *) pcanAo->prec); -} - -LOCAL void aoMessage ( - aoCanPrivate_t *pcanAo, - canMessage_t *pmessage -) { - if (pcanAo->prec->scan == SCAN_IO_EVENT && - pmessage->rtr == RTR) { - pcanAo->status = NO_ALARM; - scanIoRequest(pcanAo->ioscanpvt); - } -} - -LOCAL void aoSignal ( - aoCanPrivate_t *pcanAo, - int status -) { - switch(status) { - case CAN_BUS_OK: - return; - case CAN_BUS_ERROR: - pcanAo->status = READ_ALARM; - break; - case CAN_BUS_OFF: - pcanAo->status = COMM_ALARM; - break; - } - callbackRequest(&pcanAo->callback); -} diff --git a/src/dev/devBiCan.c b/src/dev/devBiCan.c deleted file mode 100644 index 0fbc28b3a..000000000 --- a/src/dev/devBiCan.c +++ /dev/null @@ -1,265 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - devBiCan.c - -Description: - CANBUS Binary Input device support - -Author: - Andrew Johnson -Created: - 14 August 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define CONVERT 0 -#define DO_NOT_CONVERT 2 - - -typedef struct { - CALLBACK callback; /* This *must* be first member */ - WDOG_ID wdId; - IOSCANPVT ioscanpvt; - struct biRecord *prec; - canIo_t inp; - long data; - int status; -} biCanPrivate_t; - -LOCAL long init_bi(struct biRecord *prec); -LOCAL long get_ioint_info(int cmd, struct biRecord *prec, IOSCANPVT *ppvt); -LOCAL long read_bi(struct biRecord *prec); -LOCAL void biProcess(biCanPrivate_t *pcanBi); -LOCAL void biMessage(biCanPrivate_t *pcanBi, canMessage_t *pmessage); -LOCAL void biSignal(biCanPrivate_t *pcanBi, int status); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi; -} devBiCan = { - 5, - NULL, - NULL, - init_bi, - get_ioint_info, - read_bi -}; - - -LOCAL long init_bi ( - struct biRecord *prec -) { - biCanPrivate_t *pcanBi; - int status; - - if (prec->inp.type != INST_IO) { - recGblRecordError(S_db_badField, (void *) prec, - "devBiCan (init_record) Illegal INP field"); - return S_db_badField; - } - - pcanBi = (biCanPrivate_t *) malloc(sizeof(biCanPrivate_t)); - if (pcanBi == NULL) { - return S_dev_noMemory; - } - prec->dpvt = pcanBi; - pcanBi->prec = prec; - pcanBi->ioscanpvt = NULL; - pcanBi->status = NO_ALARM; - - /* Convert the address string into members of the canIo structure */ - status = canIoParse(prec->inp.value.instio.string, &pcanBi->inp); - if (status || - pcanBi->inp.parameter < 0 || - pcanBi->inp.parameter > 7) { - recGblRecordError(S_can_badAddress, (void *) prec, - "devBiCan (init_record) bad CAN address"); - return S_can_badAddress; - } - - #ifdef DEBUG - printf("biCan %s: Init bus=%s, id=%#x, off=%d, parm=%d\n", - prec->name, pcanBi->inp.busName, pcanBi->inp.identifier, - pcanBi->inp.offset, pcanBi->inp.parameter); - #endif - - /* For bi records, the final parameter specifies the input bit number, - with offset specifying the message byte number. */ - prec->mask = 1 << pcanBi->inp.parameter; - - #ifdef DEBUG - printf(" bit=%d, mask=%#x\n", - pcanBi->inp.parameter, prec->mask); - #endif - - /* Create a callback for asynchronous processing */ - callbackSetCallback(biProcess, &pcanBi->callback); - callbackSetPriority(prec->prio, &pcanBi->callback); - - /* and a watchdog for CANbus RTR timeouts */ - pcanBi->wdId = wdCreate(); - if (pcanBi->wdId == NULL) { - return S_dev_noMemory; - } - - /* Register the message and signal handlers with the Canbus driver */ - canMessage(pcanBi->inp.canBusID, pcanBi->inp.identifier, - (canMsgCallback_t *) biMessage, pcanBi); - canSignal(pcanBi->inp.canBusID, (canSigCallback_t *) biSignal, pcanBi); - - return OK; -} - -LOCAL long get_ioint_info ( - int cmd, - struct biRecord *prec, - IOSCANPVT *ppvt -) { - biCanPrivate_t *pcanBi = (biCanPrivate_t *) prec->dpvt; - - if (pcanBi->ioscanpvt == NULL) { - scanIoInit(&pcanBi->ioscanpvt); - } - - #ifdef DEBUG - printf("canBi %s: get_ioint_info %d\n", prec->name, cmd); - #endif - - *ppvt = pcanBi->ioscanpvt; - return OK; -} - -LOCAL long read_bi ( - struct biRecord *prec -) { - biCanPrivate_t *pcanBi = (biCanPrivate_t *) prec->dpvt; - - if (pcanBi->inp.canBusID == NULL) { - return DO_NOT_CONVERT; - } - - #ifdef DEBUG - printf("canBi %s: read_bi status=%#x\n", prec->name, pcanBi->status); - #endif - - switch (pcanBi->status) { - case TIMEOUT_ALARM: - case COMM_ALARM: - recGblSetSevr(prec, pcanBi->status, MAJOR_ALARM); - pcanBi->status = NO_ALARM; - return DO_NOT_CONVERT; - case READ_ALARM: - recGblSetSevr(prec, COMM_ALARM, MINOR_ALARM); - pcanBi->status = NO_ALARM; - return DO_NOT_CONVERT; - - case NO_ALARM: - if (prec->pact || prec->scan == SCAN_IO_EVENT) { - #ifdef DEBUG - printf("canBi %s: message id=%#x, data=%#x\n", - prec->name, pcanBi->inp.identifier, pcanBi->data); - #endif - - prec->rval = pcanBi->data & prec->mask; - return CONVERT; - } else { - canMessage_t message; - - message.identifier = pcanBi->inp.identifier; - message.rtr = RTR; - message.length = 0; - - #ifdef DEBUG - printf("canBi %s: RTR, id=%#x\n", - prec->name, pcanBi->inp.identifier); - #endif - - prec->pact = TRUE; - pcanBi->status = TIMEOUT_ALARM; - - callbackSetPriority(prec->prio, &pcanBi->callback); - wdStart(pcanBi->wdId, pcanBi->inp.timeout, - (FUNCPTR) callbackRequest, (int) pcanBi); - canWrite(pcanBi->inp.canBusID, &message, pcanBi->inp.timeout); - return 0; - } - default: - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - pcanBi->status = NO_ALARM; - return DO_NOT_CONVERT; - } -} - -LOCAL void biProcess ( - biCanPrivate_t *pcanBi -) { - dbScanLock((struct dbCommon *) pcanBi->prec); - (*((struct rset *) pcanBi->prec->rset)->process)(pcanBi->prec); - dbScanUnlock((struct dbCommon *) pcanBi->prec); -} - -LOCAL void biMessage ( - biCanPrivate_t *pcanBi, - canMessage_t *pmessage -) { - if (pmessage->rtr == RTR) { - return; /* Ignore RTRs */ - } - - pcanBi->data = pmessage->data[pcanBi->inp.offset]; - - if (pcanBi->prec->scan == SCAN_IO_EVENT) { - pcanBi->status = NO_ALARM; - scanIoRequest(pcanBi->ioscanpvt); - } else if (pcanBi->status == TIMEOUT_ALARM) { - pcanBi->status = NO_ALARM; - wdCancel(pcanBi->wdId); - callbackRequest(&pcanBi->callback); - } -} - -LOCAL void biSignal ( - biCanPrivate_t *pcanBi, - int status -) { - switch(status) { - case CAN_BUS_OK: - return; - case CAN_BUS_ERROR: - pcanBi->status = READ_ALARM; - break; - case CAN_BUS_OFF: - pcanBi->status = COMM_ALARM; - break; - } - callbackRequest(&pcanBi->callback); -} diff --git a/src/dev/devBoCan.c b/src/dev/devBoCan.c deleted file mode 100644 index d946e892e..000000000 --- a/src/dev/devBoCan.c +++ /dev/null @@ -1,244 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - devBoCan.c - -Description: - CANBUS Binary Output device support - -Author: - Andrew Johnson -Created: - 14 August 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef struct { - CALLBACK callback; /* This *must* be first member */ - IOSCANPVT ioscanpvt; - struct boRecord *prec; - canIo_t out; - long data; - int status; -} boCanPrivate_t; - -LOCAL long init_bo(struct boRecord *prec); -LOCAL long get_ioint_info(int cmd, struct boRecord *prec, IOSCANPVT *ppvt); -LOCAL long write_bo(struct boRecord *prec); -LOCAL void boProcess(boCanPrivate_t *pcanBo); -LOCAL void boMessage(boCanPrivate_t *pcanBo, canMessage_t *pmessage); -LOCAL void boSignal(boCanPrivate_t *pcanBo, int status); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_bo; -} devBoCan = { - 5, - NULL, - NULL, - init_bo, - get_ioint_info, - write_bo -}; - - -LOCAL long init_bo ( - struct boRecord *prec -) { - boCanPrivate_t *pcanBo; - int status; - - if (prec->out.type != INST_IO) { - recGblRecordError(S_db_badField, (void *) prec, - "devBoCan (init_record) Illegal INP field"); - return S_db_badField; - } - - pcanBo = (boCanPrivate_t *) malloc(sizeof(boCanPrivate_t)); - if (pcanBo == NULL) { - return S_dev_noMemory; - } - prec->dpvt = pcanBo; - pcanBo->prec = prec; - pcanBo->ioscanpvt = NULL; - pcanBo->status = NO_ALARM; - - /* Convert the parameter string into members of the canIo structure */ - status = canIoParse(prec->out.value.instio.string, &pcanBo->out); - if (status || - pcanBo->out.parameter < 0 || - pcanBo->out.parameter > 7) { - recGblRecordError(S_can_badAddress, (void *) prec, - "devBoCan (init_record) bad CAN address"); - return S_can_badAddress; - } - - #ifdef DEBUG - printf("canBo %s: Init bus=%s, id=%#x, off=%d, parm=%d\n", - prec->name, pcanBo->out.busName, pcanBo->out.identifier, - pcanBo->out.offset, pcanBo->out.parameter); - #endif - - /* For bo records, the final parameter specifies the output bit number, - with the offset specifying the message byte number. */ - prec->mask = 1 << pcanBo->out.parameter; - - #ifdef DEBUG - printf(" bit=%d, mask=%#x\n", out.parameter, prec->mask); - #endif - - /* Create a callback for error processing */ - callbackSetCallback(boProcess, &pcanBo->callback); - callbackSetPriority(prec->prio, &pcanBo->callback); - - /* Register the message and signal handlers with the Canbus driver */ - canMessage(pcanBo->out.canBusID, pcanBo->out.identifier, - (canMsgCallback_t *) boMessage, pcanBo); - canSignal(pcanBo->out.canBusID, (canSigCallback_t *) boSignal, pcanBo); - - return OK; -} - -LOCAL long get_ioint_info ( - int cmd, - struct boRecord *prec, - IOSCANPVT *ppvt -) { - boCanPrivate_t *pcanBo = (boCanPrivate_t *) prec->dpvt; - - if (pcanBo->ioscanpvt == NULL) { - scanIoInit(&pcanBo->ioscanpvt); - } - - #ifdef DEBUG - printf("boCan %s: get_ioint_info %d\n", prec->name, cmd); - #endif - - *ppvt = pcanBo->ioscanpvt; - return OK; -} - -LOCAL long write_bo ( - struct boRecord *prec -) { - boCanPrivate_t *pcanBo = (boCanPrivate_t *) prec->dpvt; - - if (pcanBo->out.canBusID == NULL) { - return ERROR; - } - - #ifdef DEBUG - printf("boCan %s: write_bo status=%#x\n", prec->name, pcanBo->status); - #endif - - switch (pcanBo->status) { - case COMM_ALARM: - recGblSetSevr(prec, pcanBo->status, MAJOR_ALARM); - pcanBo->status = NO_ALARM; - return ERROR; - case READ_ALARM: - recGblSetSevr(prec, COMM_ALARM, MINOR_ALARM); - pcanBo->status = NO_ALARM; - return ERROR; - - case NO_ALARM: - { - canMessage_t message; - int status; - - message.identifier = pcanBo->out.identifier; - message.rtr = SEND; - - pcanBo->data = prec->rval & prec->mask; - - message.data[pcanBo->out.offset] = pcanBo->data; - message.length = pcanBo->out.offset + 1; - - #ifdef DEBUG - printf("canBo %s: SEND id=%#x, length=%d, data=%#x\n", - prec->name, message.identifier, message.length, - pcanBo->data); - #endif - - status = canWrite(pcanBo->out.canBusID, &message, - pcanBo->out.timeout); - if (status) { - #ifdef DEBUG - printf("canBo %s: canWrite status=%#x\n", status); - #endif - - recGblSetSevr(prec, TIMEOUT_ALARM, MINOR_ALARM); - return ERROR; - } - return 0; - } - default: - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - pcanBo->status = NO_ALARM; - return ERROR; - } -} - -LOCAL void boProcess ( - boCanPrivate_t *pcanBo -) { - dbScanLock((struct dbCommon *) pcanBo->prec); - (*((struct rset *) pcanBo->prec->rset)->process)(pcanBo->prec); - dbScanUnlock((struct dbCommon *) pcanBo->prec); -} - -LOCAL void boMessage ( - boCanPrivate_t *pcanBo, - canMessage_t *pmessage -) { - if (pcanBo->prec->scan == SCAN_IO_EVENT && - pmessage->rtr == RTR) { - pcanBo->status = NO_ALARM; - scanIoRequest(pcanBo->ioscanpvt); - } -} - -LOCAL void boSignal ( - boCanPrivate_t *pcanBo, - int status -) { - switch(status) { - case CAN_BUS_OK: - return; - case CAN_BUS_ERROR: - pcanBo->status = READ_ALARM; - break; - case CAN_BUS_OFF: - pcanBo->status = COMM_ALARM; - break; - } - callbackRequest(&pcanBo->callback); -} diff --git a/src/dev/devMbbiCan.c b/src/dev/devMbbiCan.c deleted file mode 100644 index 0090b01e9..000000000 --- a/src/dev/devMbbiCan.c +++ /dev/null @@ -1,267 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - devMbbiCan.c - -Description: - CANBUS Multi-Bit Binary Input device support - -Author: - Andrew Johnson -Created: - 14 August 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define CONVERT 0 -#define DO_NOT_CONVERT 2 - - -typedef struct { - CALLBACK callback; /* This *must* be first member */ - WDOG_ID wdId; - IOSCANPVT ioscanpvt; - struct mbbiRecord *prec; - canIo_t inp; - long data; - int status; -} mbbiCanPrivate_t; - -LOCAL long init_mbbi(struct mbbiRecord *prec); -LOCAL long get_ioint_info(int cmd, struct mbbiRecord *prec, IOSCANPVT *ppvt); -LOCAL long read_mbbi(struct mbbiRecord *prec); -LOCAL void mbbiProcess(mbbiCanPrivate_t *pcanMbbi); -LOCAL void mbbiMessage(mbbiCanPrivate_t *pcanMbbi, canMessage_t *pmessage); -LOCAL void mbbiSignal(mbbiCanPrivate_t *pcanMbbi, int status); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbi; -} devMbbiCan = { - 5, - NULL, - NULL, - init_mbbi, - get_ioint_info, - read_mbbi -}; - - -LOCAL long init_mbbi ( - struct mbbiRecord *prec -) { - mbbiCanPrivate_t *pcanMbbi; - int status; - - if (prec->inp.type != INST_IO) { - recGblRecordError(S_db_badField, (void *) prec, - "devMbbiCan (init_record) Illegal INP field"); - return S_db_badField; - } - - pcanMbbi = (mbbiCanPrivate_t *) malloc(sizeof(mbbiCanPrivate_t)); - if (pcanMbbi == NULL) { - return S_dev_noMemory; - } - prec->dpvt = pcanMbbi; - pcanMbbi->prec = prec; - pcanMbbi->ioscanpvt = NULL; - pcanMbbi->status = NO_ALARM; - - /* Convert the address string into members of the canIo structure */ - status = canIoParse(prec->inp.value.instio.string, &pcanMbbi->inp); - if (status || - pcanMbbi->inp.parameter < 0 || - pcanMbbi->inp.parameter > 7) { - recGblRecordError(S_can_badAddress, (void *) prec, - "devMbbiCan (init_record) bad CAN address"); - return S_can_badAddress; - } - - #ifdef DEBUG - printf("mbbiCan %s: Init bus=%s, id=%#x, off=%d, parm=%d\n", - prec->name, pcanMbbi->inp.busName, pcanMbbi->inp.identifier, - pcanMbbi->inp.offset, pcanMbbi->inp.parameter); - #endif - - /* For mbbi records, the final parameter specifies the input bit shift, - with offset specifying the message byte number. */ - prec->shft = pcanMbbi->inp.parameter; - prec->mask <<= pcanMbbi->inp.parameter; - - #ifdef DEBUG - printf(" shft=%d, mask=%#x\n", - pcanMbbi->inp.parameter, prec->mask); - #endif - - /* Create a callback for asynchronous processing */ - callbackSetCallback(mbbiProcess, &pcanMbbi->callback); - callbackSetPriority(prec->prio, &pcanMbbi->callback); - - /* and a watchdog for CANbus RTR timeouts */ - pcanMbbi->wdId = wdCreate(); - if (pcanMbbi->wdId == NULL) { - return S_dev_noMemory; - } - - /* Register the message and signal handlers with the Canbus driver */ - canMessage(pcanMbbi->inp.canBusID, pcanMbbi->inp.identifier, - (canMsgCallback_t *) mbbiMessage, pcanMbbi); - canSignal(pcanMbbi->inp.canBusID, - (canSigCallback_t *) mbbiSignal, pcanMbbi); - - return OK; -} - -LOCAL long get_ioint_info ( - int cmd, - struct mbbiRecord *prec, - IOSCANPVT *ppvt -) { - mbbiCanPrivate_t *pcanMbbi = (mbbiCanPrivate_t *) prec->dpvt; - - if (pcanMbbi->ioscanpvt == NULL) { - scanIoInit(&pcanMbbi->ioscanpvt); - } - - #ifdef DEBUG - printf("canMbbi %s: get_ioint_info %d\n", prec->name, cmd); - #endif - - *ppvt = pcanMbbi->ioscanpvt; - return OK; -} - -LOCAL long read_mbbi ( - struct mbbiRecord *prec -) { - mbbiCanPrivate_t *pcanMbbi = (mbbiCanPrivate_t *) prec->dpvt; - - if (pcanMbbi->inp.canBusID == NULL) { - return DO_NOT_CONVERT; - } - - #ifdef DEBUG - printf("canMbbi %s: read_mbbi status=%#x\n", prec->name, pcanMbbi->status); - #endif - - switch (pcanMbbi->status) { - case TIMEOUT_ALARM: - case COMM_ALARM: - recGblSetSevr(prec, pcanMbbi->status, MAJOR_ALARM); - pcanMbbi->status = NO_ALARM; - return DO_NOT_CONVERT; - case READ_ALARM: - recGblSetSevr(prec, COMM_ALARM, MINOR_ALARM); - pcanMbbi->status = NO_ALARM; - return DO_NOT_CONVERT; - - case NO_ALARM: - if (prec->pact || prec->scan == SCAN_IO_EVENT) { - #ifdef DEBUG - printf("canMbbi %s: message id=%#x, data=%#x\n", - prec->name, pcanMbbi->inp.identifier, pcanMbbi->data); - #endif - - prec->rval = pcanMbbi->data & prec->mask; - return CONVERT; - } else { - canMessage_t message; - - message.identifier = pcanMbbi->inp.identifier; - message.rtr = RTR; - message.length = 0; - - #ifdef DEBUG - printf("canMbbi %s: RTR, id=%#x\n", - prec->name, pcanMbbi->inp.identifier); - #endif - - prec->pact = TRUE; - pcanMbbi->status = TIMEOUT_ALARM; - - callbackSetPriority(prec->prio, &pcanMbbi->callback); - wdStart(pcanMbbi->wdId, pcanMbbi->inp.timeout, - (FUNCPTR) callbackRequest, (int) pcanMbbi); - canWrite(pcanMbbi->inp.canBusID, &message, pcanMbbi->inp.timeout); - return 0; - } - default: - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - pcanMbbi->status = NO_ALARM; - return DO_NOT_CONVERT; - } -} - -LOCAL void mbbiProcess ( - mbbiCanPrivate_t *pcanMbbi -) { - dbScanLock((struct dbCommon *) pcanMbbi->prec); - (*((struct rset *) pcanMbbi->prec->rset)->process)(pcanMbbi->prec); - dbScanUnlock((struct dbCommon *) pcanMbbi->prec); -} - -LOCAL void mbbiMessage ( - mbbiCanPrivate_t *pcanMbbi, - canMessage_t *pmessage -) { - if (pmessage->rtr == RTR) { - return; /* Ignore RTRs */ - } - - pcanMbbi->data = pmessage->data[pcanMbbi->inp.offset]; - - if (pcanMbbi->prec->scan == SCAN_IO_EVENT) { - pcanMbbi->status = NO_ALARM; - scanIoRequest(pcanMbbi->ioscanpvt); - } else if (pcanMbbi->status == TIMEOUT_ALARM) { - pcanMbbi->status = NO_ALARM; - wdCancel(pcanMbbi->wdId); - callbackRequest(&pcanMbbi->callback); - } -} - -LOCAL void mbbiSignal ( - mbbiCanPrivate_t *pcanMbbi, - int status -) { - switch(status) { - case CAN_BUS_OK: - return; - case CAN_BUS_ERROR: - pcanMbbi->status = READ_ALARM; - break; - case CAN_BUS_OFF: - pcanMbbi->status = COMM_ALARM; - break; - } - callbackRequest(&pcanMbbi->callback); -} diff --git a/src/dev/devMbbiDirectCan.c b/src/dev/devMbbiDirectCan.c deleted file mode 100644 index b52aee2f4..000000000 --- a/src/dev/devMbbiDirectCan.c +++ /dev/null @@ -1,267 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - devMbbiDirectCan.c - -Description: - CANBUS Multi-Bit Binary Input Direct device support - -Author: - Andrew Johnson -Created: - 14 August 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define CONVERT 0 -#define DO_NOT_CONVERT 2 - - -typedef struct { - CALLBACK callback; /* This *must* be first member */ - WDOG_ID wdId; - IOSCANPVT ioscanpvt; - struct mbbiDirectRecord *prec; - canIo_t inp; - long data; - int status; -} mbbiDirectCanPrivate_t; - -LOCAL long init_mbbiDirect(struct mbbiDirectRecord *prec); -LOCAL long get_ioint_info(int cmd, struct mbbiDirectRecord *prec, IOSCANPVT *ppvt); -LOCAL long read_mbbiDirect(struct mbbiDirectRecord *prec); -LOCAL void mbbiDirectProcess(mbbiDirectCanPrivate_t *pcanMbbiDirect); -LOCAL void mbbiDirectMessage(mbbiDirectCanPrivate_t *pcanMbbiDirect, canMessage_t *pmessage); -LOCAL void mbbiDirectSignal(mbbiDirectCanPrivate_t *pcanMbbiDirect, int status); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbiDirect; -} devMbbiDirectCan = { - 5, - NULL, - NULL, - init_mbbiDirect, - get_ioint_info, - read_mbbiDirect -}; - - -LOCAL long init_mbbiDirect ( - struct mbbiDirectRecord *prec -) { - mbbiDirectCanPrivate_t *pcanMbbiDirect; - int status; - - if (prec->inp.type != INST_IO) { - recGblRecordError(S_db_badField, (void *) prec, - "devMbbiDirectCan (init_record) Illegal INP field"); - return S_db_badField; - } - - pcanMbbiDirect = (mbbiDirectCanPrivate_t *) malloc(sizeof(mbbiDirectCanPrivate_t)); - if (pcanMbbiDirect == NULL) { - return S_dev_noMemory; - } - prec->dpvt = pcanMbbiDirect; - pcanMbbiDirect->prec = prec; - pcanMbbiDirect->ioscanpvt = NULL; - pcanMbbiDirect->status = NO_ALARM; - - /* Convert the address string into members of the canIo structure */ - status = canIoParse(prec->inp.value.instio.string, &pcanMbbiDirect->inp); - if (status || - pcanMbbiDirect->inp.parameter < 0 || - pcanMbbiDirect->inp.parameter > 7) { - recGblRecordError(S_can_badAddress, (void *) prec, - "devMbbiDirectCan (init_record) bad CAN address"); - return S_can_badAddress; - } - - #ifdef DEBUG - printf("mbbiDirectCan %s: Init bus=%s, id=%#x, off=%d, parm=%d\n", - prec->name, pcanMbbiDirect->inp.busName, pcanMbbiDirect->inp.identifier, - pcanMbbiDirect->inp.offset, pcanMbbiDirect->inp.parameter); - #endif - - /* For mbbiDirect records, the final parameter specifies the input bit shift, - with offset specifying the message byte number. */ - prec->shft = pcanMbbiDirect->inp.parameter; - prec->mask <<= pcanMbbiDirect->inp.parameter; - - #ifdef DEBUG - printf(" shft=%d, mask=%#x\n", - pcanMbbiDirect->inp.parameter, prec->mask); - #endif - - /* Create a callback for asynchronous processing */ - callbackSetCallback(mbbiDirectProcess, &pcanMbbiDirect->callback); - callbackSetPriority(prec->prio, &pcanMbbiDirect->callback); - - /* and a watchdog for CANbus RTR timeouts */ - pcanMbbiDirect->wdId = wdCreate(); - if (pcanMbbiDirect->wdId == NULL) { - return S_dev_noMemory; - } - - /* Register the message and signal handlers with the Canbus driver */ - canMessage(pcanMbbiDirect->inp.canBusID, pcanMbbiDirect->inp.identifier, - (canMsgCallback_t *) mbbiDirectMessage, pcanMbbiDirect); - canSignal(pcanMbbiDirect->inp.canBusID, - (canSigCallback_t *) mbbiDirectSignal, pcanMbbiDirect); - - return OK; -} - -LOCAL long get_ioint_info ( - int cmd, - struct mbbiDirectRecord *prec, - IOSCANPVT *ppvt -) { - mbbiDirectCanPrivate_t *pcanMbbiDirect = (mbbiDirectCanPrivate_t *) prec->dpvt; - - if (pcanMbbiDirect->ioscanpvt == NULL) { - scanIoInit(&pcanMbbiDirect->ioscanpvt); - } - - #ifdef DEBUG - printf("canMbbiDirect %s: get_ioint_info %d\n", prec->name, cmd); - #endif - - *ppvt = pcanMbbiDirect->ioscanpvt; - return OK; -} - -LOCAL long read_mbbiDirect ( - struct mbbiDirectRecord *prec -) { - mbbiDirectCanPrivate_t *pcanMbbiDirect = (mbbiDirectCanPrivate_t *) prec->dpvt; - - if (pcanMbbiDirect->inp.canBusID == NULL) { - return DO_NOT_CONVERT; - } - - #ifdef DEBUG - printf("canMbbiDirect %s: read_mbbiDirect status=%#x\n", prec->name, pcanMbbiDirect->status); - #endif - - switch (pcanMbbiDirect->status) { - case TIMEOUT_ALARM: - case COMM_ALARM: - recGblSetSevr(prec, pcanMbbiDirect->status, MAJOR_ALARM); - pcanMbbiDirect->status = NO_ALARM; - return DO_NOT_CONVERT; - case READ_ALARM: - recGblSetSevr(prec, COMM_ALARM, MINOR_ALARM); - pcanMbbiDirect->status = NO_ALARM; - return DO_NOT_CONVERT; - - case NO_ALARM: - if (prec->pact || prec->scan == SCAN_IO_EVENT) { - #ifdef DEBUG - printf("canMbbiDirect %s: message id=%#x, data=%#x\n", - prec->name, pcanMbbiDirect->inp.identifier, pcanMbbiDirect->data); - #endif - - prec->rval = pcanMbbiDirect->data & prec->mask; - return CONVERT; - } else { - canMessage_t message; - - message.identifier = pcanMbbiDirect->inp.identifier; - message.rtr = RTR; - message.length = 0; - - #ifdef DEBUG - printf("canMbbiDirect %s: RTR, id=%#x\n", - prec->name, pcanMbbiDirect->inp.identifier); - #endif - - prec->pact = TRUE; - pcanMbbiDirect->status = TIMEOUT_ALARM; - - callbackSetPriority(prec->prio, &pcanMbbiDirect->callback); - wdStart(pcanMbbiDirect->wdId, pcanMbbiDirect->inp.timeout, - (FUNCPTR) callbackRequest, (int) pcanMbbiDirect); - canWrite(pcanMbbiDirect->inp.canBusID, &message, pcanMbbiDirect->inp.timeout); - return 0; - } - default: - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - pcanMbbiDirect->status = NO_ALARM; - return DO_NOT_CONVERT; - } -} - -LOCAL void mbbiDirectProcess ( - mbbiDirectCanPrivate_t *pcanMbbiDirect -) { - dbScanLock((struct dbCommon *) pcanMbbiDirect->prec); - (*((struct rset *) pcanMbbiDirect->prec->rset)->process)(pcanMbbiDirect->prec); - dbScanUnlock((struct dbCommon *) pcanMbbiDirect->prec); -} - -LOCAL void mbbiDirectMessage ( - mbbiDirectCanPrivate_t *pcanMbbiDirect, - canMessage_t *pmessage -) { - if (pmessage->rtr == RTR) { - return; /* Ignore RTRs */ - } - - pcanMbbiDirect->data = pmessage->data[pcanMbbiDirect->inp.offset]; - - if (pcanMbbiDirect->prec->scan == SCAN_IO_EVENT) { - pcanMbbiDirect->status = NO_ALARM; - scanIoRequest(pcanMbbiDirect->ioscanpvt); - } else if (pcanMbbiDirect->status == TIMEOUT_ALARM) { - pcanMbbiDirect->status = NO_ALARM; - wdCancel(pcanMbbiDirect->wdId); - callbackRequest(&pcanMbbiDirect->callback); - } -} - -LOCAL void mbbiDirectSignal ( - mbbiDirectCanPrivate_t *pcanMbbiDirect, - int status -) { - switch(status) { - case CAN_BUS_OK: - return; - case CAN_BUS_ERROR: - pcanMbbiDirect->status = READ_ALARM; - break; - case CAN_BUS_OFF: - pcanMbbiDirect->status = COMM_ALARM; - break; - } - callbackRequest(&pcanMbbiDirect->callback); -} diff --git a/src/dev/devMbboCan.c b/src/dev/devMbboCan.c deleted file mode 100644 index 1ff50ff8b..000000000 --- a/src/dev/devMbboCan.c +++ /dev/null @@ -1,245 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - devMbboCan.c - -Description: - CANBUS Multi-Bit Binary Output device support - -Author: - Andrew Johnson -Created: - 14 August 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef struct { - CALLBACK callback; /* This *must* be first member */ - IOSCANPVT ioscanpvt; - struct mbboRecord *prec; - canIo_t out; - long data; - int status; -} mbboCanPrivate_t; - -LOCAL long init_mbbo(struct mbboRecord *prec); -LOCAL long get_ioint_info(int cmd, struct mbboRecord *prec, IOSCANPVT *ppvt); -LOCAL long write_mbbo(struct mbboRecord *prec); -LOCAL void mbboProcess(mbboCanPrivate_t *pcanMbbo); -LOCAL void mbboMessage(mbboCanPrivate_t *pcanMbbo, canMessage_t *pmessage); -LOCAL void mbboSignal(mbboCanPrivate_t *pcanMbbo, int status); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_mbbo; -} devMbboCan = { - 5, - NULL, - NULL, - init_mbbo, - get_ioint_info, - write_mbbo -}; - - -LOCAL long init_mbbo ( - struct mbboRecord *prec -) { - mbboCanPrivate_t *pcanMbbo; - int status; - - if (prec->out.type != INST_IO) { - recGblRecordError(S_db_badField, (void *) prec, - "devMbboCan (init_record) Illegal INP field"); - return S_db_badField; - } - - pcanMbbo = (mbboCanPrivate_t *) malloc(sizeof(mbboCanPrivate_t)); - if (pcanMbbo == NULL) { - return S_dev_noMemory; - } - prec->dpvt = pcanMbbo; - pcanMbbo->prec = prec; - pcanMbbo->ioscanpvt = NULL; - pcanMbbo->status = NO_ALARM; - - /* Convert the parameter string into members of the canIo structure */ - status = canIoParse(prec->out.value.instio.string, &pcanMbbo->out); - if (status || - pcanMbbo->out.parameter < 0 || - pcanMbbo->out.parameter > 7) { - recGblRecordError(S_can_badAddress, (void *) prec, - "devMbboCan (init_record) bad CAN address"); - return S_can_badAddress; - } - - #ifdef DEBUG - printf("canMbbo %s: Init bus=%s, id=%#x, off=%d, parm=%d\n", - prec->name, pcanMbbo->out.busName, pcanMbbo->out.identifier, - pcanMbbo->out.offset, pcanMbbo->out.parameter); - #endif - - /* For mbbo records, the final parameter specifies the output bit shift, - with the offset specifying the message byte number. */ - prec->shft = pcanMbbo->out.parameter; - prec->mask <<= pcanMbbo->out.parameter; - - #ifdef DEBUG - printf(" bit=%d, mask=%#x\n", out.parameter, prec->mask); - #endif - - /* Create a callback for error processing */ - callbackSetCallback(mbboProcess, &pcanMbbo->callback); - callbackSetPriority(prec->prio, &pcanMbbo->callback); - - /* Register the message and signal handlers with the Canbus driver */ - canMessage(pcanMbbo->out.canBusID, pcanMbbo->out.identifier, - (canMsgCallback_t *) mbboMessage, pcanMbbo); - canSignal(pcanMbbo->out.canBusID, (canSigCallback_t *) mbboSignal, pcanMbbo); - - return OK; -} - -LOCAL long get_ioint_info ( - int cmd, - struct mbboRecord *prec, - IOSCANPVT *ppvt -) { - mbboCanPrivate_t *pcanMbbo = (mbboCanPrivate_t *) prec->dpvt; - - if (pcanMbbo->ioscanpvt == NULL) { - scanIoInit(&pcanMbbo->ioscanpvt); - } - - #ifdef DEBUG - printf("mbboCan %s: get_ioint_info %d\n", prec->name, cmd); - #endif - - *ppvt = pcanMbbo->ioscanpvt; - return OK; -} - -LOCAL long write_mbbo ( - struct mbboRecord *prec -) { - mbboCanPrivate_t *pcanMbbo = (mbboCanPrivate_t *) prec->dpvt; - - if (pcanMbbo->out.canBusID == NULL) { - return ERROR; - } - - #ifdef DEBUG - printf("mbboCan %s: write_mbbo status=%#x\n", prec->name, pcanMbbo->status); - #endif - - switch (pcanMbbo->status) { - case COMM_ALARM: - recGblSetSevr(prec, pcanMbbo->status, MAJOR_ALARM); - pcanMbbo->status = NO_ALARM; - return ERROR; - case READ_ALARM: - recGblSetSevr(prec, COMM_ALARM, MINOR_ALARM); - pcanMbbo->status = NO_ALARM; - return ERROR; - - case NO_ALARM: - { - canMessage_t message; - int status; - - message.identifier = pcanMbbo->out.identifier; - message.rtr = SEND; - - pcanMbbo->data = prec->rval & prec->mask; - - message.data[pcanMbbo->out.offset] = pcanMbbo->data; - message.length = pcanMbbo->out.offset + 1; - - #ifdef DEBUG - printf("canMbbo %s: SEND id=%#x, length=%d, data=%#x\n", - prec->name, message.identifier, message.length, - pcanMbbo->data); - #endif - - status = canWrite(pcanMbbo->out.canBusID, &message, - pcanMbbo->out.timeout); - if (status) { - #ifdef DEBUG - printf("canMbbo %s: canWrite status=%#x\n", status); - #endif - - recGblSetSevr(prec, TIMEOUT_ALARM, MINOR_ALARM); - return ERROR; - } - return 0; - } - default: - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - pcanMbbo->status = NO_ALARM; - return ERROR; - } -} - -LOCAL void mbboProcess ( - mbboCanPrivate_t *pcanMbbo -) { - dbScanLock((struct dbCommon *) pcanMbbo->prec); - (*((struct rset *) pcanMbbo->prec->rset)->process)(pcanMbbo->prec); - dbScanUnlock((struct dbCommon *) pcanMbbo->prec); -} - -LOCAL void mbboMessage ( - mbboCanPrivate_t *pcanMbbo, - canMessage_t *pmessage -) { - if (pcanMbbo->prec->scan == SCAN_IO_EVENT && - pmessage->rtr == RTR) { - pcanMbbo->status = NO_ALARM; - scanIoRequest(pcanMbbo->ioscanpvt); - } -} - -LOCAL void mbboSignal ( - mbboCanPrivate_t *pcanMbbo, - int status -) { - switch(status) { - case CAN_BUS_OK: - return; - case CAN_BUS_ERROR: - pcanMbbo->status = READ_ALARM; - break; - case CAN_BUS_OFF: - pcanMbbo->status = COMM_ALARM; - break; - } - callbackRequest(&pcanMbbo->callback); -} diff --git a/src/dev/devMbboDirectCan.c b/src/dev/devMbboDirectCan.c deleted file mode 100644 index c12bcea09..000000000 --- a/src/dev/devMbboDirectCan.c +++ /dev/null @@ -1,245 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - devMbboDirectCan.c - -Description: - CANBUS Multi-Bit Binary Output Direct device support - -Author: - Andrew Johnson -Created: - 14 August 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef struct { - CALLBACK callback; /* This *must* be first member */ - IOSCANPVT ioscanpvt; - struct mbboDirectRecord *prec; - canIo_t out; - long data; - int status; -} mbboDirectCanPrivate_t; - -LOCAL long init_mbboDirect(struct mbboDirectRecord *prec); -LOCAL long get_ioint_info(int cmd, struct mbboDirectRecord *prec, IOSCANPVT *ppvt); -LOCAL long write_mbboDirect(struct mbboDirectRecord *prec); -LOCAL void mbboDirectProcess(mbboDirectCanPrivate_t *pcanMbboDirect); -LOCAL void mbboDirectMessage(mbboDirectCanPrivate_t *pcanMbboDirect, canMessage_t *pmessage); -LOCAL void mbboDirectSignal(mbboDirectCanPrivate_t *pcanMbboDirect, int status); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_mbboDirect; -} devMbboDirectCan = { - 5, - NULL, - NULL, - init_mbboDirect, - get_ioint_info, - write_mbboDirect -}; - - -LOCAL long init_mbboDirect ( - struct mbboDirectRecord *prec -) { - mbboDirectCanPrivate_t *pcanMbboDirect; - int status; - - if (prec->out.type != INST_IO) { - recGblRecordError(S_db_badField, (void *) prec, - "devMbboDirectCan (init_record) Illegal INP field"); - return S_db_badField; - } - - pcanMbboDirect = (mbboDirectCanPrivate_t *) malloc(sizeof(mbboDirectCanPrivate_t)); - if (pcanMbboDirect == NULL) { - return S_dev_noMemory; - } - prec->dpvt = pcanMbboDirect; - pcanMbboDirect->prec = prec; - pcanMbboDirect->ioscanpvt = NULL; - pcanMbboDirect->status = NO_ALARM; - - /* Convert the parameter string into members of the canIo structure */ - status = canIoParse(prec->out.value.instio.string, &pcanMbboDirect->out); - if (status || - pcanMbboDirect->out.parameter < 0 || - pcanMbboDirect->out.parameter > 7) { - recGblRecordError(S_can_badAddress, (void *) prec, - "devMbboDirectCan (init_record) bad CAN address"); - return S_can_badAddress; - } - - #ifdef DEBUG - printf("canMbboDirect %s: Init bus=%s, id=%#x, off=%d, parm=%d\n", - prec->name, pcanMbboDirect->out.busName, pcanMbboDirect->out.identifier, - pcanMbboDirect->out.offset, pcanMbboDirect->out.parameter); - #endif - - /* For mbboDirect records, the final parameter specifies the output bit shift, - with the offset specifying the message byte number. */ - prec->shft = pcanMbboDirect->out.parameter; - prec->mask <<= pcanMbboDirect->out.parameter; - - #ifdef DEBUG - printf(" bit=%d, mask=%#x\n", out.parameter, prec->mask); - #endif - - /* Create a callback for error processing */ - callbackSetCallback(mbboDirectProcess, &pcanMbboDirect->callback); - callbackSetPriority(prec->prio, &pcanMbboDirect->callback); - - /* Register the message and signal handlers with the Canbus driver */ - canMessage(pcanMbboDirect->out.canBusID, pcanMbboDirect->out.identifier, - (canMsgCallback_t *) mbboDirectMessage, pcanMbboDirect); - canSignal(pcanMbboDirect->out.canBusID, (canSigCallback_t *) mbboDirectSignal, pcanMbboDirect); - - return OK; -} - -LOCAL long get_ioint_info ( - int cmd, - struct mbboDirectRecord *prec, - IOSCANPVT *ppvt -) { - mbboDirectCanPrivate_t *pcanMbboDirect = (mbboDirectCanPrivate_t *) prec->dpvt; - - if (pcanMbboDirect->ioscanpvt == NULL) { - scanIoInit(&pcanMbboDirect->ioscanpvt); - } - - #ifdef DEBUG - printf("mbboDirectCan %s: get_ioint_info %d\n", prec->name, cmd); - #endif - - *ppvt = pcanMbboDirect->ioscanpvt; - return OK; -} - -LOCAL long write_mbboDirect ( - struct mbboDirectRecord *prec -) { - mbboDirectCanPrivate_t *pcanMbboDirect = (mbboDirectCanPrivate_t *) prec->dpvt; - - if (pcanMbboDirect->out.canBusID == NULL) { - return ERROR; - } - - #ifdef DEBUG - printf("mbboDirectCan %s: write_mbboDirect status=%#x\n", prec->name, pcanMbboDirect->status); - #endif - - switch (pcanMbboDirect->status) { - case COMM_ALARM: - recGblSetSevr(prec, pcanMbboDirect->status, MAJOR_ALARM); - pcanMbboDirect->status = NO_ALARM; - return ERROR; - case READ_ALARM: - recGblSetSevr(prec, COMM_ALARM, MINOR_ALARM); - pcanMbboDirect->status = NO_ALARM; - return ERROR; - - case NO_ALARM: - { - canMessage_t message; - int status; - - message.identifier = pcanMbboDirect->out.identifier; - message.rtr = SEND; - - pcanMbboDirect->data = prec->rval & prec->mask; - - message.data[pcanMbboDirect->out.offset] = pcanMbboDirect->data; - message.length = pcanMbboDirect->out.offset + 1; - - #ifdef DEBUG - printf("canMbboDirect %s: SEND id=%#x, length=%d, data=%#x\n", - prec->name, message.identifier, message.length, - pcanMbboDirect->data); - #endif - - status = canWrite(pcanMbboDirect->out.canBusID, &message, - pcanMbboDirect->out.timeout); - if (status) { - #ifdef DEBUG - printf("canMbboDirect %s: canWrite status=%#x\n", status); - #endif - - recGblSetSevr(prec, TIMEOUT_ALARM, MINOR_ALARM); - return ERROR; - } - return 0; - } - default: - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - pcanMbboDirect->status = NO_ALARM; - return ERROR; - } -} - -LOCAL void mbboDirectProcess ( - mbboDirectCanPrivate_t *pcanMbboDirect -) { - dbScanLock((struct dbCommon *) pcanMbboDirect->prec); - (*((struct rset *) pcanMbboDirect->prec->rset)->process)(pcanMbboDirect->prec); - dbScanUnlock((struct dbCommon *) pcanMbboDirect->prec); -} - -LOCAL void mbboDirectMessage ( - mbboDirectCanPrivate_t *pcanMbboDirect, - canMessage_t *pmessage -) { - if (pcanMbboDirect->prec->scan == SCAN_IO_EVENT && - pmessage->rtr == RTR) { - pcanMbboDirect->status = NO_ALARM; - scanIoRequest(pcanMbboDirect->ioscanpvt); - } -} - -LOCAL void mbboDirectSignal ( - mbboDirectCanPrivate_t *pcanMbboDirect, - int status -) { - switch(status) { - case CAN_BUS_OK: - return; - case CAN_BUS_ERROR: - pcanMbboDirect->status = READ_ALARM; - break; - case CAN_BUS_OFF: - pcanMbboDirect->status = COMM_ALARM; - break; - } - callbackRequest(&pcanMbboDirect->callback); -} diff --git a/src/dev/devSmAB1746HSTP1.c b/src/dev/devSmAB1746HSTP1.c deleted file mode 100644 index da48661e3..000000000 --- a/src/dev/devSmAB1746HSTP1.c +++ /dev/null @@ -1,1711 +0,0 @@ -/* devSmAB1746HSTP1.c */ -/* - * Original Author: Richard Claus - * Current Author: Richard Claus - * Date: 1/4/96 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1996, the Regents of the University of California, - * the University of Chicago Board of Governors and The Board - * of Trustees of the Leland Stanford Junior University. - * All rights reserved. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * (W-31-109-ENG-38) at Argonne National Laboratory, and - * (DE-AC03-76SF00515) at the Stanford Linear Accelerator Center. - * - * The latter requires the following Disclaimer Notice: - * - * The items furnished herewith were developed under the sponsorship - * of the U.S. Government. Neither the U.S., nor the U.S. D.O.E., nor the - * Leland Stanford Junior University, nor their employees, makes any war- - * ranty, express or implied, or assumes any liability or responsibility - * for accuracy, completeness or usefulness of any information, apparatus, - * product or process disclosed, or represents that its use will not in- - * fringe privately-owned rights. Mention of any product, its manufactur- - * er, or suppliers shall not, nor is it intended to, imply approval, dis- - * approval, or fitness for any particular use. The U.S. and the Univer- - * sity at all times retain the right to use and disseminate the furnished - * items for any purpose whatsoever. Notice 91 02 01 - * - * Initial development by: - * The PEP-II Low Level RF Group - * Positron Electron Project upgrade - * Stanford Linear Accelerator Center - * - * Co-developed with: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * and: - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 1-04-96 rc Created using existing Allen Bradley device - * support as a model - * .02 6-17-96 rc Mods to make -Wall -pedantic not complain - * .03 7-30-96 rc Changed alarm severity reporting in Hstp1Write - * .04 10-09-96 rc/saa Fix bug when there's no hardware and remove - * HW limit alarm. - * ... - */ - - -/* Notes on the usage of this code -| ------------------------------- -| This device support module was written assuming that there are no wiring -| errors. Consequently, if your apparatus does not agree throughout itself -| which direction is clockwise (+) and which direction is counterclockwise (-), -| unexpected things may happen. We (the author, the EPICS community and the -| US government) take no responsibility for damage done to your apparatus or -| anything else as a consequence of errors in this code, bad commands -| processed by this code, wiring errors in the apparatus addressed by this -| code or anything else in relation to this code. -| -| This code was written from the perspective of the Allen Bradley 1746-HSTP1 -| module. Clockwise (+) is therefore defined to be the direction in which -| the stepper motor axis turns when it is viewed from the shaft end of the -| motor, as per page 4-18 of the 1746-HSTP1 User's Manual (AB Pub No. -| 1746-999-121, March 1995). -| -| The 1746-HSTP1 devices have no hardware configuration switches or jumpers -| to be concerned with. However, "HSTP1 CONFIG OUTPUT WORDs" (Pages 4-4 and -| A-1 of the User's Manual) must be passed to the device support layer in the -| parm section of the stepper motor record .OUT field. The string is parsed -| with the format string "%hi%hi%i" and is allowed to be a maximum of -| AB_PARAM_SZ (currently #defined to be 26 in include/link.h) characters -| long. Use only whitespace to separate the values. The three values that -| must be supplied are: -| -| Hstp1CfgCsr[0] - Configuration word -| Hstp1CfgCsr[1] - Active level word -| Hstp1StartSpd - Starting speed word (1 - 250000 pulses/sec) -| -| An example param string is: 0x8413 0x0010 500 -| -| Page 4-4 of the User's Manual states that valid configurations require -| the home limit switch input and one or both of the end (CW or CCW) limit -| switch inputs to be enabled, even if the associated switch is not present. -| -| Due to the way in which the HSTP1 handles limit switch conditions, it is -| best to avoid them. If a limit switch has been activated, one can either -| issue a Find Home command to the HSTP1 to make it hunt for the home switch, -| or issue single step (Jog) commands to bump the jig off the switch. The -| jogging procedure is very slow since it requires a reading the HSTP1 -| registers to get the current state of the limit switches, a clearing of -| the HSTP1 command register to make the appropriate jog bit sensitive to -| transition and a setting of the appropriate jog bit in the command register. -| A 25 MHz NI VXIcpu-030 operating with an AB 6008-SV1R scanning module can -| thus achieve a jog rate of about 3 Hz. -| If a position request causes the jig to run into one of the switches, the -| only motion requests that are accepted by this code are those that move the -| jig in the direction of getting off of the switch, again, presuming no -| wiring errors. -| -| One of the rules of writing EPICS device support code is that the process -| routine must complete as fast as possible since any delays in it cause other -| records to be held up. For this reason all commands to this device support -| layer issued by the record support process routine are queued onto a message -| queue. The reason it is done this way rather than processing the commands -| directly is that there are sometimes delays in getting access to the hard- -| ware, either the VME scanner, or the controller itself. Because it is easy -| to set up a situation in which EPICS sends commands to this code faster than -| they can be processed, one must handle the case where the queue fills up. -| When the queue is full, we break the rules and wait for up to -| HSTP1_K_EPICSQDLY seconds for previously entered commands to be taken off -| the queue in an attempt to throttle EPICS. If the timeout expires, bad -| status is returned to indicate that the command could not be handled at -| the time. Typically, the queue is configured to be deep enough that this -| situation never arises. -| -| In order to reduce the chance of a knobbed .VAL field from overflowing the -| command queue, the motor is declared to be moving as soon as a motion -| request is recognized, even though it is not necessarily moving yet. This -| prevents the record support layer from sending out corrections until the -| motor arrives at the requested spot. However, there is a problem because -| if the position request is changed while the motor is still moving, it will -| be ignored by the record support. To prevent this, supply a non-zero retry -| count and an appropriate deadband when setting up your database. -| Additionally, always put knobs and sliders in "release" mode rather than in -| "motion" mode. -| -| The basic scan rate when there are active stepper motors is 1/3 second. -| When there are no active stepper motors, this code sleeps. Consequently, -| any manual motion of the stepper motor axes is not accounted for. -| -| This code can, in principle, handle an arbitrary number of 1746-HSTP1 -| stepper motor controller modules. However, limitations are provided by -| memory, semaphore, and message queue resources, and bus and "blue hose" -| bandwidths. Note that this code spawns only two tasks, both of which are -| terminated with corresponding resources freed if no stepper motor records -| are found in the system. -| -| As alluded to above, the scheme used in this code is multiply asynchronous. -| The basic sequence of events is: -| EPICS causes a command to be put onto the command queue. -| This causes the ScanTask to wake up to process the command. -| The ScanTask allocates the controller. -| The ScanTask issues the first in a sequence of perhaps several operations -| that make up the command, to the Allen Bradley Scanner driver layer. -| When the AB driver completes the operation (see drvAb.c for details), -| Hstp1Callback is called. -| Hstp1Callback figures out which motor controller operation has completed -| and adds its private block to the response task's work list and then -| wakes up the response task. -| When the response task wakes up, it examines its work list. Then next -| state in the sequence of operations which make up the command is given -| by the state function address that is stored in the private block. The -| response task calls this function. -| Several state functions may be called in this way, each invoked after -| Hstp1Callback signals the previous one has completed. -| When the set of sequences that make up a command is complete, the motor -| controller is deallocated. -| -| The steps this code goes through can be observed with the code compiled with -| -DDBG and the global variable Hstp1Dbg set non-NULL. Beware that there is -| a lot of output, however, especially when multiple motors are being -| controlled. -| -| The response task work list must be updated with mutual exclusion techniques -| in order not to corrupt the list. -| -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define Function(function) static const char FN[] = (function); -#define MASK(bit) (1 << (bit)) -#define wSizeOf(thing) (sizeof(thing) / sizeof(short)) - -#define Printf if (Hstp1Dbg) Hstp1Printf -#ifdef DBG -# define Dbg(cmd) cmd -#else -# define Dbg(cmd) -#endif - - - -/* Configuration word 0 bit definitions for both reading and writing */ -#define HSTP1_M_CWLIM MASK( 0) /* Set for CW limit switch */ -#define HSTP1_M_CCWLIM MASK( 1) /* Set for CCW limit switch */ -#define HSTP1_M_PLSINP MASK( 2) /* Set for pulse train enb/dsb switch */ -#define HSTP1_M_EXTINT MASK( 3) /* Set for external interrupt */ -#define HSTP1_M_HOMELIM MASK( 4) /* Set for home limit switch */ -#define HSTP1_M_HOMEPROX MASK( 5) /* Set for home proximity switch */ -#define HSTP1_M_QUADENC MASK( 8) /* Set for quadrature encoder */ -#define HSTP1_M_DIAGFDBK MASK( 9) /* Set for diagnostic feedback */ -#define HSTP1_M_PLSTRNDIR MASK(10) /* Set for output pulse train & dirn */ -#define HSTP1_M_MRKLIM MASK(12) /* Set for marker pulse home */ -#define HSTP1_M_CFGERR MASK(13) /* Set when a config error exists */ -#define HSTP1_M_MODOK MASK(14) /* Set when module is okay */ -#define HSTP1_M_CFGCMD MASK(15) /* Set for Configuration Mode */ - -/* Configuration word 1 bit definitions for both reading and writing */ -#define HSTP1_M_ACTCWLIM MASK( 0) /* Active level of CW limit switch */ -#define HSTP1_M_ACTCCWLIM MASK( 1) /* Active level of CCW limit switch */ -#define HSTP1_M_ACTPLSINP MASK( 2) /* Active level of pulse train dsb */ -#define HSTP1_M_ACTEXTINT MASK( 3) /* Active level of external interrupt */ -#define HSTP1_M_ACTHOMELIM MASK( 4) /* Active level of home limit switch */ -#define HSTP1_M_ACTHOMEPRX MASK( 5) /* Active level of home prox switch */ - -/* Command word 0 bit definitions for writing */ -#define HSTP1_M_ABSMOVE MASK( 0) /* Execute absolute move */ -#define HSTP1_M_RELMOVE MASK( 1) /* Execute relative move */ -#define HSTP1_M_HOLDMOTN MASK( 2) /* Hold motion */ -#define HSTP1_M_RESMMOTN MASK( 3) /* Resume motion */ -#define HSTP1_M_IMMDSTOP MASK( 4) /* Immediate stop */ -#define HSTP1_M_FNDHMCW MASK( 5) /* Find home in CW direction */ -#define HSTP1_M_FNDHMCCW MASK( 6) /* Find home in CCW direction */ -#define HSTP1_M_JOGCW MASK( 7) /* Execute CW jog */ -#define HSTP1_M_JOGCCW MASK( 8) /* Execute CCW jog */ -#define HSTP1_M_PSETPOSN MASK( 9) /* Preset position */ -#define HSTP1_M_RESETERRS MASK(10) /* Reset errors */ -#define HSTP1_M_PGMBLND MASK(11) /* Program blend move profile */ -#define HSTP1_M_RDBLND MASK(12) /* Read blend move profile */ -#define HSTP1_M_RUNBLND MASK(13) /* Run blend move profile */ -#define HSTP1_M_PSETENC MASK(14) /* Preset encoder position */ -#define HSTP1_M_CMDCFG MASK(15) /* Clear for Command mode */ - -/* Command word 0 bit definitions for reading */ -#define HSTP1_M_CWMOVE MASK( 0) /* Set when axis is moving CW */ -#define HSTP1_M_CCWMOVE MASK( 1) /* Set when axis is moving CCW */ -#define HSTP1_M_HOLD MASK( 2) /* Set when module is in a hold */ -#define HSTP1_M_STOPPED MASK( 3) /* Set when axis is stopped */ -#define HSTP1_M_HOME MASK( 4) /* Set when axis is in a home pos'n */ -#define HSTP1_M_ACCEL MASK( 5) /* Set when axis accelerating */ -#define HSTP1_M_DECEL MASK( 6) /* Set when axis decelerating */ -#define HSTP1_M_MVCMPLT MASK( 7) /* Set when current move is complete */ -#define HSTP1_M_BLENDMV MASK( 8) /* Set when module is in a blend move */ -#define HSTP1_M_SNDNXTBLND MASK( 9) /* Send next blend move data bit */ -#define HSTP1_M_POSNINVALID MASK(10) /* Set when position is invalid */ -#define HSTP1_M_INPERRS MASK(11) /* Set when input errors exist */ -#define HSTP1_M_CMDERR MASK(12) /* Set when a command error exists */ -/* #def HSTP1_M_CFGERR MASK(13) Def'd above: Set when config error */ -/* #def HSTP1_M_MODOK MASK(14) Def'd above: Set when module is OK */ -#define HSTP1_M_MODEFLG MASK(15) /* Mode flag: 0 = Command, 1 = Config */ - -/* Command word 1 bit definitions for reading */ -#define HSTP1_M_CWLIMACT MASK( 0) /* CW limit switch is active */ -#define HSTP1_M_CCWLIMACT MASK( 1) /* CCW limit switch is active */ -#define HSTP1_M_IMMDSTOPACT MASK( 2) /* Immediate stop input is active */ -#define HSTP1_M_EXTINTACT MASK( 3) /* external interrupt is active */ -#define HSTP1_M_HOMELIMACT MASK( 4) /* home limit switch is active */ -#define HSTP1_M_HOMEPRXACT MASK( 5) /* home prox switch is active */ - - -/* Various constants */ -#define HSTP1_K_MINPOSN 0 /* Minimum position value */ -#define HSTP1_K_MAXPOSN 8388607 /* Maximum position value */ -#define HSTP1_K_MINSPEED 1 /* Pulses per second */ -#define HSTP1_K_MAXSPEED 250000 /* Pulses per second */ -#define HSTP1_K_MINACCEL 1 /* Pulses per millisecond per second */ -#define HSTP1_K_MAXACCEL 2000 /* Pulses per millisecond per second */ - -/* Subtask parameters */ -#define HSTP1_SCANNAME "tHstp1Scan" -#define HSTP1_SCANPRI 46 -#define HSTP1_SCANSTK 3072 -#define HSTP1_RESPNAME "tHstp1Resp" -#define HSTP1_RESPPRI 46 -#define HSTP1_RESPSTK 3072 - -#define HSTP1_K_BUFSIZE 256 /* Size of print buffer */ -#define HSTP1_K_CMDCNT 64 /* Maximum number of cmd messages */ -#define HSTP1_K_EPICSQDLY 1 /* Max delay to add cmd to full queue */ -#define HSTP1_K_SCANDELAY (sysClkRateGet () / 3) - -#define VELOCITY 0 /* From recSteppermotor.c */ -#define POSITION 1 /* " " */ - -/* Create the dsets*/ -static long report (int); -static long initialize (int); -static long initRecord (struct steppermotorRecord *); -static long command (struct steppermotorRecord *, short, int, int); - - -typedef struct -{ - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - long (*sm_command) (struct steppermotorRecord *, short, int, int); -} ABSMDSET; - -ABSMDSET devSmAB1746Hstp1 = {5, - report, initialize, initRecord, NULL, command}; - -/* Defines and structures for stepper motor */ -typedef struct motor_data MotorData; -typedef struct steppermotorRecord SmRecord; - -typedef struct -{ - int func; - int arg1; - int arg2; -} Hstp1Msg; - -typedef struct -{ - short msw; - short lsw; -} MswLsw; - -typedef struct _Hstp1CfgOut -{ - unsigned short cfg; - unsigned short actLvl; - MswLsw startSpd; - short pad[4]; -} Hstp1CfgOut; - -typedef struct _Hstp1CfgOut Hstp1CfgIn; - -typedef struct -{ - Hstp1CfgIn in; - Hstp1CfgOut out; -} Hstp1Cfg; - -typedef struct -{ - unsigned short cmd; - unsigned short resvd; - MswLsw posn; - MswLsw vel; - short accel; - short decel; -} Hstp1CmdOut; - -typedef struct -{ - unsigned short status[2]; - MswLsw posn; - MswLsw encPosn; - short pad[2]; -} Hstp1CmdIn; - -typedef struct -{ - Hstp1CmdIn in; - Hstp1CmdOut out; -} Hstp1Cmd; - -typedef struct _Hstp1Pvt /* Block per stepper motor record */ -{ - NODE scanLnks; /* Links used by the scan task */ - NODE respLnks; /* Links used by the response task */ - void *hstp1Blk; /* Info common to all HSTP1s */ - void *drvPvt; /* Per HSTP1 driver private block */ - SmRecord *rec; /* Pointer to stepper motor record */ - int (*recCb) (MotorData *, SmRecord *); - void *recCbArg; /* Rec sup callback and arg */ - void (*stateFn) (struct _Hstp1Pvt *, void *); /* State function */ - void *stateArg; /* Argument for stateFn function */ - MSG_Q_ID cmdQue; /* Command message queue */ - int move; /* A positional move is in progress */ - int stop; /* Emergency stop flag */ - SEM_ID allocSem; /* Controller allocation semaphore */ - int active; /* TRUE when controller is active */ - int busy; /* TRUE if CB info not yet processed */ - unsigned long startSpd; /* Starting speed in easy to use form */ - int mode; /* POSITION or VELOCITY */ - Hstp1Cfg cfg; /* Current config registers */ - Hstp1Cmd cmd; /* Current command registers */ - union - { - Hstp1CfgIn cfg; - Hstp1CmdIn cmd; - } rdBuf; /* Register buffer when type unknown */ - MotorData motorData; /* Processed motor data for rec sup */ -} Hstp1Pvt; - -typedef struct /* Block for all HSTP1s in system */ -{ - int scanTid; /* Register read-back task ID */ - SEM_ID scanSem; /* Semaphore to wake ScanTask */ - LIST scanLst; /* Linked list of Hstp1Pvt blocks */ - int respTid; /* Register analysis task ID */ - SEM_ID respSem; /* Semaphore to wake RespTask */ - LIST respLst; /* Linked work list for RespTask */ - SEM_ID listSem; /* Mutual exclusion sem for respLst */ -} Hstp1Blk; - - -static Hstp1Blk *Hstp1 = NULL; /* For missing arg on some functions */ -int Hstp1Dbg = FALSE; /* TRUE to enable debugging prints */ - - -/* Forward references */ -static void StateRead (Hstp1Pvt *, void *); -static void StateWrite (Hstp1Pvt *, void *); -static void StateCfgClr (Hstp1Pvt *, void *); -static void StateJog (Hstp1Pvt *, void *); -static void StatePsetEnc (Hstp1Pvt *, void *); - -static void ProcessAction (Hstp1Pvt *, int, int, int); -static void StateCfgRead (Hstp1Pvt *, void *); -static void StateCmdRead (Hstp1Pvt *, void *); -static void Hstp1ScanTask (Hstp1Blk *); -static void Hstp1RespTask (Hstp1Blk *); -static void Hstp1Callback (void *); - -static int Hstp1Read (Hstp1Pvt *, void *, int); -static int Hstp1Write (Hstp1Pvt *, void *, int); -static int Hstp1Clear (Hstp1Pvt *); - -static long Hstp1Eval (MswLsw); -static char *Hstp1Sprintf (char *, const char *, char *, ...); -static int Hstp1Printf (const char *, char *, ...); - - - -static void Hstp1Callback (void *drvPvt) -/* - Description - ----------- - This is the call-back routine that is called by the Allen Bradley driver - support module when a block transfer operation completes. - - Parameters - ---------- - drvPvt - A pointer to the driver private block - - Returns - ------- - nothing -*/ -{ - Function ("Hstp1Callback") - - Hstp1Pvt *hstp1; - - - /* Find the device private block for this module */ - hstp1 = (Hstp1Pvt *) (*pabDrv->getUserPvt) (drvPvt); - - Dbg (Printf (FN, "drvPvt = %08x, hstp1 = %08x", drvPvt, hstp1)); - - if (!hstp1) return; - - /* Add controller to list of motors to be processed */ - if (!hstp1->busy) - { - Hstp1Blk *hstp1Blk = (Hstp1Blk *) hstp1->hstp1Blk; - - /* Only one callback per motor is allowed to be outstanding at any time */ - hstp1->busy = TRUE; - - /* Block list updates while we add to it */ - semTake (hstp1Blk->listSem, WAIT_FOREVER); - lstAdd (&hstp1Blk->respLst, &hstp1->respLnks); - semGive (hstp1Blk->listSem); - - /* Wake up the response task */ - semGive (hstp1Blk->respSem); - } - else - { - Hstp1Printf (FN, "Previous callback for motor %0x not processed yet", - hstp1); - semGive (hstp1->allocSem); - } -} - - - -static long command (SmRecord *rec, - short func, - int arg1, - int arg2) -/* - Description - ----------- - This function is called by the record support module when it desires to - carry out an operation on a stepper motor. Most functions require access to - the stepper motor controller registers. The rules of EPICS device support - state that it is not permissible to delay processing in this routine. - Therefore, if a previous call to this routine initiated a series of - opperations to the stepper motor controller, all that can be done on a - subsequent call is to queue up the request for later processing. If the - queue is full, then we actually do delay processing to allow some of the - entry slots in the queue to free up and to keep EPICS from sending more - requests. - - When the previous request completes, the queued up request will start via - the Scan Task. This means that there may be a significant delay between a - request and the time it is actually carried out. This should not be of any - consequence since the delay is much smaller than the inherent slow behavior - of the motor itself. - - Parameters - ---------- - rec - A pointer to the active record - func - The function to be carried out (defined in steppermotor.h) - arg1 - An argument to go along with func - arg2 - An argument to go along with func - - Returns - ------- - 0 (success) or -1 (failure) */ -{ - Function ("command") - - Hstp1Pvt *hstp1 = (Hstp1Pvt *) rec->dpvt; - int send = FALSE; - - - Dbg (Printf (FN, "func = %hd, arg1 = %d, arg2 = %d", func, arg1, arg2)); - - /* Verify that init succeeded */ - if (!hstp1) - { - Hstp1Printf (FN, "rec->devPvt is NULL"); - recGblSetSevr (rec, WRITE_ALARM, INVALID_ALARM); - return (-1); /* Don't convert */ - } - - hstp1->stop = FALSE; - - /* Process the requested command */ - switch (func) - { - case SM_MODE: /* Configure device on mode update */ - { - char *prm = rec->out.value.abio.parm; - short cfgCsr[2]; - long startSpd; - - Dbg (Printf (FN, "SM_MODE - prm = |%s|, len = %u", prm, strlen (prm))); - - /* Parse configuration parameters from record parm field string */ - if (sscanf (prm, "%hi%hi%i", &cfgCsr[0], &cfgCsr[1], &startSpd) < 3) - { - char buf[HSTP1_K_BUFSIZE]; - - recGblRecordError (S_db_badField, (void *) rec, - Hstp1Sprintf (buf, FN, -"\tSM_MODE - Bad or missing record parm field")); - return (-1); - } - - /* Save the mode type */ - hstp1->mode = arg1; - - /* Get start speed within range and split into MSW and LSW */ - if (startSpd < HSTP1_K_MINSPEED) startSpd = HSTP1_K_MINSPEED; - if (startSpd > HSTP1_K_MAXSPEED) startSpd = HSTP1_K_MAXSPEED; - - arg1 = *(int *) cfgCsr; - arg2 = startSpd; - - send = TRUE; - } - break; - - case SM_VELOCITY: /* Set the velocity and acceleration */ - { - register int vel = arg1; /* arg1 in pulses/sec */ - register short accel = (arg2 + 500) / 1000; /* arg2 in pulses/sec/sec */ - - /* Get velocity and acceleration within range, split into MSW and LSW */ - if (vel < hstp1->startSpd) vel = hstp1->startSpd; - if (vel > HSTP1_K_MAXSPEED) vel = HSTP1_K_MAXSPEED; - if (accel < HSTP1_K_MINACCEL) accel = HSTP1_K_MINACCEL; - if (accel > HSTP1_K_MAXACCEL) accel = HSTP1_K_MAXACCEL; - - arg1 = vel; - arg2 = accel; - - send = TRUE; - } - break; - - case SM_FIND_HOME: /* Move to a home switch */ - /* break purposely left out to continue with SM_FIND_LIMIT */ - - case SM_FIND_LIMIT: /* Move to a limit switch */ - arg1 = arg1 >= 0 ? HSTP1_K_MAXPOSN : -HSTP1_K_MAXPOSN; - /* break purposely left out to continue with SM_MOVE */ - - case SM_MOVE: /* Move the motor */ - if (hstp1->mode == POSITION) - { - /* Postpone corrections by EPICS until motor gets to requested spot */ - if (arg1) rec->movn = TRUE; - - send = TRUE; - } - break; - - case SM_MOTION: /* Control the motion */ - if (arg1 == 0) /* Emergency stop */ - { - hstp1->stop = TRUE; /* Short circuit any in-progress motn */ - } - send = TRUE; - break; - - case SM_CALLBACK: /* Set recSup call-back routine & arg */ - if (hstp1->recCb != 0) return (-1); - hstp1->recCb = (int (*) ()) arg1; - hstp1->recCbArg = (void *) arg2; - break; - - case SM_SET_HOME: /* Define present position to be zero */ - if (hstp1->mode == POSITION) send = TRUE; - break; - - case SM_ENCODER_RATIO: /* Set the encoder ratio */ - /* Not sure what to do for this */ - break; - - case SM_READ: /* Read the motor status */ - send = TRUE; - break; - } - - /* Send a message to the scan task and wake it up */ - if (send) - { - Hstp1Msg msg; - - msg.func = func; - msg.arg1 = arg1; - msg.arg2 = arg2; - - /* Throttle EPICS if rate of messages overflows queue */ - if (msgQSend (hstp1->cmdQue, (char *) &msg, sizeof (msg), - (HSTP1_K_EPICSQDLY * sysClkRateGet ()), MSG_PRI_NORMAL) != OK) - { - if (errnoGet () == S_objLib_OBJ_UNAVAILABLE) - Hstp1Printf (FN, "command queue overflow"); - else - Hstp1Printf (FN, "command queue error: %s", strerror (errnoGet ())); - recGblSetSevr (rec, WRITE_ALARM, INVALID_ALARM); - - return (-1); - } - - /* Wake up the scan task */ - semGive (((Hstp1Blk *) (hstp1->hstp1Blk))->scanSem); - } - - return (0); -} - - - -static void Hstp1ScanTask (Hstp1Blk *hstp1Blk) -/* - Description - ----------- - This is the main routine of the Scan Task. Its job is to initiate - processing of commands to the stepper motor controller. When an activity - causes this task to wake up, it goes through the list of stepper motor - controller until it finds an active one. Multiple controllers may be - active at the same time. A controller may be activated in order to - process a new command or to do a periodic status update. - - Once an active controller has been found, this task tries to allocate - it. If there is a command sequence in progress, this will fail. - Consequently, the task goes on to look for another active controller to - treat. When it gets to the end of the list and there is still an active - controller, it delays for a short time to allow the in-progress sequence(s) - to complete before trying again. - - Once the controller has been allocated, the command message queue is - checked. If a message is found, it is processed. If not, then it is - assumed that the controller has been activated in order to do a status - update and so that is processed. - - Parameters - ---------- - hstp1Blk - A pointer to the per system control block - - Returns - ------- - doesn't -*/ -{ - Function ("Hstp1ScanTask") - - int hstp1Active; - int msgCnt; - - - Dbg (Printf (FN, "starting, hstp1Blk = %08x", hstp1Blk)); - - /* Loop 'til we're killed */ - while (TRUE) - { - /* Wait until somebody wakes us up */ - semTake (hstp1Blk->scanSem, WAIT_FOREVER); - - Dbg (Printf (FN, "awoke")); - - /* Loop over motor controllers so long as there is one active */ - hstp1Active = TRUE; - while (hstp1Active) - { - Hstp1Pvt *hstp1 = (Hstp1Pvt *) lstFirst (&hstp1Blk->scanLst); - - /* Treat active controllers */ - hstp1Active = FALSE; - while (hstp1) - { - msgCnt = msgQNumMsgs (hstp1->cmdQue); - if (hstp1->active || msgCnt) - { - hstp1Active = TRUE; - - /* If no cmd seq for this module is in progress, alloc & start seq */ - if (semTake (hstp1->allocSem, NO_WAIT) == OK) - { - Hstp1Msg msg; - - /* If message waiting, process it, else must be a monitor request */ - if (msgCnt) - { - if (msgQReceive (hstp1->cmdQue, (char *) &msg, sizeof (msg), - NO_WAIT) == ERROR) - { - Hstp1Printf (FN, "command queue error: %s", - strerror (errnoGet ())); - } - else - { - Dbg (Printf (FN, "func = %i", msg.func)); - ProcessAction (hstp1, msg.func, msg.arg1, msg.arg2); - } - } - else - { - Dbg (Printf (FN, "Queueing read")); - - ProcessAction (hstp1, SM_READ, 0, 0); - } - } - } - - /* Go on to the next controller in the list */ - hstp1 = (Hstp1Pvt *) lstNext (&hstp1->scanLnks); - } - - /* Wait before we poll again if all controllers were busy */ - semTake (hstp1Blk->scanSem, HSTP1_K_SCANDELAY); - } - Dbg (Printf (FN, "Going to sleep")); - } -} - - - -static void ProcessAction (Hstp1Pvt *hstp1, - int func, - int arg1, - int arg2) -/* - Description - ----------- - This function processes command requests and queues the first block - transfer of the sequence necessary to fulfill the request. - - Parameters - ---------- - hstp1 - A pointer to the HSTP1 private block - func - A function to be carried out (defined in steppermotor.h) - arg1 - An argument to go along with func - arg2 - An argument to go along with func - - Returns - ------- - nothing -*/ -{ - Dbg (Function ("ProcessAction")) - - - /* Set up device registers */ - switch (func) - { - case SM_MODE: /* Configure device on mode update */ - { - register Hstp1CfgOut *cfg = &hstp1->cfg.out; - - /* Configure the motor */ - cfg->cfg = ((short *) &arg1)[0]; - cfg->actLvl = ((short *) &arg1)[1]; - cfg->startSpd.msw = arg2 / 1000; - cfg->startSpd.lsw = arg2 - 1000 * cfg->startSpd.msw; - - /* Update the configuration registers */ - Dbg (Printf (FN, "SM_MODE - State going to Write")); - hstp1->stateFn = StateCfgClr; - Hstp1Write (hstp1, (void *) cfg, wSizeOf (*cfg)); - } - break; - - case SM_VELOCITY: /* Set the velocity and acceleration */ - { - register Hstp1CmdOut *cmd = &hstp1->cmd.out; - - cmd->vel.msw = arg1 / 1000; - cmd->vel.lsw = arg1 - 1000 * cmd->vel.msw; - cmd->accel = arg2; - cmd->decel = arg2; - - Dbg (Printf (FN, -"SM_VELOCITY -\narg1 = %i, coarse = %hi, fine = %hi, arg2 = %i", - arg1, cmd->vel.msw, cmd->vel.lsw, arg2)); - - /* Free the controller for the next command */ - semGive (hstp1->allocSem); - } - break; - - case SM_FIND_HOME: /* Make motor find the home switch */ - { - hstp1->cmd.out.cmd = arg1 >= 0 ? HSTP1_M_FNDHMCW : HSTP1_M_FNDHMCCW; - - hstp1->move = TRUE; - - /* To resensitize all command word 0 bits to transitions, clear it */ - Dbg (Printf (FN, "SM_MOVE - State going to Clear")); - hstp1->stateFn = StateCfgClr; - Hstp1Clear (hstp1); - } - break; - - case SM_FIND_LIMIT: /* Move to a limit switch */ - case SM_MOVE: /* Move the motor */ - { - register Hstp1CmdOut *cmd = &hstp1->cmd.out; - register int posnSign = 0; - register long posn = arg1; - register short coarsePosn; - register short finePosn; - - /* Deal with the annoying way that the HSTP1 handles sign */ - if (posn < 0) - { - posn = -posn; - posnSign = 1 << 15; - } - - /* Split position request into coarse and fine values */ - coarsePosn = posn / 1000; - finePosn = posn - 1000 * coarsePosn; - - /* Set the command words appropriately */ - cmd->posn.msw = coarsePosn | posnSign; - cmd->posn.lsw = finePosn; - cmd->cmd = HSTP1_M_RELMOVE; - - Dbg (Printf (FN, "\ncmd = %h04x, posn = %h04x, %h04x, vel = %h04x, %h04x, accel = %hi, decel = %hi", - cmd->cmd, cmd->posn.msw, cmd->posn.lsw, - cmd->vel.msw, cmd->vel.lsw, cmd->accel, cmd->decel)); - - hstp1->move = TRUE; - - /* To resensitize all command word 0 bits to transitions, clear it */ - Dbg (Printf (FN, "SM_MOVE - State going to Clear")); - hstp1->stateFn = StateCfgClr; - Hstp1Clear (hstp1); - } - break; - - case SM_MOTION: /* Control the motion */ - { - register Hstp1CmdOut *cmd = &hstp1->cmd.out; - - if (arg1 == 0) /* Emergency stop */ - { - cmd->cmd = HSTP1_M_IMMDSTOP; - - Dbg (Printf (FN, "SM_MOTION - State going to Write")); - hstp1->stateFn = StateWrite; - Hstp1Write (hstp1, (void *) cmd, wSizeOf (*cmd)); - } - else if (hstp1->mode == VELOCITY) /* Start the motor */ - { - hstp1->move = TRUE; - - cmd->cmd = arg2 ? HSTP1_M_JOGCCW : HSTP1_M_JOGCW; - - /* To resensitize all command word 0 bits to transitions, clear it */ - Dbg (Printf (FN, "SM_MOTION - State going to Clear")); - hstp1->stateFn = StateCfgClr; - Hstp1Clear (hstp1); - } - } - break; - - case SM_SET_HOME: /* Define present position to be zero */ - { - register Hstp1CmdOut *cmd = &hstp1->cmd.out; - - cmd->posn.msw = 0; - cmd->posn.lsw = 0; - cmd->cmd = HSTP1_M_PSETPOSN; /* Can't also preset encoder */ - - /* Send the command */ - Dbg (Printf (FN, "SM_SET_HOME - State going to Write")); - hstp1->stateFn = hstp1->cfg.in.cfg & HSTP1_M_QUADENC ? StatePsetEnc - : StateWrite; - Hstp1Write (hstp1, (void *) cmd, wSizeOf (*cmd)); - } - break; - - case SM_READ: /* Read the motor status */ - Dbg (Printf (FN, "SM_READ - State going to Read")); - hstp1->stateFn = StateRead; - Hstp1Read (hstp1, (void *) &hstp1->rdBuf, wSizeOf (hstp1->rdBuf)); - break; - } -} - - - -static void Hstp1RespTask (Hstp1Blk *hstp1Blk) -/* - Description - ----------- - This is the main routine of the response task. This task wakes up in - response to a block transfer completion. If the block transfer failed - for some reason an alarm is raised and the controller is deallocated. - If it succeeded, the next state function (as determined by the previous - state function) in the sequence is called. - - Parameters - ---------- - hstp1Blk - A pointer to the system HSTP1 control block - - Returns - ------- - doesn't -*/ -{ - Function ("Hstp1RespTask") - - abStatus status; - Hstp1Pvt *hstp1 = NULL; - - - Dbg (Printf (FN, "starting, hstp1Blk = %08x", hstp1Blk)); - - /* Loop 'til the rug is pulled out from under our feet */ - while (TRUE) - { - /* Wait for somebody to wake us up */ - semTake (hstp1Blk->respSem, WAIT_FOREVER); - - /* Get the motor controller of interest with list updates blocked */ - semTake (hstp1Blk->listSem, WAIT_FOREVER); - hstp1 = (void *) lstGet (&hstp1Blk->respLst); - semGive (hstp1Blk->listSem); - if (hstp1 == NULL) - { - Hstp1Printf (FN, "Motor controller pointer is unexpectedly null"); - continue; - } - hstp1 = (Hstp1Pvt *)((long) hstp1 - ((long) &(((Hstp1Pvt *) 0)->respLnks))); - hstp1->busy = FALSE; - - Dbg (Printf (FN, "awoke with hstp1 = %08x", hstp1)); - - /* Deal with bad BT completion status */ - if ((status = (*pabDrv->getStatus) (hstp1->drvPvt)) != abSuccess) - { - Dbg (Printf (FN, "BT completion status = %s", abStatusMessage[status])); - recGblSetSevr (hstp1->rec, COMM_ALARM, INVALID_ALARM); - semGive (hstp1->allocSem); - } - else - { - /* Handle the current state by calling the appropriate function */ - (*hstp1->stateFn) (hstp1, hstp1->stateArg); - } - } -} - - - -static void StateRead (Hstp1Pvt *hstp1, - void *arg) -{ - /* Determine what we're looking at and copy it to the right place */ - if (hstp1->rdBuf.cfg.cfg & HSTP1_M_CFGCMD) - { - memcpy (&hstp1->cfg.in, &hstp1->rdBuf.cfg, sizeof (hstp1->cfg.in)); - StateCfgRead (hstp1, arg); - } - else - { - memcpy (&hstp1->cmd.in, &hstp1->rdBuf.cmd, sizeof (hstp1->cmd.in)); - StateCmdRead (hstp1, arg); - } -} - - - -static void StateCfgRead (Hstp1Pvt *hstp1, - void *arg) -{ - Dbg (Function ("StateCfgRead")) - - Hstp1CfgIn *cfg = &hstp1->cfg.in; - Hstp1CmdOut cmd = {0, 0, {0, 0}, {0, 0}, 0, 0}; - - - Dbg (Printf (FN, "cfg = %04x, lvl = %04x, spd = %h04x, %h04x", - cfg->cfg, cfg->actLvl, cfg->startSpd.msw, cfg->startSpd.lsw)); - - /* Handle errors */ - if (!(cfg->cfg & HSTP1_M_MODOK) || (cfg->cfg & HSTP1_M_CFGERR)) - { - recGblSetSevr (hstp1->rec, UDF_ALARM, INVALID_ALARM); - } - - /* Force HSTP1 into command mode */ - memcpy (&cmd, &hstp1->cmd.out, sizeof (cmd)); - cmd.cmd = 0; - - /* Send the command */ - Dbg (Printf (FN, "State going to Write")); - hstp1->stateFn = StateWrite; - Hstp1Write (hstp1, (void *) &cmd, wSizeOf (cmd)); -} - - - -static void StateCmdRead (Hstp1Pvt *hstp1, - void *arg) -{ - Dbg (Function ("StateCmdRead")) - - Hstp1CmdIn *cmd = &hstp1->cmd.in; - MotorData *md = &hstp1->motorData; - - - Dbg (Printf (FN, "\nstatus[0,1] = %h04x, %h04x, posn = %h04x, %h04x, encPosn = %h04x, %h04x", - cmd->status[0], cmd->status[1], - cmd->posn.msw, cmd->posn.lsw, - cmd->encPosn.msw, cmd->encPosn.lsw)); - - /* Process the command data into a format that record support likes */ - md->cw_limit = (cmd->status[1] & HSTP1_M_CWLIMACT) ? 1 : 0; - md->ccw_limit = (cmd->status[1] & HSTP1_M_CCWLIMACT) ? 1 : 0; - md->direction = (cmd->status[0] & HSTP1_M_CCWMOVE) ? 1 : 0; - md->moving = (cmd->status[0] & - (HSTP1_M_CWMOVE | HSTP1_M_CCWMOVE | - HSTP1_M_ACCEL | HSTP1_M_DECEL)) ? 1 : 0; - md->constant_velocity = ( cmd->status[0] & - (HSTP1_M_CWMOVE | HSTP1_M_CCWMOVE) && - !(cmd->status[0] & - (HSTP1_M_ACCEL | HSTP1_M_DECEL))) ? 1 : 0; - md->encoder_position = Hstp1Eval (cmd->encPosn); - md->motor_position = Hstp1Eval (cmd->posn); - - Dbg (Printf (FN, "\ncwLim = %d, ccwLim = %d, dir = %d, moving = %d, motor_position = %d", - md->cw_limit, md->ccw_limit, md->direction, - md->moving, md->motor_position)); - - /* For move operations we may need to jog off a limit switch first */ - if (hstp1->move && !hstp1->stop) - { - if (md->cw_limit || md->ccw_limit) - { - Hstp1CmdOut jog = {0, 0, {0, 0}, {0, 0}, 0, 0}; - register Hstp1CmdOut *cmd = &hstp1->cmd.out; - register MswLsw *posn = &cmd->posn; - register long req = hstp1->mode == POSITION ? - Hstp1Eval (*posn) : (cmd->cmd == HSTP1_M_JOGCCW ? -1 : 1); - - /* - | Choose a single step direction, unless request is out of range or - | movement would cause the jig to go deeper into the limit switch - */ - if (md->cw_limit && (req < 0)) - { - jog.cmd = HSTP1_M_JOGCCW; - } - else if (md->ccw_limit && (req > 0)) - { - jog.cmd = HSTP1_M_JOGCW; - } - - /* Single step, if so indicated */ - if (jog.cmd) - { - /* - | Update the relative position request to include this step. - | NB that posn is a positive number with the sign in a special bit! - | Thus only decrement operations are valid as we get closer to the - | desired position. There is no need to worry about a sign change - | since we've arrived at the desired position if posn == 0. At that - | point req == 0 and nothing happens, unless we're in velocity mode - */ - if (hstp1->mode == POSITION) - { - posn->lsw--; - if (posn->lsw < 0) - { - posn->lsw = 999; - posn->msw--; - } - } - - /* Let EPICS know there is a move instruction in progress */ - md->moving = md->moving || hstp1->move; - - /* Jog and set up to clear and read limit switch state again */ - Dbg (Printf (FN, "State going to Jog, jog = %d", jog.cmd)); - hstp1->stateFn = StateJog; - Hstp1Write (hstp1, (void *) &jog, wSizeOf (jog)); - } - else - { - /* Indicate the move has been completed */ - hstp1->move = FALSE; - } - } - else - { - Hstp1CmdOut *out = &hstp1->cmd.out; - - /* Let EPICS know there is a move instruction in progress */ - md->moving = md->moving || hstp1->move; - - /* Indicate the move instruction has been taken care of (well, almost) */ - hstp1->move = FALSE; - - /* Go update the registers */ - Dbg (Printf (FN, "State going to Write")); - hstp1->stateFn = StateWrite; - Hstp1Write (hstp1, (void *) out, wSizeOf (*out)); - - /* Update DB velocity and acceleration only after command was output */ - md->velocity = (((hstp1->mode == VELOCITY) && - (out->cmd & HSTP1_M_JOGCCW)) ? -1 : 1) * - Hstp1Eval (out->vel); - md->accel = 1000 * out->accel; - } - } - - /* Post results to database */ - if (hstp1->recCb) - { - (*hstp1->recCb) (md, hstp1->recCbArg); - Dbg (Printf (FN, "Back from SMCB_Callback, init = %d, sthm = %d", - hstp1->rec->init, hstp1->rec->sthm)); - } - - /* Set alarms, if any */ - Dbg (Printf (FN, "status = %h04x, %h04x", cmd->status[0], cmd->status[1])); - - if (!(cmd->status[0] & HSTP1_M_MODOK) || (cmd->status[0] & HSTP1_M_CFGERR)) - { - recGblSetSevr (hstp1->rec, UDF_ALARM, INVALID_ALARM); - } - else if (cmd->status[0] & HSTP1_M_CMDERR) - { - recGblSetSevr (hstp1->rec, WRITE_ALARM, MINOR_ALARM); - } - - /* If we've just output a move command, return without freeing controller */ - if ((hstp1->stateFn == StateJog) || (hstp1->stateFn == StateWrite)) return; - - /* If motor is moving, mark the motor active */ - hstp1->active = md->moving; - - /* Free the controller */ - Dbg (Printf (FN, "State going to Free")); - semGive (hstp1->allocSem); -} - - - -static void StateWrite (Hstp1Pvt *hstp1, - void *arg) -{ - Dbg (Function ("StateWrite")) - - - /* Free the controller */ - Dbg (Printf (FN, "State going to Free")); - semGive (hstp1->allocSem); - - /* Enable the scan task to periodically read controller status */ - Dbg (Printf (FN, "Waking ScanTask")); - hstp1->active = TRUE; - semGive (((Hstp1Blk *) (hstp1->hstp1Blk))->scanSem); -} - - - -static void StateCfgClr (Hstp1Pvt *hstp1, - void *arg) -{ - Dbg (Function ("StateCfgClr")) - - Dbg (Printf (FN, "State going to Read")); - hstp1->stateFn = StateRead; - Hstp1Read (hstp1, (void *) &hstp1->rdBuf, wSizeOf (hstp1->rdBuf)); -} - - - -static void StateJog (Hstp1Pvt *hstp1, - void *arg) -{ - Dbg (Function ("StateJog")) - - static Hstp1CmdOut clear = {0, 0, {0, 0}, {0, 0}, 0, 0}; - - - Dbg (Printf (FN, "State going to CfgClr")); - hstp1->stateFn = StateCfgClr; - - /* Go clear the command registers */ - Hstp1Write (hstp1, (void *) &clear, wSizeOf (clear)); -} - - - -static void StatePsetEnc (Hstp1Pvt *hstp1, - void *arg) -{ - Dbg (Function ("StatePsetEnc")) - - Dbg (Printf (FN, "State going to Write")); - hstp1->stateFn = StateWrite; - - hstp1->cmd.out.posn.msw = 0; - hstp1->cmd.out.posn.lsw = 0; - hstp1->cmd.out.cmd = HSTP1_M_PSETENC; - Hstp1Write (hstp1, (void *) &hstp1->cmd.out, wSizeOf (hstp1->cmd.out)); -} - - - -static int Hstp1Clear (Hstp1Pvt *hstp1) -{ - Hstp1CmdOut zero; - - - /* Clear only the command word of the output buffer */ - memcpy (&zero, &hstp1->cmd.out, sizeof (hstp1->cmd.out)); - zero.cmd = 0; - - return (Hstp1Write (hstp1, (void *) &zero, wSizeOf (zero))); -} - - - -static int Hstp1Write (Hstp1Pvt *hstp1, - void *msg, - int msgLen) -{ - Dbg (Function ("Hstp1Write")) - - register int loopCount = sysClkRateGet () / 3; - abStatus status; - - - /* Initiate a block transfer to set the new register values */ - do - { - if ((status = (*pabDrv->btWrite) (hstp1->drvPvt, msg, msgLen)) != abBusy) - break; - taskDelay (sysClkRateGet () / 20); - } while (loopCount--); - - /* If not queued within the timeout period, indicate error */ - if (status != abBtqueued) - { - unsigned short severity = INVALID_ALARM; - - Dbg (Printf (FN, "btWrite failed with %s", abStatusMessage[status])); - if ((status == abBusy) || (status == abTimeout)) severity = MAJOR_ALARM; - recGblSetSevr (hstp1->rec, WRITE_ALARM, severity); - semGive (hstp1->allocSem); - return (ERROR); - } - - return (OK); -} - - - -static int Hstp1Read (Hstp1Pvt *hstp1, - void *msg, - int msgLen) -{ - Dbg (Function ("Hstp1Read")) - - register int loopCount = sysClkRateGet () / 3; - abStatus status; - - - /* Initiate a block transfer to get the new register values */ - do - { - if ((status = (*pabDrv->btRead) (hstp1->drvPvt, msg, msgLen)) != abBusy) - break; - taskDelay (sysClkRateGet () / 20); - } while (loopCount--); - - /* If not queued within the timeout period, indicate error */ - if (status != abBtqueued) - { - Dbg (Printf (FN, "btRead failed with %s", abStatusMessage[status])); - recGblSetSevr (hstp1->rec, READ_ALARM, MAJOR_ALARM); - semGive (hstp1->allocSem); - return (ERROR); - } - - return (OK); -} - - - -static long initialize (int after) -/* - Description - ----------- - This is the initialization function that is called once before the record - support level initializes and once afterward. In this routine we start - up the scan and response tasks and allocate the various resources needed. - If upon the second call, no stepper motor records were found in the data - base, these resources and tasks are freed. - - Parameters - ---------- - after - Flag that is 1 on the second call - - Returns - ------- - 0 (zero) -*/ -{ - Function ("initialize") - - Hstp1Blk *hstp1Blk = Hstp1; - - - Dbg (Printf (FN, "called with after = %u", after)); - - if (after == 1) - { - if (hstp1Blk == NULL) - { - Hstp1Printf (FN, "hstp1Blk is unexpectedly NULL"); - taskSuspend (0); - } - - /* If the DB contains no motor records, kill the motor tasks */ - if (lstCount (&hstp1Blk->scanLst) == 0) - { - taskwdRemove (hstp1Blk->scanTid); - taskwdRemove (hstp1Blk->respTid); - taskDelete (hstp1Blk->scanTid); - taskDelete (hstp1Blk->respTid); - semDelete (hstp1Blk->scanSem); - lstFree (&hstp1Blk->scanLst); - semDelete (hstp1Blk->respSem); - lstFree (&hstp1Blk->respLst); - semDelete (hstp1Blk->listSem); - - free (hstp1Blk); - - Hstp1 = NULL; - } - - return (0); - } - - /* Make sure we're in the right state */ - if (hstp1Blk != NULL) - { - Hstp1Printf (FN, "hstp1Blk is unexpectedly non-NULL: %08x", hstp1Blk); - taskSuspend (0); - } - - /* Before any init_records are called, set up the one and only Hstp1Blk */ - hstp1Blk = calloc (1, sizeof (*hstp1Blk)); - - /* Save a pointer to the controller block in a static for others to use */ - Hstp1 = hstp1Blk; - - /* Initialize the controller linked list */ - lstInit (&hstp1Blk->scanLst); - - /* Create a semaphore to communicate with the HSTP1 scan task */ - if ((hstp1Blk->scanSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY)) == NULL) - { - Hstp1Printf (FN, "scanSem semBCreate failed"); - taskSuspend (0); - } - - /* Start HSTP1 scan task and make sure user is notified if it disappears */ - hstp1Blk->scanTid = taskSpawn (HSTP1_SCANNAME, HSTP1_SCANPRI, - VX_FP_TASK, HSTP1_SCANSTK, - (FUNCPTR) Hstp1ScanTask, (int) hstp1Blk, - 0, 0, 0, 0, 0, 0, 0, 0, 0); - - /* Create a counting semaphore to communicate with the response task */ - if ((hstp1Blk->respSem = semCCreate (SEM_Q_FIFO, 0)) == NULL) - { - Hstp1Printf (FN, "respSem semCCreate failed"); - taskSuspend (0); - } - taskwdInsert (hstp1Blk->scanTid, NULL, 0L); - - /* Create a mutual exclusion semaphore to block response list updates */ - if ((hstp1Blk->listSem = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE)) == NULL) - { - Hstp1Printf (FN, "listSem semMCreate failed"); - taskSuspend (0); - } - - /* Start the response task and make sure user is notified if it disappears */ - hstp1Blk->respTid = taskSpawn (HSTP1_RESPNAME, HSTP1_RESPPRI, - VX_FP_TASK, HSTP1_RESPSTK, - (FUNCPTR) Hstp1RespTask, (int) hstp1Blk, - 0, 0, 0, 0, 0, 0, 0, 0, 0); - taskwdInsert (hstp1Blk->respTid, NULL, 0L); - - return (0); -} - - - -static long initRecord (SmRecord *rec) -/* - Description - ----------- - This is the initialization routine called by the record support layer for - each stepper motor record found in the database. This function registers - the 1746-HSTP1 module addressed in the record with the Allen Bradley driver - support layer. If this succeeds, a device private block is allocated, an - allocation semaphore and a command message queue are created. - - Parameters - ---------- - rec - A pointer to the record - - Returns - ------- - 0 or S_db_badField -*/ -{ - Function ("initRecord") - - struct abio *abio; - Hstp1Pvt *hstp1; - abStatus status; - long stat = 0; - void *drvPvt; - - Dbg (Printf (FN, "called with rec = %08x", rec)); - - /* Pointer to the data addess structure */ - abio = &rec->out.value.abio; - - /* Register the card */ - status = (*pabDrv->registerCard) (abio->link, abio->adapter, abio->card, - typeBt, "AB 1746-HSTP1", - Hstp1Callback, &drvPvt); - switch (status) - { - case abSuccess: - { - char buf[HSTP1_K_BUFSIZE]; - - stat = S_db_badField; - recGblRecordError (stat, (void *) rec, - Hstp1Sprintf (buf, FN, "\tregisterCard: slot %hu already used", abio->card)); - } - break; - - case abNewCard: - { - Hstp1Blk *hstp1Blk = Hstp1; - - hstp1 = calloc (1, sizeof (*hstp1)); - hstp1->drvPvt = drvPvt; - hstp1->hstp1Blk = hstp1Blk; - hstp1->rec = rec; - (*pabDrv->setUserPvt) (drvPvt, (void *) hstp1); - rec->dpvt = hstp1; - - /* Create a mutex with which to allocate the HSTP1 controller */ - if ((hstp1->allocSem = semBCreate (SEM_Q_FIFO, SEM_FULL)) == NULL) - { - char buf[HSTP1_K_BUFSIZE]; - - stat = S_db_badField; - recGblRecordError (stat, (void *) rec, - Hstp1Sprintf (buf, FN, "\tallocSem semBCreate failed")); - break; - } - - /* Create a command message queue to communicate with the scan task */ - if ((hstp1->cmdQue = msgQCreate (HSTP1_K_CMDCNT, sizeof (Hstp1Msg), - MSG_Q_FIFO)) == NULL) - { - char buf[HSTP1_K_BUFSIZE]; - - stat = S_db_badField; - recGblRecordError (stat, (void *) rec, - Hstp1Sprintf (buf, FN, "\tcmdQue msgQCreate failed")); - break; - } - - /* Add the PV to the list of stepper motor PVs */ - lstAdd (&hstp1Blk->scanLst, &hstp1->scanLnks); - } - break; - - default: - { - char buf[HSTP1_K_BUFSIZE]; - - stat = S_db_badField; - recGblRecordError (stat, (void *) rec, - Hstp1Sprintf (buf, FN, "\tregisterCard error: %s", - abStatusMessage[status])); - } - break; - } - - return (stat); -} - - - -static long report (int level) -/* - Description - ----------- - This function is used to output the status of all the 1746-HSTP1s in the - system at the VxWorks prompt with the dbior command. - - Parameters - ---------- - level - level of detail the user is interested in seeing - - Returns - ------- - 0 (zero) -*/ -{ - Hstp1Blk *hstp1Blk = Hstp1; - register Hstp1Pvt *hstp1; - - - if (hstp1Blk == 0) - { - epicsPrintf ("AB-1746HSTP1 card(s) not initialized\n"); - return (0); - } - hstp1 = (Hstp1Pvt *) lstFirst (&hstp1Blk->scanLst); - - while (hstp1) - { - struct abio *abio = (struct abio *) &(hstp1->rec->out.value); - register char *active = hstp1->active ? "" : "not "; - - epicsPrintf ( -"\nAB SM: 1746-HSTP1: link/adapter/card = %u/%u/%u is %sactive\n", - abio->link, abio->adapter, abio->card, active); - if (level > 0) - { - register MotorData *md = &hstp1->motorData; - - epicsPrintf ("\tCW limit = %d\tCCW limit = %d\tMoving = %d\tConstant Velocity = %d" -"\n\tDirection = %d\tVelocity = %d p/sec\tAccel = %d p/sec/sec" -"\n\tEncoder Position = %d\tMotor Position = %d\n", - md->cw_limit, md->ccw_limit, md->moving, - md->constant_velocity, - md->direction, md->velocity, md->accel, - md->encoder_position, md->motor_position); - - } - if (level > 1) - { - register Hstp1CmdIn *in = &hstp1->cmd.in; - register Hstp1CmdOut *out = &hstp1->cmd.out; - - epicsPrintf ( -"\nHSTP1 %s registers:\tOutput\t\tInput" -"\n\tWord 0\t\t\t %h04x\t\t %h04x" -"\n\tWord 1\t\t\t\t\t %h04x" -"\n\tPosition\t\t %6d\t\t %6d" -"\n\tEncoder position\t\t\t %4d" -"\n\tVelocity\t\t %4u" -"\n\tAcceleration\t\t %4hd" -"\n\tDeceleration\t\t %4hd\n", - "Command", - out->cmd, in->status[0], - in->status[1], - Hstp1Eval (out->posn), Hstp1Eval (in->posn), - Hstp1Eval (in->encPosn), - Hstp1Eval (out->vel), - out->accel, - out->decel); - } - if (level > 2) - { - register Hstp1CfgIn *in = &hstp1->cfg.in; - register Hstp1CfgOut *out = &hstp1->cfg.out; - - epicsPrintf ( -"\nHSTP1 %s registers:\tOutput\t\tInput" -"\n\tWord 0\t\t\t %04x\t\t %04x" -"\n\tWord 1\t\t\t %04x\t\t %04x" -"\n\tStarting speed\t\t %4d\t\t %4d\n", - "Configuration", - out->cfg, in->cfg, - out->actLvl, in->actLvl, - Hstp1Eval (out->startSpd), Hstp1Eval (in->startSpd)); - } - - hstp1 = (Hstp1Pvt *) lstNext (&hstp1->scanLnks); - } - return (0); -} - - - -static long Hstp1Eval (MswLsw item) -{ - long temp = 1000 * (item.msw & 0x7fff) + item.lsw; - return (item.msw & 0x8000 ? -temp : temp); -} - - - -static char *Hstp1Sprintf (char *buf, const char *fn, char *fmt, ...) -{ - char fmtBuf[HSTP1_K_BUFSIZE]; - va_list var; - - /* Build a new format string in the provided buffer */ - sprintf (fmtBuf, "devSmAB1746Hstp1 (%s): %s\n", fn, fmt); - - va_start (var, fmt); - vsprintf (buf, fmtBuf, var); - return (buf); -} - - - -static int Hstp1Printf (const char *fn, char *fmt, ...) -{ - char fmtBuf[HSTP1_K_BUFSIZE]; - va_list var; - - - /* Build a new format string on the stack */ - sprintf (fmtBuf, "devSmAB1746Hstp1 (%s): %s\n", fn, fmt); - - va_start (var, fmt); - return (epicsVprintf (fmtBuf, var)); -} diff --git a/src/dev/dvxDev/Makefile b/src/dev/dvxDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/dvxDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/dvxDev/Makefile.Vx b/src/dev/dvxDev/Makefile.Vx new file mode 100644 index 000000000..c5000b3dd --- /dev/null +++ b/src/dev/dvxDev/Makefile.Vx @@ -0,0 +1,11 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devAiDvx2502.c +SRCS.c += ../devWfDvx2502.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAiDvx2502.c b/src/dev/dvxDev/devAiDvx2502.c similarity index 100% rename from src/dev/devAiDvx2502.c rename to src/dev/dvxDev/devAiDvx2502.c diff --git a/src/dev/devWfDvx2502.c b/src/dev/dvxDev/devWfDvx2502.c similarity index 100% rename from src/dev/devWfDvx2502.c rename to src/dev/dvxDev/devWfDvx2502.c diff --git a/src/dev/gpibDev/Makefile b/src/dev/gpibDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/gpibDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/gpibDev/Makefile.Vx b/src/dev/gpibDev/Makefile.Vx new file mode 100644 index 000000000..08f453452 --- /dev/null +++ b/src/dev/gpibDev/Makefile.Vx @@ -0,0 +1,12 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +INC += devCommonGpib.h + +SRCS.c += ../devCommonGpib.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devCommonGpib.c b/src/dev/gpibDev/devCommonGpib.c similarity index 99% rename from src/dev/devCommonGpib.c rename to src/dev/gpibDev/devCommonGpib.c index c3996f501..b47096cb2 100644 --- a/src/dev/devCommonGpib.c +++ b/src/dev/gpibDev/devCommonGpib.c @@ -3,6 +3,9 @@ /* * $Log$ + * Revision 1.36 1998/01/20 22:08:59 mrk + * cleanup includes + * * Revision 1.35 1997/06/30 12:53:06 mrk * GPIBEFASTO: Last fix was TOO strict * diff --git a/src/dev/devCommonGpib.h b/src/dev/gpibDev/devCommonGpib.h similarity index 100% rename from src/dev/devCommonGpib.h rename to src/dev/gpibDev/devCommonGpib.h diff --git a/src/dev/hpe1368Dev/Makefile b/src/dev/hpe1368Dev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/hpe1368Dev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/hpe1368Dev/Makefile.Vx b/src/dev/hpe1368Dev/Makefile.Vx new file mode 100644 index 000000000..b762103e9 --- /dev/null +++ b/src/dev/hpe1368Dev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devHpe1368a.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devHpe1368a.c b/src/dev/hpe1368Dev/devHpe1368a.c similarity index 100% rename from src/dev/devHpe1368a.c rename to src/dev/hpe1368Dev/devHpe1368a.c diff --git a/src/dev/joergerDev/Makefile b/src/dev/joergerDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/joergerDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/joergerDev/Makefile.Vx b/src/dev/joergerDev/Makefile.Vx new file mode 100644 index 000000000..d15aa7bfe --- /dev/null +++ b/src/dev/joergerDev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devWfJoergerVtr1.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devWfJoergerVtr1.c b/src/dev/joergerDev/devWfJoergerVtr1.c similarity index 100% rename from src/dev/devWfJoergerVtr1.c rename to src/dev/joergerDev/devWfJoergerVtr1.c diff --git a/src/dev/kscV215Dev/Makefile b/src/dev/kscV215Dev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/kscV215Dev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/kscV215Dev/Makefile.Vx b/src/dev/kscV215Dev/Makefile.Vx new file mode 100644 index 000000000..f4c72c990 --- /dev/null +++ b/src/dev/kscV215Dev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devAiKscV215.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAiKscV215.c b/src/dev/kscV215Dev/devAiKscV215.c similarity index 100% rename from src/dev/devAiKscV215.c rename to src/dev/kscV215Dev/devAiKscV215.c diff --git a/src/dev/mizarDev/Makefile b/src/dev/mizarDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/mizarDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/mizarDev/Makefile.Vx b/src/dev/mizarDev/Makefile.Vx new file mode 100644 index 000000000..667ecba40 --- /dev/null +++ b/src/dev/mizarDev/Makefile.Vx @@ -0,0 +1,11 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devMz8310.c +SRCS.c += ../devTimerMz8310.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devMz8310.c b/src/dev/mizarDev/devMz8310.c similarity index 100% rename from src/dev/devMz8310.c rename to src/dev/mizarDev/devMz8310.c diff --git a/src/dev/devTimerMz8310.c b/src/dev/mizarDev/devTimerMz8310.c similarity index 100% rename from src/dev/devTimerMz8310.c rename to src/dev/mizarDev/devTimerMz8310.c diff --git a/src/dev/mpvDev/Makefile b/src/dev/mpvDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/mpvDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/mpvDev/Makefile.Vx b/src/dev/mpvDev/Makefile.Vx new file mode 100644 index 000000000..b171d4c4f --- /dev/null +++ b/src/dev/mpvDev/Makefile.Vx @@ -0,0 +1,15 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devBiMpv910.c +SRCS.c += ../devBoMpv902.c +SRCS.c += ../devMbbiDirectMpv910.c +SRCS.c += ../devMbbiMpv910.c +SRCS.c += ../devMbboDirectMpv902.c +SRCS.c += ../devMbboMpv902.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devBiMpv910.c b/src/dev/mpvDev/devBiMpv910.c similarity index 100% rename from src/dev/devBiMpv910.c rename to src/dev/mpvDev/devBiMpv910.c diff --git a/src/dev/devBoMpv902.c b/src/dev/mpvDev/devBoMpv902.c similarity index 100% rename from src/dev/devBoMpv902.c rename to src/dev/mpvDev/devBoMpv902.c diff --git a/src/dev/devMbbiDirectMpv910.c b/src/dev/mpvDev/devMbbiDirectMpv910.c similarity index 100% rename from src/dev/devMbbiDirectMpv910.c rename to src/dev/mpvDev/devMbbiDirectMpv910.c diff --git a/src/dev/devMbbiMpv910.c b/src/dev/mpvDev/devMbbiMpv910.c similarity index 100% rename from src/dev/devMbbiMpv910.c rename to src/dev/mpvDev/devMbbiMpv910.c diff --git a/src/dev/devMbboDirectMpv902.c b/src/dev/mpvDev/devMbboDirectMpv902.c similarity index 100% rename from src/dev/devMbboDirectMpv902.c rename to src/dev/mpvDev/devMbboDirectMpv902.c diff --git a/src/dev/devMbboMpv902.c b/src/dev/mpvDev/devMbboMpv902.c similarity index 100% rename from src/dev/devMbboMpv902.c rename to src/dev/mpvDev/devMbboMpv902.c diff --git a/src/dev/omsDev/Makefile b/src/dev/omsDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/omsDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/omsDev/Makefile.Vx b/src/dev/omsDev/Makefile.Vx new file mode 100644 index 000000000..ec59a1ef5 --- /dev/null +++ b/src/dev/omsDev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devSmOms6Axis.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devSmOms6Axis.c b/src/dev/omsDev/devSmOms6Axis.c similarity index 100% rename from src/dev/devSmOms6Axis.c rename to src/dev/omsDev/devSmOms6Axis.c diff --git a/src/dev/pentekDev/Makefile b/src/dev/pentekDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/pentekDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/pentekDev/Makefile.Vx b/src/dev/pentekDev/Makefile.Vx new file mode 100644 index 000000000..09646c540 --- /dev/null +++ b/src/dev/pentekDev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devWfPentek4261.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devWfPentek4261.c b/src/dev/pentekDev/devWfPentek4261.c similarity index 100% rename from src/dev/devWfPentek4261.c rename to src/dev/pentekDev/devWfPentek4261.c diff --git a/src/dev/softDev/Makefile b/src/dev/softDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/softDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/softDev/Makefile.Vx b/src/dev/softDev/Makefile.Vx new file mode 100644 index 000000000..831f1b67b --- /dev/null +++ b/src/dev/softDev/Makefile.Vx @@ -0,0 +1,32 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devAiSoft.c +SRCS.c += ../devAiSoftRaw.c +SRCS.c += ../devAoSoft.c +SRCS.c += ../devAoSoftRaw.c +SRCS.c += ../devBiSoft.c +SRCS.c += ../devBiSoftRaw.c +SRCS.c += ../devBoSoft.c +SRCS.c += ../devBoSoftRaw.c +SRCS.c += ../devEventSoft.c +SRCS.c += ../devHistogramSoft.c +SRCS.c += ../devLiSoft.c +SRCS.c += ../devLoSoft.c +SRCS.c += ../devMbbiSoft.c +SRCS.c += ../devMbbiSoftRaw.c +SRCS.c += ../devMbboDirectSoft.c +SRCS.c += ../devMbboDirectSoftRaw.c +SRCS.c += ../devMbboSoft.c +SRCS.c += ../devMbboSoftRaw.c +SRCS.c += ../devPtSoft.c +SRCS.c += ../devSASoft.c +SRCS.c += ../devSiSoft.c +SRCS.c += ../devSoSoft.c +SRCS.c += ../devWfSoft.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAiSoft.c b/src/dev/softDev/devAiSoft.c similarity index 100% rename from src/dev/devAiSoft.c rename to src/dev/softDev/devAiSoft.c diff --git a/src/dev/devAiSoftRaw.c b/src/dev/softDev/devAiSoftRaw.c similarity index 100% rename from src/dev/devAiSoftRaw.c rename to src/dev/softDev/devAiSoftRaw.c diff --git a/src/dev/devAoSoft.c b/src/dev/softDev/devAoSoft.c similarity index 100% rename from src/dev/devAoSoft.c rename to src/dev/softDev/devAoSoft.c diff --git a/src/dev/devAoSoftRaw.c b/src/dev/softDev/devAoSoftRaw.c similarity index 100% rename from src/dev/devAoSoftRaw.c rename to src/dev/softDev/devAoSoftRaw.c diff --git a/src/dev/devBiSoft.c b/src/dev/softDev/devBiSoft.c similarity index 100% rename from src/dev/devBiSoft.c rename to src/dev/softDev/devBiSoft.c diff --git a/src/dev/devBiSoftRaw.c b/src/dev/softDev/devBiSoftRaw.c similarity index 100% rename from src/dev/devBiSoftRaw.c rename to src/dev/softDev/devBiSoftRaw.c diff --git a/src/dev/devBoSoft.c b/src/dev/softDev/devBoSoft.c similarity index 100% rename from src/dev/devBoSoft.c rename to src/dev/softDev/devBoSoft.c diff --git a/src/dev/devBoSoftRaw.c b/src/dev/softDev/devBoSoftRaw.c similarity index 100% rename from src/dev/devBoSoftRaw.c rename to src/dev/softDev/devBoSoftRaw.c diff --git a/src/dev/devEventSoft.c b/src/dev/softDev/devEventSoft.c similarity index 100% rename from src/dev/devEventSoft.c rename to src/dev/softDev/devEventSoft.c diff --git a/src/dev/devHistogramSoft.c b/src/dev/softDev/devHistogramSoft.c similarity index 100% rename from src/dev/devHistogramSoft.c rename to src/dev/softDev/devHistogramSoft.c diff --git a/src/dev/devLiSoft.c b/src/dev/softDev/devLiSoft.c similarity index 100% rename from src/dev/devLiSoft.c rename to src/dev/softDev/devLiSoft.c diff --git a/src/dev/devLoSoft.c b/src/dev/softDev/devLoSoft.c similarity index 100% rename from src/dev/devLoSoft.c rename to src/dev/softDev/devLoSoft.c diff --git a/src/dev/devMbbiDirectSoft.c b/src/dev/softDev/devMbbiDirectSoft.c similarity index 100% rename from src/dev/devMbbiDirectSoft.c rename to src/dev/softDev/devMbbiDirectSoft.c diff --git a/src/dev/devMbbiDirectSoftRaw.c b/src/dev/softDev/devMbbiDirectSoftRaw.c similarity index 100% rename from src/dev/devMbbiDirectSoftRaw.c rename to src/dev/softDev/devMbbiDirectSoftRaw.c diff --git a/src/dev/devMbbiSoft.c b/src/dev/softDev/devMbbiSoft.c similarity index 100% rename from src/dev/devMbbiSoft.c rename to src/dev/softDev/devMbbiSoft.c diff --git a/src/dev/devMbbiSoftRaw.c b/src/dev/softDev/devMbbiSoftRaw.c similarity index 100% rename from src/dev/devMbbiSoftRaw.c rename to src/dev/softDev/devMbbiSoftRaw.c diff --git a/src/dev/devMbboDirectSoft.c b/src/dev/softDev/devMbboDirectSoft.c similarity index 100% rename from src/dev/devMbboDirectSoft.c rename to src/dev/softDev/devMbboDirectSoft.c diff --git a/src/dev/devMbboDirectSoftRaw.c b/src/dev/softDev/devMbboDirectSoftRaw.c similarity index 100% rename from src/dev/devMbboDirectSoftRaw.c rename to src/dev/softDev/devMbboDirectSoftRaw.c diff --git a/src/dev/devMbboSoft.c b/src/dev/softDev/devMbboSoft.c similarity index 100% rename from src/dev/devMbboSoft.c rename to src/dev/softDev/devMbboSoft.c diff --git a/src/dev/devMbboSoftRaw.c b/src/dev/softDev/devMbboSoftRaw.c similarity index 100% rename from src/dev/devMbboSoftRaw.c rename to src/dev/softDev/devMbboSoftRaw.c diff --git a/src/dev/devPtSoft.c b/src/dev/softDev/devPtSoft.c similarity index 100% rename from src/dev/devPtSoft.c rename to src/dev/softDev/devPtSoft.c diff --git a/src/dev/devSASoft.c b/src/dev/softDev/devSASoft.c similarity index 100% rename from src/dev/devSASoft.c rename to src/dev/softDev/devSASoft.c diff --git a/src/dev/devSiSoft.c b/src/dev/softDev/devSiSoft.c similarity index 100% rename from src/dev/devSiSoft.c rename to src/dev/softDev/devSiSoft.c diff --git a/src/dev/devSoSoft.c b/src/dev/softDev/devSoSoft.c similarity index 100% rename from src/dev/devSoSoft.c rename to src/dev/softDev/devSoSoft.c diff --git a/src/dev/devWfSoft.c b/src/dev/softDev/devWfSoft.c similarity index 100% rename from src/dev/devWfSoft.c rename to src/dev/softDev/devWfSoft.c diff --git a/src/dev/symbDev/Makefile b/src/dev/symbDev/Makefile new file mode 100644 index 000000000..36018e19c --- /dev/null +++ b/src/dev/symbDev/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/config/CONFIG_BASE +include $(TOP)/config/RULES_ARCHS diff --git a/src/dev/symbDev/Makefile.Vx b/src/dev/symbDev/Makefile.Vx new file mode 100644 index 000000000..14931c192 --- /dev/null +++ b/src/dev/symbDev/Makefile.Vx @@ -0,0 +1,26 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +DBDINSTALL = symb.dbd + +SRCS.c += ../devAiSymb.c +SRCS.c += ../devAoSymb.c +SRCS.c += ../devBiSymb.c +SRCS.c += ../devBoSymb.c +SRCS.c += ../devLiSymb.c +SRCS.c += ../devLoSymb.c +SRCS.c += ../devMbbiSymb.c +SRCS.c += ../devMbbiSymbRaw.c +SRCS.c += ../devMbboSymb.c +SRCS.c += ../devMbboSymbRaw.c +SRCS.c += ../devSiSymb.c +SRCS.c += ../devSoSymb.c +SRCS.c += ../devSymbFind.c +SRCS.c += ../devWfSymb.c + +PROD = $(SRCS.c:../%.c=%.o) +LIBOBJS = $(SRCS.c:../%.c=%.o) +LIBNAME = symb + + +include $(TOP)/config/RULES.Vx diff --git a/src/dev/symbDev/README b/src/dev/symbDev/README new file mode 100644 index 000000000..d7e988555 --- /dev/null +++ b/src/dev/symbDev/README @@ -0,0 +1,43 @@ +README file for dev/symb directory +---------------------------------- + +This directory contains all files necessary to build and test a version +of EPICS vxWorks global variable device support which uses the INST_IO +string as the variable name specification rather than deriving the name +from the record name. + +In addition to specifying a variable name, a leading "*" operator indicates +that the variable is a pointer and a trailing "[nnnn]" indicates that an +element of an array should be accessed. + +Refer to the header comments of devSymbFind.c for full details. + +The following files are in the release: + +README This file + +Makefile UAE Makefile +Makefile.Vx UAE vxWorks Makefile + +devAiSymb.c Modified versions of standard EPICS +devAoSymb.c vxWorks global variable device support +devLiSymb.c +devLoSymb.c +devSiSymb.c +devSoSymb.c + +devSymbFind.c New module containing parsing code + (includes conditionally compiled test routine) + +devSymbTest.c Defines globals and a routine for test + +devSup.ascii New INST_IO entries for the above six records + +symb.sr Test database (works with devSymbTest.c) +symbStartup.vws Test vxWorks startup script + + +08-Jun-96, William Lupton (wlupton@keck.hawaii.edu), CVS tag: symb-1-0 +---------------------------------------------------------------------- + +first release diff --git a/src/dev/devAiSymb.c b/src/dev/symbDev/devAiSymb.c similarity index 69% rename from src/dev/devAiSymb.c rename to src/dev/symbDev/devAiSymb.c index 4766b5c81..7a53f3aed 100644 --- a/src/dev/devAiSymb.c +++ b/src/dev/symbDev/devAiSymb.c @@ -36,13 +36,16 @@ * Derived from soft record device support. * Modification Log: * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. */ #include #include -#include -#include +#include +#include #include #include @@ -53,6 +56,7 @@ #include #include #include +#include /* Create the dset for devAiSymb */ static long init_record(); @@ -76,34 +80,14 @@ struct { double testd = 5.5; - static long init_record(pai) -/* - Looks for record name in global symbol table. Strips off any - prefix separated by a ":" before the lookup, to allow same variable - name in multiple ioc's. Strips off suffixes separated by ";", to - allow multiple references to same variable in an ioc. -*/ struct aiRecord *pai; { - char *nptr, pname[29]; - SYM_TYPE stype; - - /* variable names from c have a prepended underscore */ - strcpy(pname,"_"); /* in case it is unprefixed */ - strcat(pname, pai->name); - nptr = strrchr(pname, ';'); /* find any suffix and */ - if (nptr) - *nptr = '\0'; /* terminate it. */ - nptr = strchr(pname, ':'); /* find any prefix and */ - if (nptr) /* bypass it */ - *nptr = '_'; /* overwrite : with _ */ - else - nptr = pname; - if (symFindByName(sysSymTbl, nptr, (char **)&pai->dpvt, &stype)) + /* determine address of record value */ + if (devSymbFind(pai->name, &pai->inp, &pai->dpvt)) { recGblRecordError(S_db_badField,(void *)pai, - "devAiSymb (init_record) Illegal NAME field"); + "devAiSymb (init_record) Illegal NAME or INP field"); return(S_db_badField); } @@ -115,10 +99,11 @@ static long read_ai(pai) struct aiRecord *pai; { long status; + struct vxSym *private = (struct vxSym *) pai->dpvt; - if (pai->dpvt) + if (private) { - pai->val = *(double *)(pai->dpvt); + pai->val = *((double *)(*private->ppvar) + private->index); status = 0; } else diff --git a/src/dev/devAoSymb.c b/src/dev/symbDev/devAoSymb.c similarity index 66% rename from src/dev/devAoSymb.c rename to src/dev/symbDev/devAoSymb.c index 9e013f089..6b598081f 100644 --- a/src/dev/devAoSymb.c +++ b/src/dev/symbDev/devAoSymb.c @@ -36,12 +36,15 @@ * Derived from soft record device support. * Modification Log: * ----------------- + * wfl 06-jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. */ #include #include -#include -#include +#include +#include #include #include @@ -52,6 +55,7 @@ #include #include #include +#include /* Create the dset for devAoSymb */ @@ -75,35 +79,15 @@ struct { NULL}; - static long init_record(pao) -/* - Looks for record name in global symbol table. strips off any - prefix separated by a ":" before the lookup, to allow same variable - name in multiple ioc's. Strips off suffixes separated by ";", to - allow multiple references to same variable in an ioc. -*/ struct aoRecord *pao; { - char *nptr, pname[29]; - SYM_TYPE stype; - - /* variable names from c have a prepended underscore */ - strcpy(pname,"_"); /* in case it is unprefixed */ - strcat(pname, pao->name); - nptr = strrchr(pname, ';'); /* find any suffix and */ - if (nptr) - *nptr = '\0'; /* terminate it. */ - nptr = strchr(pname, ':'); /* strip off prefix, if any */ - if (nptr) - *nptr = '_'; /* overwrite : with _ */ - else - nptr = pname; - if (symFindByName(sysSymTbl, nptr, (char **)&pao->dpvt, &stype)) + /* determine address of record value */ + if (devSymbFind(pao->name, &pao->out, &pao->dpvt)) { - recGblRecordError(S_db_badField,(void *)pao, - "devAoSymb (init_record) Illegal NAME field"); - return(S_db_badField); + recGblRecordError(S_db_badField,(void *)pao, + "devAoSymb (init_record) Illegal NAME or OUT field"); + return(S_db_badField); } return(2); /* don't convert */ @@ -112,8 +96,10 @@ static long init_record(pao) static long write_ao(pao) struct aoRecord *pao; { - if (pao->dpvt) - *(double *)(pao->dpvt) = pao->val; + struct vxSym *private = (struct vxSym *) pao->dpvt; + + if (private) + *((double *)(*private->ppvar) + private->index) = pao->val; else return(1); diff --git a/src/dev/symbDev/devBiSymb.c b/src/dev/symbDev/devBiSymb.c new file mode 100644 index 000000000..17f622895 --- /dev/null +++ b/src/dev/symbDev/devBiSymb.c @@ -0,0 +1,112 @@ +/* base/src/dev $Id$ */ + +/* @(#)devBiSymb.c 1.1 6/4/93 + * Device Support for VxWorks Global Symbol Binary Input Records + * + * + * Author: Carl Lionberger + * Date: 060893 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * The Control Systems Group + * Systems Engineering Department + * Lawrence Berkeley Laboratory + * + * NOTES: + * Derived from soft record device support. + * Modification Log: + * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. + * wfl 12-Dec-96 created from longin support + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Create the dset for devBiSymb */ +static long init_record(); +static long read_bi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_bi; +}devBiSymb={ + 5, + NULL, + NULL, + init_record, + NULL, + read_bi}; + +long testb = 1; + +static long init_record(pbi) + struct biRecord *pbi; +{ + /* determine address of record value */ + if (devSymbFind(pbi->name, &pbi->inp, &pbi->dpvt)) + { + recGblRecordError(S_db_badField,(void *)pbi, + "devBiSymb (init_record) Illegal NAME or INP field"); + return(S_db_badField); + } + + return(0); +} + +static long read_bi(pbi) + struct biRecord *pbi; +{ + long status; + struct vxSym *private = (struct vxSym *) pbi->dpvt; + + if (pbi->dpvt) + { + pbi->val = *((unsigned short *)(*private->ppvar) + private->index); + status = 0; + } + else + status = 1; + + if(RTN_SUCCESS(status)) pbi->udf=FALSE; + + return(2); /*don't convert*/ +} diff --git a/src/dev/symbDev/devBoSymb.c b/src/dev/symbDev/devBoSymb.c new file mode 100644 index 000000000..0909e7ad3 --- /dev/null +++ b/src/dev/symbDev/devBoSymb.c @@ -0,0 +1,109 @@ +/* base/src/dev $Id$ */ + +/* @(#)devBoSymb.c 1.1 6/4/93 + * Device Support for VxWorks Global Symbol Binary Output Records + * + * + * Author: Carl Lionberger + * Date: 060893 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * The Control Systems Group + * Systems Engineering Department + * Lawrence Berkeley Laboratory + * + * NOTES: + * Derived from soft record device support. + * Modification Log: + * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. + * wfl 12-Dec-96 created from longout support + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static long init_record(); +static long write_bo(); + +/* Create the dset for devBoSymb */ + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_bo; +}devBoSymb={ + 5, + NULL, + NULL, + init_record, + NULL, + write_bo}; + + +static long init_record(pbo) + struct boRecord *pbo; +{ + /* determine address of record value */ + if (devSymbFind(pbo->name, &pbo->out, &pbo->dpvt)) + { + recGblRecordError(S_db_badField,(void *)pbo, + "devBoSymb (init_record) Illegal NAME or OUT field"); + return(S_db_badField); + } + + return(0); +} + +static long write_bo(pbo) + struct boRecord *pbo; +{ + struct vxSym *private = (struct vxSym *) pbo->dpvt; + + if (private) + *((unsigned short *)(*private->ppvar) + private->index) = pbo->val; + else + return(1); + + pbo->udf=FALSE; + + return(0); +} diff --git a/src/dev/devLiSymb.c b/src/dev/symbDev/devLiSymb.c similarity index 67% rename from src/dev/devLiSymb.c rename to src/dev/symbDev/devLiSymb.c index d8330b8df..adff71fc9 100644 --- a/src/dev/devLiSymb.c +++ b/src/dev/symbDev/devLiSymb.c @@ -36,12 +36,15 @@ * Derived from soft record device support. * Modification Log: * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. */ #include #include -#include -#include +#include +#include #include #include @@ -51,6 +54,7 @@ #include #include #include +#include /* Create the dset for devLiSymb */ static long init_record(); @@ -73,35 +77,15 @@ struct { long testl = 5463; - static long init_record(plongin) -/* - Looks for record name in global symbol table. strips off any - prefix separated by a ":" before the lookup, to allow same variable - name in multiple ioc's. Strips off suffixes separated by ";", to - allow multiple references to same variable in an ioc. -*/ struct longinRecord *plongin; { - char *nptr, pname[29]; - SYM_TYPE stype; - - /* variable names from c have a prepended underscore */ - strcpy(pname,"_"); /* in case it is unprefixed */ - strcat(pname, plongin->name); - nptr = strrchr(pname, ';'); /* find any suffix and */ - if (nptr) - *nptr = '\0'; /* terminate it. */ - nptr = strchr(pname, ':'); /* strip off prefix, if any */ - if (nptr) - *nptr = '_'; /* overwrite : with _ */ - else - nptr = pname; - if (symFindByName(sysSymTbl, nptr, (char **)&plongin->dpvt, &stype)) + /* determine address of record value */ + if (devSymbFind(plongin->name, &plongin->inp, &plongin->dpvt)) { - recGblRecordError(S_db_badField,(void *)plongin, - "devLiSymb (init_record) Illegal NAME field"); - return(S_db_badField); + recGblRecordError(S_db_badField,(void *)plongin, + "devLiSymb (init_record) Illegal NAME or INP field"); + return(S_db_badField); } return(0); @@ -111,10 +95,11 @@ static long read_longin(plongin) struct longinRecord *plongin; { long status; + struct vxSym *private = (struct vxSym *) plongin->dpvt; if (plongin->dpvt) { - plongin->val = *(long *)(plongin->dpvt); + plongin->val = *((long *)(*private->ppvar) + private->index); status = 0; } else diff --git a/src/dev/devLoSymb.c b/src/dev/symbDev/devLoSymb.c similarity index 65% rename from src/dev/devLoSymb.c rename to src/dev/symbDev/devLoSymb.c index 1606b26f7..99c080cec 100644 --- a/src/dev/devLoSymb.c +++ b/src/dev/symbDev/devLoSymb.c @@ -36,13 +36,16 @@ * Derived from soft record device support. * Modification Log: * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. */ #include #include -#include -#include +#include +#include #include #include @@ -52,6 +55,7 @@ #include #include #include +#include static long init_record(); static long write_longout(); @@ -75,33 +79,14 @@ struct { static long init_record(plongout) -/* - Looks for record name in global symbol table. strips off any - prefix separated by a ":" before the lookup, to allow same variable - name in multiple ioc's. Strips off suffixes separated by ";", to - allow multiple references to same variable in an ioc. -*/ struct longoutRecord *plongout; { - char *nptr, pname[29]; - SYM_TYPE stype; - - /* variable names from c have a prepended underscore */ - strcpy(pname,"_"); /* in case it is unprefixed */ - strcat(pname, plongout->name); - nptr = strrchr(pname, ';'); /* find any suffix and */ - if (nptr) - *nptr = '\0'; /* terminate it. */ - nptr = strchr(pname, ':'); /* strip off prefix, if any */ - if (nptr) - *nptr = '_'; /* overwrite : with _ */ - else - nptr = pname; - if (symFindByName(sysSymTbl, nptr, (char **)&plongout->dpvt, &stype)) + /* determine address of record value */ + if (devSymbFind(plongout->name, &plongout->out, &plongout->dpvt)) { - recGblRecordError(S_db_badField,(void *)plongout, - "devLoSymb (init_record) Illegal NAME field"); - return(S_db_badField); + recGblRecordError(S_db_badField,(void *)plongout, + "devLoSymb (init_record) Illegal NAME or OUT field"); + return(S_db_badField); } return(0); @@ -110,10 +95,14 @@ static long init_record(plongout) static long write_longout(plongout) struct longoutRecord *plongout; { - if (plongout->dpvt) - *(long *)(plongout->dpvt) = plongout->val; + struct vxSym *private = (struct vxSym *) plongout->dpvt; + + if (private) + *((long *)(*private->ppvar) + private->index) = plongout->val; else return(1); + plongout->udf=FALSE; + return(0); } diff --git a/src/dev/symbDev/devMbbiSymb.c b/src/dev/symbDev/devMbbiSymb.c new file mode 100644 index 000000000..0e65392c9 --- /dev/null +++ b/src/dev/symbDev/devMbbiSymb.c @@ -0,0 +1,112 @@ +/* base/src/dev $Id$ */ + +/* @(#)devBiSymb.c 1.1 6/4/93 + * Device Support for VxWorks Global Symbol Multi-bit Binary Input Records + * + * + * Author: Carl Lionberger + * Date: 060893 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * The Control Systems Group + * Systems Engineering Department + * Lawrence Berkeley Laboratory + * + * NOTES: + * Derived from soft record device support. + * Modification Log: + * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. + * wfl 13-Dec-96 created from bi support + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Create the dset for devMbbiSymb */ +static long init_record(); +static long read_mbbi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_mbbi; +}devMbbiSymb={ + 5, + NULL, + NULL, + init_record, + NULL, + read_mbbi}; + +long testmb = 1; + +static long init_record(pmbbi) + struct mbbiRecord *pmbbi; +{ + /* determine address of record value */ + if (devSymbFind(pmbbi->name, &pmbbi->inp, &pmbbi->dpvt)) + { + recGblRecordError(S_db_badField,(void *)pmbbi, + "devMbbiSymb (init_record) Illegal NAME or INP field"); + return(S_db_badField); + } + + return(0); +} + +static long read_mbbi(pmbbi) + struct mbbiRecord *pmbbi; +{ + long status; + struct vxSym *private = (struct vxSym *) pmbbi->dpvt; + + if (pmbbi->dpvt) + { + pmbbi->val = *((long *)(*private->ppvar) + private->index); + status = 0; + } + else + status = 1; + + if(RTN_SUCCESS(status)) pmbbi->udf=FALSE; + + return(2); /*don't convert*/ +} diff --git a/src/dev/symbDev/devMbbiSymbRaw.c b/src/dev/symbDev/devMbbiSymbRaw.c new file mode 100644 index 000000000..e3ff4e76e --- /dev/null +++ b/src/dev/symbDev/devMbbiSymbRaw.c @@ -0,0 +1,110 @@ +/* base/src/dev $Id$ */ + +/* @(#)devMbbiSymbRaw.c 1.1 6/4/93 + * Device Support for VxWorks Global Symbol Multi-bit Binary Input Raw Records + * + * + * Author: Carl Lionberger + * Date: 060893 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * The Control Systems Group + * Systems Engineering Department + * Lawrence Berkeley Laboratory + * + * NOTES: + * Derived from soft record device support. + * Modification Log: + * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. + * wfl 13-Dec-96 created from bi support + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Create the dset for devMbbiSymbRaw */ +static long init_record(); +static long read_mbbi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_mbbi; +}devMbbiSymbRaw={ + 5, + NULL, + NULL, + init_record, + NULL, + read_mbbi}; + +long testmbr = 1; + +static long init_record(pmbbi) + struct mbbiRecord *pmbbi; +{ + /* determine address of record value */ + if (devSymbFind(pmbbi->name, &pmbbi->inp, &pmbbi->dpvt)) + { + recGblRecordError(S_db_badField,(void *)pmbbi, + "devMbbiSymbRaw (init_record) Illegal NAME or INP field"); + return(S_db_badField); + } + + return(0); +} + +static long read_mbbi(pmbbi) + struct mbbiRecord *pmbbi; +{ + long status; + struct vxSym *private = (struct vxSym *) pmbbi->dpvt; + + if (pmbbi->dpvt) + { + pmbbi->rval = *((long *)(*private->ppvar) + private->index); + status = 0; + } + else + status = 1; + + return(0); +} diff --git a/src/dev/symbDev/devMbboSymb.c b/src/dev/symbDev/devMbboSymb.c new file mode 100644 index 000000000..4eec9b2e8 --- /dev/null +++ b/src/dev/symbDev/devMbboSymb.c @@ -0,0 +1,109 @@ +/* base/src/dev $Id$ */ + +/* @(#)devMbboSymb.c 1.1 6/4/93 + * Device Support for VxWorks Global Symbol Multi-bit Binary Output Records + * + * + * Author: Carl Lionberger + * Date: 060893 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * The Control Systems Group + * Systems Engineering Department + * Lawrence Berkeley Laboratory + * + * NOTES: + * Derived from soft record device support. + * Modification Log: + * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. + * wfl 13-Dec-96 created from bo support + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static long init_record(); +static long write_mbbo(); + +/* Create the dset for devMbboSymb */ + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_mbbo; +}devMbboSymb={ + 5, + NULL, + NULL, + init_record, + NULL, + write_mbbo}; + + +static long init_record(pmbbo) + struct mbboRecord *pmbbo; +{ + /* determine address of record value */ + if (devSymbFind(pmbbo->name, &pmbbo->out, &pmbbo->dpvt)) + { + recGblRecordError(S_db_badField,(void *)pmbbo, + "devMbboSymb (init_record) Illegal NAME or OUT field"); + return(S_db_badField); + } + + return(0); +} + +static long write_mbbo(pmbbo) + struct mbboRecord *pmbbo; +{ + struct vxSym *private = (struct vxSym *) pmbbo->dpvt; + + if (private) + *((long *)(*private->ppvar) + private->index) = pmbbo->val; + else + return(1); + + pmbbo->udf=FALSE; + + return(0); +} diff --git a/src/dev/symbDev/devMbboSymbRaw.c b/src/dev/symbDev/devMbboSymbRaw.c new file mode 100644 index 000000000..ba0f85485 --- /dev/null +++ b/src/dev/symbDev/devMbboSymbRaw.c @@ -0,0 +1,109 @@ +/* base/src/dev $Id$ */ + +/* @(#)devMbboSymbRaw.c 1.1 6/4/93 + * Device Support for VxWorks Global Symbol Raw Multi-bit Binary Output Records + * + * + * Author: Carl Lionberger + * Date: 060893 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * The Control Systems Group + * Systems Engineering Department + * Lawrence Berkeley Laboratory + * + * NOTES: + * Derived from soft record device support. + * Modification Log: + * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. + * wfl 13-Dec-96 created from bo support + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static long init_record(); +static long write_mbbo(); + +/* Create the dset for devMbboSymbRaw */ + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_mbbo; +}devMbboSymbRaw={ + 5, + NULL, + NULL, + init_record, + NULL, + write_mbbo}; + + +static long init_record(pmbbo) + struct mbboRecord *pmbbo; +{ + /* determine address of record value */ + if (devSymbFind(pmbbo->name, &pmbbo->out, &pmbbo->dpvt)) + { + recGblRecordError(S_db_badField,(void *)pmbbo, + "devMbboSymbRaw (init_record) Illegal NAME or OUT field"); + return(S_db_badField); + } + + return(0); +} + +static long write_mbbo(pmbbo) + struct mbboRecord *pmbbo; +{ + struct vxSym *private = (struct vxSym *) pmbbo->dpvt; + + if (private) + *((long *)(*private->ppvar) + private->index) = pmbbo->rval; + else + return(1); + + pmbbo->udf=FALSE; + + return(0); +} diff --git a/src/dev/devSiSymb.c b/src/dev/symbDev/devSiSymb.c similarity index 67% rename from src/dev/devSiSymb.c rename to src/dev/symbDev/devSiSymb.c index 015331bcd..dcb31c584 100644 --- a/src/dev/devSiSymb.c +++ b/src/dev/symbDev/devSiSymb.c @@ -36,14 +36,17 @@ * Derived from soft record device support. * Modification Log: * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. */ #include -#include -#include -#include #include +#include +#include +#include #include #include @@ -52,6 +55,7 @@ #include #include #include +#include /* Create the dset for devSiSymb */ static long init_record(); @@ -75,33 +79,14 @@ struct { char tests[] = {"01234567891123456789212345678931234567894123456789"}; static long init_record(pstringin) -/* - Looks for record name in global symbol table. strips off any - prefix separated by a ":" before the lookup, to allow same variable - name in multiple ioc's. Strips off suffixes separated by ";", to - allow multiple references to same variable in an ioc. -*/ struct stringinRecord *pstringin; { - char *nptr, pname[29]; - SYM_TYPE stype; - - /* variable names from c have a prepended underscore */ - strcpy(pname,"_"); /* in case it is unprefixed */ - strcat(pname, pstringin->name); - nptr = strrchr(pname, ';'); /* find any suffix and */ - if (nptr) - *nptr = '\0'; /* terminate it. */ - nptr = strchr(pname, ':'); /* strip off prefix, if any */ - if (nptr) - *nptr = '_'; /* overwrite : with _ */ - else - nptr = pname; - if (symFindByName(sysSymTbl, nptr, (char **)&pstringin->dpvt, &stype)) + /* determine address of record value */ + if (devSymbFind(pstringin->name, &pstringin->inp, &pstringin->dpvt)) { - recGblRecordError(S_db_badField,(void *)pstringin, - "devSiSymb (init_record) Illegal NAME field"); - return(S_db_badField); + recGblRecordError(S_db_badField,(void *)pstringin, + "devSiSymb (init_record) Illegal NAME or INP field"); + return(S_db_badField); } return(0); @@ -111,11 +96,12 @@ static long read_stringin(pstringin) struct stringinRecord *pstringin; { long status; + struct vxSym *private = (struct vxSym *) pstringin->dpvt; - if (pstringin->dpvt) + if (private) { pstringin->val[39] = '\0'; - strncpy(pstringin->val,(char *)pstringin->dpvt,39); + strncpy(pstringin->val, (char *)(*private->ppvar) + private->index, 39); status = 0; } else diff --git a/src/dev/devSoSymb.c b/src/dev/symbDev/devSoSymb.c similarity index 66% rename from src/dev/devSoSymb.c rename to src/dev/symbDev/devSoSymb.c index d72a04e71..38a6012cd 100644 --- a/src/dev/devSoSymb.c +++ b/src/dev/symbDev/devSoSymb.c @@ -36,14 +36,17 @@ * Derived from soft record device support. * Modification Log: * ----------------- + * wfl 06-Jun-96 call devSymbFind() to parse PARM field and + * look up symbol + * anj 14-Oct-96 Changed devSymbFind() parameters. */ #include -#include -#include -#include #include +#include +#include +#include #include #include @@ -52,6 +55,7 @@ #include #include #include +#include static long init_record(); static long write_stringout(); @@ -75,33 +79,14 @@ struct { static long init_record(pstringout) -/* - Looks for record name in global symbol table. strips off any - prefix separated by a ":" before the lookup, to allow same variable - name in multiple ioc's. Strips off suffixes separated by ";", to - allow multiple references to same variable in an ioc. -*/ struct stringoutRecord *pstringout; { - char *nptr, pname[29]; - SYM_TYPE stype; - - /* variable names from c have a prepended underscore */ - strcpy(pname,"_"); /* in case it is unprefixed */ - strcat(pname, pstringout->name); - nptr = strrchr(pname, ';'); /* find any suffix and */ - if (nptr) - *nptr = '\0'; /* terminate it. */ - nptr = strchr(pname, ':'); /* strip off prefix, if any */ - if (nptr) - *nptr = '_'; /* overwrite : with _ */ - else - nptr = pname; - if (symFindByName(sysSymTbl, nptr, (char **)&pstringout->dpvt, &stype)) + /* determine address of record value */ + if (devSymbFind(pstringout->name, &pstringout->out, &pstringout->dpvt)) { - recGblRecordError(S_db_badField,(void *)pstringout, - "devSoSymb (init_record) Illegal NAME field"); - return(S_db_badField); + recGblRecordError(S_db_badField,(void *)pstringout, + "devSoSymb (init_record) Illegal NAME or OUT field"); + return(S_db_badField); } return(0); @@ -110,13 +95,17 @@ static long init_record(pstringout) static long write_stringout(pstringout) struct stringoutRecord *pstringout; { - if (pstringout->dpvt) + struct vxSym *private = (struct vxSym *) pstringout->dpvt; + + if (private) { pstringout->val[39] = '\0'; - strcpy((char *)pstringout->dpvt,pstringout->val); + strcpy((char *)(*private->ppvar) + private->index, pstringout->val); } else return(1); + pstringout->udf = FALSE; + return(0); } diff --git a/src/dev/symbDev/devSymb.h b/src/dev/symbDev/devSymb.h new file mode 100644 index 000000000..e3fbd21a6 --- /dev/null +++ b/src/dev/symbDev/devSymb.h @@ -0,0 +1,31 @@ +/* devSymb.h - Header for vxWorks global var device support routines */ + +/* $Id$ + * + * Author: Andrew Johnson (RGO) + * Date: 11 October 1996 + */ + +/* Modification History: + * $Log$ + * Revision 1.1 1996/10/24 18:29:20 wlupton + * Andrew Johnson's changes (upwards-compatible) + * + * Revision 1.1 1996/10/22 15:30:24 anj + * vxWorks Variable support changed to do pointer indirection at + * run-time. Also added device support for the Waveform record. + * + */ + +/* This is the device private structure */ + +struct vxSym { + void **ppvar; + void *pvar; + long index; +}; + + +/* This is the call to create it */ + +extern int devSymbFind(char *name, struct link *plink, void *pdpvt); diff --git a/src/dev/symbDev/devSymbFind.c b/src/dev/symbDev/devSymbFind.c new file mode 100644 index 000000000..67614258e --- /dev/null +++ b/src/dev/symbDev/devSymbFind.c @@ -0,0 +1,305 @@ +/* devSymbFind.c - Support routines for vxWorks global var device support */ + +/* $Id$ + * + * Author: William Lupton (Keck) + * Date: 7 June 1996 + */ + +/* modification history: + * $Log$ + * Revision 1.2.2.1 1997/10/11 02:26:54 wlupton + * now working with R3.13 + * + * Revision 1.2 1996/10/24 18:29:20 wlupton + * Andrew Johnson's changes (upwards-compatible) + * + * Revision 1.2 1996/10/22 15:30:25 anj + * vxWorks Variable support changed to do pointer indirection at + * run-time. Also added device support for the Waveform record. + * + * Revision 1.1 1996/09/17 09:55:37 anj + * Added William Lupton's vxWorks global variable device support, and + * some slight adjustment to the ANB display screens. + * + * Revision 1.1 1996/06/09 00:52:24 wlupton + * initial insertion + * + */ + +/* +DESCRIPTION: + +This module contains routines for converting a vxWorks global variable +name specification into its address. Two cases are supported: + +1. If the supplied link field is of type INST_IO, its string value is + assumed to be of the form: + + [ "*" ] name [ "[" index "]" ] + + where quoted items are literal and square brackets imply optional + items. White space is ignored. The leading "*", if specified, + implies that the variable in question contains the address of the + desired data. The name is the name of the vxWorks global variable (a + leading underscore is added). The optional array index is multipled + by the data element size (e.g. sizeof(char), sizeof(long) or + sizeof(double)) and applied as an offset to the data address. + + For example: + + a) "fred" refers to the value of the vxWorks global variable "_fred" + + b) "*fred" refers to the value whose address is the value of the + vxWorks global variable "_fred" + + c) "fred[1]" assumes that the vxWorks global variable "_fred" is an + array and refers to its second element + + d) "*fred[1]" assumes that the vxWorks global variable "_fred" + contains the address of an array and refers to the second element + of the array + + Note that the interpretation of the "*" operator is not the same as + in C. For example, "fred" and "fred[0]" are the same and "*fred" and + "fred[0]" are not the same. In this version of the driver, the + value of the pointer is read at run-time rather than initialisation. + + Finally note that strings are not treated any differently from longs + or doubles in that the address returned from this routine is simply + the address of the data. "fred" is the entire string. "fred[2]" + starts at the third character of the string. + +2. Otherwise, behavior is the same as before: the name of the vxWorks + global variable is derived from the record name by stripping off any + prefix ending with the first ":" and any suffix starting with the + last ";". As in the other case, an underscore is automatically + prefixed. + + For example: + + a) "ppp:fred;sss" refers to the vxWorks global variable "_fred" + + b) "a:b:c;d;e" refers to the vxWorks global variable "_b:c;d" + +The second case is supported for backwards compatibility. The first +(INST_IO) is preferred. +*/ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +/* forward references */ +static int parseInstio(char *string, int *deref, char **name, int *index); +static int parseName(char *string, int *deref, char **name, int *index); + +/* + * Determine vxWorks variable name and return address of data + */ +int devSymbFind(char *name, struct link *plink, void *pdpvt) +{ + int deref; + char *nptr; + int index; + SYM_TYPE stype; + void *paddr; + struct vxSym *private; + struct vxSym **pprivate = (struct vxSym **) pdpvt; + + /* if link is of type INST_IO, parse INST_IO string */ + if (plink->type == INST_IO) + { + struct instio *pinstio = (struct instio *) &plink->value.instio; + if (parseInstio(pinstio->string, &deref, &nptr, &index)) + return ERROR; + } + + /* otherwise derive variable name from record name as before */ + else + { + if (parseName(name, &deref, &nptr, &index)) + return ERROR; + } + + if (symFindByName(sysSymTbl, nptr, (char **) &paddr, &stype)) + return ERROR; + + /* Name exists, allocate a private structure */ + private = (struct vxSym *) malloc(sizeof (struct vxSym)); + if (private == NULL) + return ERROR; + + /* Fill in the fields */ + private->index = index; + + /* Setup pointers to the found symbol address */ + if (deref) { + private->ppvar = paddr; + /* private->pvar is not needed with deref symbols */ + } else { + private->ppvar = &private->pvar; + private->pvar = paddr; + } + + /* Pass new private structure back to caller */ + *pprivate = private; + + return OK; +} + +/* + * Parse string of the form ["*"]name["["index"]"] (white space is ignored). + */ +static int parseInstio(char *string, int *deref, char **name, int *index) +{ + static char pname[256]; + char *begin; + + /* copy leading underscore to name */ + strcpy(pname, "_"); + + /* set default return values */ + *deref = 0; + *name = pname; + *index = 0; + + /* skip leading white space */ + for (; isspace(*string); string++); + + /* if next char is "*", will dereference */ + if (*string == '*') + { + *deref = 1; + string++; + } + + /* skip white space */ + for (; isspace(*string); string++); + + /* variable name begins here */ + begin = string; + + /* search for white space or "[" */ + for (; *string && !isspace(*string) && *string != '['; string++); + + /* copy and terminate variable name */ + strncat(pname, begin, string-begin); + pname[string-begin+1] = '\0'; + + /* skip white space */ + for (; isspace(*string); string++); + + /* if found "[", parse index */ + if (*string == '[') + { + string++; + + for (; isspace(*string); string++); + + for(; isdigit(*string); string++) + { + *index *= 10; + *index += *string - '0'; + } + + for (; isspace(*string); string++); + + if (*string != ']') + { + printf("no trailing ]\n"); + return ERROR; + } + + string++; + } + + /* skip trailing white space */ + for (; isspace(*string); string++); + + /* expect to be at end of string */ + if (*string != '\0') + { + printf("unexpected trailing characters\n"); + return ERROR; + } + + return OK; +} + +/* + * Extract vxWorks global variable name from string of form "ppp:name;sss". + */ +static int parseName(char *string, int *deref, char **name, int *index) +{ + static char pname[256]; + + /* no dereferencing */ + *deref = 0; + + /* variable names from C have a prepended underscore */ + strcpy(pname,"_"); + strcat(pname, string); + + /* find any suffix and terminate it */ + *name = strrchr(pname, ';'); + if (*name) + **name = '\0'; + + /* find any prefix and bypass it */ + *name = strchr(pname, ':'); + if (*name) + **name = '_'; + else + *name = pname; + + /* no indexing */ + *index = 0; + + return OK; +} + +/* + * conditionally compiled routine for testing parsing routines + */ +#ifdef TEST +int test(char *string) +{ + int error; + int deref; + char *nptr; + int index; + char *addr; + SYM_TYPE stype; + + printf( "instio: %s -> ", string); + error = parseInstio(string, &deref, &nptr, &index); + printf("%s: ", error ? "error" : "ok" ); + printf("deref=%d, name=%s, index=%d", deref, nptr, index); + if (!symFindByName(sysSymTbl, nptr, &addr, &stype)) + { + if (deref) addr = *((char **)addr); + addr += sizeof(long) * index; + printf(" -> value = %d", *(long *)addr); + } + printf("\n"); + + printf( "name: %s -> ", string); + error = parseName(string, &deref, &nptr, &index); + printf("%s: ", error ? "error" : "ok" ); + printf("deref=%d, name=%s, index=%d", deref, nptr, index); + if (!symFindByName(sysSymTbl, nptr, &addr, &stype)) + printf(" -> value = %d", *(long *)addr); + printf("\n"); + + return OK; +} +#endif /* TEST */ diff --git a/src/dev/symbDev/devSymbTest.c b/src/dev/symbDev/devSymbTest.c new file mode 100644 index 000000000..4f5cc1af9 --- /dev/null +++ b/src/dev/symbDev/devSymbTest.c @@ -0,0 +1,101 @@ +/* devSymbTest.c - Test routines for vxWorks global var device support */ + +/* $Id$ + * + * Author: William Lupton (Keck) + * Date: 8 June 1996 + */ + +/* modification history: + * $Log$ + * Revision 1.1 1996/06/09 00:52:25 wlupton + * initial insertion + * + */ + +/* +DESCRIPTION: + +This module contains routines for testing vxWorks global variable +device support. +*/ + +#include +#include + +#include +#include +#include + +#include +#include + +/* global variables for testing */ + +/* long scalar */ +long testLongScalar = 42; + +/* long array */ +long testLongArray[] = {0,1,2,3,4,5,6,7,8,9}; + +/* double scalar */ +double testDoubleScalar = 125.0; + +/* double array */ +double testDoubleArray[] = {20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0}; + +/* string */ +char testString[] = "0123456789"; + +/* structure and variables referencing its fields */ +struct { + long xxxx; + double yyyy[3]; + char zzzz[80]; +} testStruct = {35, {1.0,2.0,3.0}, "hello dolly"}; + +long *testLongPtr = &testStruct.xxxx; +double *testDoublePtr = testStruct.yyyy; +char *testStringPtr = testStruct.zzzz; + +/* routines for starting and stopping auto-change of values */ +long testRunning = 0; + +int testStart() { + int i, j; + + testRunning = 1; + + for ( i = 0; testRunning; i++ ) { + + /* change global data values */ + testLongScalar++; + for ( j = 0; j < sizeof( testLongArray ) / sizeof( long ); j++ ) + testLongArray[j]++; + testDoubleScalar++; + for ( j = 0; j < sizeof( testDoubleArray ) / sizeof( double ); j++ ) + testDoubleArray[j]++; + for ( j = 0; j < strlen( testString ) - 1; j++ ) + testString[j] = testString[j+1]; + testString[j] = testString[0]; + testStruct.xxxx++; + testStruct.yyyy[0]++; + testStruct.yyyy[1]++; + testStruct.yyyy[2]++; + if ( i % 2 ) + strcpy( testStruct.zzzz, "hello dolly" ); + else + strcpy( testStruct.zzzz, "dolly hello" ); + + /* wait a second */ + taskDelay( sysClkRateGet() ); + } + printf( "test stopped\n" ); + return 0; +} + +int testStop() { + testRunning = 0; + return 0; +} + diff --git a/src/dev/symbDev/devWfSymb.c b/src/dev/symbDev/devWfSymb.c new file mode 100644 index 000000000..329ee93c3 --- /dev/null +++ b/src/dev/symbDev/devWfSymb.c @@ -0,0 +1,111 @@ +/* devWfSymb.c */ +/* base/src/dev $Id$ */ + +/* devWfSymb.c - Device Support for vxWorks Global Symbol Waveform Records*/ +/* + * Author: Andrew Johnson + * Date: 15-10-96 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * ... + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devWfSymb */ +static long init_record(); +static long read_wf(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_wf; +}devWfSymb={ + 5, + NULL, + NULL, + init_record, + NULL, + read_wf}; + +static int sizeofTypes[] = {MAX_STRING_SIZE,1,1,2,2,4,4,4,8,2}; + +double testwf[] = {1.1, 2.2, 4.4, 8.8, 16.16, 32.32}; + + +static long init_record(pwf) + struct waveformRecord *pwf; +{ + /* determine address of record value */ + if (devSymbFind(pwf->name, &pwf->inp, &pwf->dpvt)) + { + recGblRecordError(S_db_badField,(void *)pwf, + "devWfSymb (init_record) Illegal NAME or INP field"); + return(S_db_badField); + } + return(0); +} + +static long read_wf(pwf) + struct waveformRecord *pwf; +{ + long status, typesize; + struct vxSym *private = (struct vxSym *) pwf->dpvt; + + if (private) + { + typesize = sizeofTypes[pwf->ftvl]; + + /* Copy the data */ + memcpy(pwf->bptr, + (char *)(*private->ppvar) + typesize * private->index, + pwf->nelm * typesize); + + pwf->nord = pwf->nelm; /* We always get it all */ + pwf->udf = FALSE; /* Record also does this (but shouldn't) */ + status = 0; + } + else + status = 1; + + return(status); /* Record actually ignores this... */ +} diff --git a/src/dev/symbDev/symb.db b/src/dev/symbDev/symb.db new file mode 100644 index 000000000..632ba7363 --- /dev/null +++ b/src/dev/symbDev/symb.db @@ -0,0 +1,368 @@ + record(ai,"testDoubleArray5") { + field(DESC,"") + field(ASG,"") + field(SCAN,".1 second") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(INP,"@testDoubleArray[5]") + field(PREC,"0") + field(LINR,"NO CONVERSION") + field(EGUF,"0.0000000e+00") + field(EGUL,"0.0000000e+00") + field(EGU,"") + field(HOPR,"0.0000000e+00") + field(LOPR,"0.0000000e+00") + field(AOFF,"0.0000000e+00") + field(ASLO,"1.0000000") + field(SMOO,"0.0000000e+00") + field(HIHI,"0.0000000e+00") + field(LOLO,"0.0000000e+00") + field(HIGH,"0.0000000e+00") + field(LOW,"0.0000000e+00") + field(HHSV,"NO_ALARM") + field(LLSV,"NO_ALARM") + field(HSV,"NO_ALARM") + field(LSV,"NO_ALARM") + field(HYST,"0.000000000000000e+00") + field(ADEL,"0.000000000000000e+00") + field(MDEL,"0.000000000000000e+00") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + } + record(ai,"testDoublePtr") { + field(DESC,"") + field(ASG,"") + field(SCAN,".1 second") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(INP,"@*testDoublePtr[2]") + field(PREC,"0") + field(LINR,"NO CONVERSION") + field(EGUF,"0.0000000e+00") + field(EGUL,"0.0000000e+00") + field(EGU,"") + field(HOPR,"0.0000000e+00") + field(LOPR,"0.0000000e+00") + field(AOFF,"0.0000000e+00") + field(ASLO,"1.0000000") + field(SMOO,"0.0000000e+00") + field(HIHI,"0.0000000e+00") + field(LOLO,"0.0000000e+00") + field(HIGH,"0.0000000e+00") + field(LOW,"0.0000000e+00") + field(HHSV,"NO_ALARM") + field(LLSV,"NO_ALARM") + field(HSV,"NO_ALARM") + field(LSV,"NO_ALARM") + field(HYST,"0.000000000000000e+00") + field(ADEL,"0.000000000000000e+00") + field(MDEL,"0.000000000000000e+00") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + } + record(ai,"testDoubleScalar") { + field(DESC,"") + field(ASG,"") + field(SCAN,".1 second") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(INP,"@testDoubleScalar") + field(PREC,"0") + field(LINR,"NO CONVERSION") + field(EGUF,"0.0000000e+00") + field(EGUL,"0.0000000e+00") + field(EGU,"") + field(HOPR,"0.0000000e+00") + field(LOPR,"0.0000000e+00") + field(AOFF,"0.0000000e+00") + field(ASLO,"1.0000000") + field(SMOO,"0.0000000e+00") + field(HIHI,"0.0000000e+00") + field(LOLO,"0.0000000e+00") + field(HIGH,"0.0000000e+00") + field(LOW,"0.0000000e+00") + field(HHSV,"NO_ALARM") + field(LLSV,"NO_ALARM") + field(HSV,"NO_ALARM") + field(LSV,"NO_ALARM") + field(HYST,"0.000000000000000e+00") + field(ADEL,"0.000000000000000e+00") + field(MDEL,"0.000000000000000e+00") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + } + record(ao,"testDoubleScalarOut") { + field(DESC,"") + field(ASG,"") + field(SCAN,"Passive") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(OUT,"@testDoubleScalar") + field(OROC,"0.0000000e+00") + field(DOL,"0.000000000000000e+00") + field(OMSL,"supervisory") + field(OIF,"Full") + field(PREC,"0") + field(LINR,"NO CONVERSION") + field(EGUF,"0.0000000e+00") + field(EGUL,"0.0000000e+00") + field(EGU,"") + field(DRVH,"0.0000000e+00") + field(DRVL,"0.0000000e+00") + field(HOPR,"0.0000000e+00") + field(LOPR,"0.0000000e+00") + field(AOFF,"0.0000000e+00") + field(ASLO,"0.0000000e+00") + field(HIHI,"0.0000000e+00") + field(LOLO,"0.0000000e+00") + field(HIGH,"0.0000000e+00") + field(LOW,"0.0000000e+00") + field(HHSV,"NO_ALARM") + field(LLSV,"NO_ALARM") + field(HSV,"NO_ALARM") + field(LSV,"NO_ALARM") + field(HYST,"0.000000000000000e+00") + field(ADEL,"0.000000000000000e+00") + field(MDEL,"0.000000000000000e+00") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + field(IVOA,"Continue normally") + field(IVOV,"0.000000000000000e+00") + } + record(longin,"testLongArray5") { + field(DESC,"") + field(ASG,"") + field(SCAN,".1 second") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(INP,"@testLongArray[5]") + field(EGU,"") + field(HOPR,"0") + field(LOPR,"0") + field(HIHI,"0") + field(LOLO,"0") + field(HIGH,"0") + field(LOW,"0") + field(HHSV,"NO_ALARM") + field(LLSV,"NO_ALARM") + field(HSV,"NO_ALARM") + field(LSV,"NO_ALARM") + field(HYST,"0") + field(ADEL,"0") + field(MDEL,"0") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + } + record(longin,"testLongPtr") { + field(DESC,"") + field(ASG,"") + field(SCAN,".1 second") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(INP,"@*testLongPtr") + field(EGU,"") + field(HOPR,"0") + field(LOPR,"0") + field(HIHI,"0") + field(LOLO,"0") + field(HIGH,"0") + field(LOW,"0") + field(HHSV,"NO_ALARM") + field(LLSV,"NO_ALARM") + field(HSV,"NO_ALARM") + field(LSV,"NO_ALARM") + field(HYST,"0") + field(ADEL,"0") + field(MDEL,"0") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + } + record(longin,"testLongScalar") { + field(DESC,"") + field(ASG,"") + field(SCAN,".1 second") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(INP,"@testLongScalar") + field(EGU,"") + field(HOPR,"0") + field(LOPR,"0") + field(HIHI,"0") + field(LOLO,"0") + field(HIGH,"0") + field(LOW,"0") + field(HHSV,"NO_ALARM") + field(LLSV,"NO_ALARM") + field(HSV,"NO_ALARM") + field(LSV,"NO_ALARM") + field(HYST,"0") + field(ADEL,"0") + field(MDEL,"0") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + } + record(longout,"testLongScalarOut") { + field(DESC,"") + field(ASG,"") + field(SCAN,"Passive") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(OUT,"@testLongScalar") + field(DOL,"0.000000000000000e+00") + field(OMSL,"supervisory") + field(EGU,"") + field(HOPR,"0") + field(LOPR,"0") + field(HIHI,"0") + field(LOLO,"0") + field(HIGH,"0") + field(LOW,"0") + field(HHSV,"NO_ALARM") + field(LLSV,"NO_ALARM") + field(HSV,"NO_ALARM") + field(LSV,"NO_ALARM") + field(HYST,"0") + field(ADEL,"0") + field(MDEL,"0") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + field(IVOA,"Continue normally") + field(IVOV,"0") + } + record(stringin,"testString") { + field(DESC,"") + field(ASG,"") + field(SCAN,".1 second") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(VAL,"") + field(INP,"@testString") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + } + record(stringin,"testStringPtr") { + field(DESC,"") + field(ASG,"") + field(SCAN,".1 second") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(VAL,"") + field(INP,"@*testStringPtr") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + } + record(stringout,"testStringOut") { + field(DESC,"") + field(ASG,"") + field(SCAN,"Passive") + field(PINI,"NO") + field(PHAS,"0") + field(EVNT,"0") + field(TSEL,"0.000000000000000e+00") + field(DTYP,"vxWorks Variable (INST_IO)") + field(DISV,"1") + field(SDIS,"0.000000000000000e+00") + field(DISS,"NO_ALARM") + field(PRIO,"LOW") + field(FLNK,"0.000000000000000e+00") + field(VAL,"") + field(DOL,"0.000000000000000e+00") + field(OMSL,"supervisory") + field(OUT,"@testString") + field(SIOL,"0.000000000000000e+00") + field(SIML,"0.000000000000000e+00") + field(SIMS,"NO_ALARM") + field(IVOA,"Continue normally") + field(IVOV,"") + } + diff --git a/src/dev/symbDev/symb.dbd b/src/dev/symbDev/symb.dbd new file mode 100644 index 000000000..1a3bb4596 --- /dev/null +++ b/src/dev/symbDev/symb.dbd @@ -0,0 +1,13 @@ +device( "ai" , INST_IO, "devAiSymb" , "vxWorks Variable (INST_IO)" ) +device( "ao" , INST_IO, "devAoSymb" , "vxWorks Variable (INST_IO)" ) +device( "bi" , INST_IO, "devBiSymb" , "vxWorks Variable (INST_IO)" ) +device( "bo" , INST_IO, "devBoSymb" , "vxWorks Variable (INST_IO)" ) +device( "longin" , INST_IO, "devLiSymb" , "vxWorks Variable (INST_IO)" ) +device( "longout" , INST_IO, "devLoSymb" , "vxWorks Variable (INST_IO)" ) +device( "mbbi" , INST_IO, "devMbbiSymb" , "vxWorks Variable (INST_IO)" ) +device( "mbbo" , INST_IO, "devMbboSymb" , "vxWorks Variable (INST_IO)" ) +device( "stringin" , INST_IO, "devSiSymb" , "vxWorks Variable (INST_IO)" ) +device( "stringout", INST_IO, "devSoSymb" , "vxWorks Variable (INST_IO)" ) +device( "waveform" , INST_IO, "devWfSymb" , "vxWorks Variable (INST_IO)" ) +device( "mbbi" , INST_IO, "devMbbiSymbRaw", "Raw vxWorks Variable (INST_IO)" ) +device( "mbbo" , INST_IO, "devMbboSymbRaw", "Raw vxWorks Variable (INST_IO)" ) diff --git a/src/dev/testDev/Makefile b/src/dev/testDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/testDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/testDev/Makefile.Vx b/src/dev/testDev/Makefile.Vx new file mode 100644 index 000000000..52cec5570 --- /dev/null +++ b/src/dev/testDev/Makefile.Vx @@ -0,0 +1,20 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devAiTestAsyn.c +SRCS.c += ../devAoTestAsyn.c +SRCS.c += ../devBiTestAsyn.c +SRCS.c += ../devBoTestAsyn.c +SRCS.c += ../devEventTestIoEvent.c +SRCS.c += ../devHistogramTestAsyn.c +SRCS.c += ../devMbbiTestAsyn.c +SRCS.c += ../devMbboTestAsyn.c +SRCS.c += ../devSiTestAsyn.c +SRCS.c += ../devSoTestAsyn.c +SRCS.c += ../devWfTestAsyn.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAiTestAsyn.c b/src/dev/testDev/devAiTestAsyn.c similarity index 100% rename from src/dev/devAiTestAsyn.c rename to src/dev/testDev/devAiTestAsyn.c diff --git a/src/dev/devAoTestAsyn.c b/src/dev/testDev/devAoTestAsyn.c similarity index 100% rename from src/dev/devAoTestAsyn.c rename to src/dev/testDev/devAoTestAsyn.c diff --git a/src/dev/devBiTestAsyn.c b/src/dev/testDev/devBiTestAsyn.c similarity index 100% rename from src/dev/devBiTestAsyn.c rename to src/dev/testDev/devBiTestAsyn.c diff --git a/src/dev/devBoTestAsyn.c b/src/dev/testDev/devBoTestAsyn.c similarity index 100% rename from src/dev/devBoTestAsyn.c rename to src/dev/testDev/devBoTestAsyn.c diff --git a/src/dev/devEventTestIoEvent.c b/src/dev/testDev/devEventTestIoEvent.c similarity index 100% rename from src/dev/devEventTestIoEvent.c rename to src/dev/testDev/devEventTestIoEvent.c diff --git a/src/dev/devHistogramTestAsyn.c b/src/dev/testDev/devHistogramTestAsyn.c similarity index 100% rename from src/dev/devHistogramTestAsyn.c rename to src/dev/testDev/devHistogramTestAsyn.c diff --git a/src/dev/devMbbiTestAsyn.c b/src/dev/testDev/devMbbiTestAsyn.c similarity index 100% rename from src/dev/devMbbiTestAsyn.c rename to src/dev/testDev/devMbbiTestAsyn.c diff --git a/src/dev/devMbboTestAsyn.c b/src/dev/testDev/devMbboTestAsyn.c similarity index 100% rename from src/dev/devMbboTestAsyn.c rename to src/dev/testDev/devMbboTestAsyn.c diff --git a/src/dev/devSiTestAsyn.c b/src/dev/testDev/devSiTestAsyn.c similarity index 100% rename from src/dev/devSiTestAsyn.c rename to src/dev/testDev/devSiTestAsyn.c diff --git a/src/dev/devSoTestAsyn.c b/src/dev/testDev/devSoTestAsyn.c similarity index 100% rename from src/dev/devSoTestAsyn.c rename to src/dev/testDev/devSoTestAsyn.c diff --git a/src/dev/devWfTestAsyn.c b/src/dev/testDev/devWfTestAsyn.c similarity index 100% rename from src/dev/devWfTestAsyn.c rename to src/dev/testDev/devWfTestAsyn.c diff --git a/src/dev/vmiDev/Makefile b/src/dev/vmiDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/vmiDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/vmiDev/Makefile.Vx b/src/dev/vmiDev/Makefile.Vx new file mode 100644 index 000000000..f062947bc --- /dev/null +++ b/src/dev/vmiDev/Makefile.Vx @@ -0,0 +1,11 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devAoVmiVme4100.c +SRCS.c += ../devVmic2534.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAoVmiVme4100.c b/src/dev/vmiDev/devAoVmiVme4100.c similarity index 100% rename from src/dev/devAoVmiVme4100.c rename to src/dev/vmiDev/devAoVmiVme4100.c diff --git a/src/dev/devVmic2534.c b/src/dev/vmiDev/devVmic2534.c similarity index 100% rename from src/dev/devVmic2534.c rename to src/dev/vmiDev/devVmic2534.c diff --git a/src/dev/vxStatsDev/Makefile b/src/dev/vxStatsDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/vxStatsDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/vxStatsDev/Makefile.Vx b/src/dev/vxStatsDev/Makefile.Vx new file mode 100644 index 000000000..ad36741c2 --- /dev/null +++ b/src/dev/vxStatsDev/Makefile.Vx @@ -0,0 +1,10 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devVXStats.c + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devVXStats.c b/src/dev/vxStatsDev/devVXStats.c similarity index 100% rename from src/dev/devVXStats.c rename to src/dev/vxStatsDev/devVXStats.c diff --git a/src/dev/xycomDev/Makefile b/src/dev/xycomDev/Makefile new file mode 100644 index 000000000..826bdd7e5 --- /dev/null +++ b/src/dev/xycomDev/Makefile @@ -0,0 +1,6 @@ +TOP=../../.. + +include $(TOP)/config/CONFIG_BASE + +include $(TOP)/config/RULES_ARCHS + diff --git a/src/dev/xycomDev/Makefile.Vx b/src/dev/xycomDev/Makefile.Vx new file mode 100644 index 000000000..87b8f8cc9 --- /dev/null +++ b/src/dev/xycomDev/Makefile.Vx @@ -0,0 +1,21 @@ +TOP = ../../../.. +include $(TOP)/config/CONFIG_BASE + +SRCS.c += ../devAiXy566Di.c +SRCS.c += ../devAiXy566DiL.c +SRCS.c += ../devAiXy566Se.c +SRCS.c += ../devBiXVme210.c +SRCS.c += ../devBoXVme220.c +SRCS.c += ../devMbbiDirectXVme210.c +SRCS.c += ../devMbbiXVme210.c +SRCS.c += ../devMbboDirectXVme220.c +SRCS.c += ../devMbboXVme220.c +SRCS.c += ../devWfXy566Sc.c +SRCS.c += ../devXy240.c + + +PROD = $(SRCS.c:../%.c=%.o) + +include $(TOP)/config/RULES.Vx + + diff --git a/src/dev/devAiXy566Di.c b/src/dev/xycomDev/devAiXy566Di.c similarity index 100% rename from src/dev/devAiXy566Di.c rename to src/dev/xycomDev/devAiXy566Di.c diff --git a/src/dev/devAiXy566DiL.c b/src/dev/xycomDev/devAiXy566DiL.c similarity index 100% rename from src/dev/devAiXy566DiL.c rename to src/dev/xycomDev/devAiXy566DiL.c diff --git a/src/dev/devAiXy566Se.c b/src/dev/xycomDev/devAiXy566Se.c similarity index 100% rename from src/dev/devAiXy566Se.c rename to src/dev/xycomDev/devAiXy566Se.c diff --git a/src/dev/devBiXVme210.c b/src/dev/xycomDev/devBiXVme210.c similarity index 100% rename from src/dev/devBiXVme210.c rename to src/dev/xycomDev/devBiXVme210.c diff --git a/src/dev/devBoXVme220.c b/src/dev/xycomDev/devBoXVme220.c similarity index 100% rename from src/dev/devBoXVme220.c rename to src/dev/xycomDev/devBoXVme220.c diff --git a/src/dev/devMbbiDirectXVme210.c b/src/dev/xycomDev/devMbbiDirectXVme210.c similarity index 100% rename from src/dev/devMbbiDirectXVme210.c rename to src/dev/xycomDev/devMbbiDirectXVme210.c diff --git a/src/dev/devMbbiXVme210.c b/src/dev/xycomDev/devMbbiXVme210.c similarity index 100% rename from src/dev/devMbbiXVme210.c rename to src/dev/xycomDev/devMbbiXVme210.c diff --git a/src/dev/devMbboDirectXVme220.c b/src/dev/xycomDev/devMbboDirectXVme220.c similarity index 100% rename from src/dev/devMbboDirectXVme220.c rename to src/dev/xycomDev/devMbboDirectXVme220.c diff --git a/src/dev/devMbboXVme220.c b/src/dev/xycomDev/devMbboXVme220.c similarity index 100% rename from src/dev/devMbboXVme220.c rename to src/dev/xycomDev/devMbboXVme220.c diff --git a/src/dev/devWfXy566Sc.c b/src/dev/xycomDev/devWfXy566Sc.c similarity index 100% rename from src/dev/devWfXy566Sc.c rename to src/dev/xycomDev/devWfXy566Sc.c diff --git a/src/dev/devXy240.c b/src/dev/xycomDev/devXy240.c similarity index 100% rename from src/dev/devXy240.c rename to src/dev/xycomDev/devXy240.c diff --git a/src/vxWorks/dev/apsDev/devApsEg.c b/src/vxWorks/dev/apsDev/devApsEg.c new file mode 100644 index 000000000..61e42a341 --- /dev/null +++ b/src/vxWorks/dev/apsDev/devApsEg.c @@ -0,0 +1,2062 @@ +/* #define EG_DEBUG */ +/* + +***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE, +AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE +AND IN ALL SOURCE LISTINGS OF THE CODE. + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +Argonne National Laboratory (ANL), with facilities in the States of +Illinois and Idaho, is owned by the United States Government, and +operated by the University of Chicago under provision of a contract +with the Department of Energy. + +Portions of this material resulted from work developed under a U.S. +Government contract and are subject to the following license: For +a period of five years from March 30, 1993, the Government is +granted for itself and others acting on its behalf a paid-up, +nonexclusive, irrevocable worldwide license in this computer +software to reproduce, prepare derivative works, and perform +publicly and display publicly. With the approval of DOE, this +period may be renewed for two additional five year periods. +Following the expiration of this period or periods, the Government +is granted for itself and others acting on its behalf, a paid-up, +nonexclusive, irrevocable worldwide license in this computer +software to reproduce, prepare derivative works, distribute copies +to the public, perform publicly and display publicly, and to permit +others to do so. + +***************************************************************** + DISCLAIMER +***************************************************************** + +NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR +THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS, +MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL +LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR +USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS +DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY +OWNED RIGHTS. + +***************************************************************** +LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY +DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). +*/ + +/* + * Author: John R. Winans + * Date: 07-21-93 + * + * PROBLEMS: + * -When transisioning from ALTERNATE mode to anything else, the mode MUST + * be set to OFF long enough to clear/reload the RAMS first. + * -In SINGLE mode, to rearm, the mode must be set to OFF, then back to SINGLE. + * + * Modification Log: + * ----------------- +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef EG_DEBUG +#define STATIC +#else +#define STATIC static +#endif + +#define EG_MONITOR /* Include the EG monitor program */ +#define RAM_LOAD_SPIN_DELAY 1 /* taskDelay() for waiting on RAM */ + +/* Only look at these bits when ORing on new bits in the control register */ +#define CTL_OR_MASK (0x9660) + +typedef struct ApsEgStruct +{ + unsigned short Control; + unsigned short EventMask; + unsigned short VmeEvent; + unsigned short Seq2Addr; + unsigned short Seq2Data; + unsigned short Seq1Addr; + unsigned short Seq1Data; + + unsigned short Event0Map; + unsigned short Event1Map; + unsigned short Event2Map; + unsigned short Event3Map; + unsigned short Event4Map; + unsigned short Event5Map; + unsigned short Event6Map; + unsigned short Event7Map; +}ApsEgStruct; + +typedef struct +{ + ApsEgStruct *pEg; /* pointer to card described. */ + SEM_ID EgLock; + struct egRecord *pEgRec; /* Record that represents the card */ + double Ram1Speed; /* in Hz */ + long Ram1Dirty; /* needs to be reloaded */ + double Ram2Speed; /* in Hz */ + long Ram2Dirty; /* needs to be reloaded */ + ELLLIST EgEvent1; /* RAM1 event list head */ + ELLLIST EgEvent2; /* RAM2 event list head */ +} EgLinkStruct; + +typedef struct +{ + ELLNODE node; + struct egeventRecord *pRec; +} EgEventNode; + +STATIC long EgInitDev(int pass); +STATIC long EgProcEgRec(struct egRecord *pRec); +STATIC long EgDisableFifo(EgLinkStruct *pParm); +STATIC long EgEnableFifo(EgLinkStruct *pParm); +STATIC long EgMasterEnable(EgLinkStruct *pParm); +STATIC long EgMasterDisable(EgLinkStruct *pParm); +STATIC long EgClearSeq(EgLinkStruct *pParm, int channel); +STATIC long EgSetTrigger(EgLinkStruct *pParm, unsigned int Channel, unsigned short Event); +STATIC long EgEnableTrigger(EgLinkStruct *pParm, unsigned int Channel, int state); +STATIC int EgSeqEnableCheck(EgLinkStruct *pParm, unsigned int Seq); +STATIC long EgSeqTrigger(EgLinkStruct *pParm, unsigned int Seq); +STATIC long EgSetSeqMode(EgLinkStruct *pParm, unsigned int Seq, int Mode); +STATIC long EgEnableVme(EgLinkStruct *pParm, int state); +STATIC long EgGenerateVmeEvent(EgLinkStruct *pParm, int Event); +STATIC long EgResetAll(EgLinkStruct *pParm); +STATIC int EgReadSeqRam(EgLinkStruct *pParm, int channel, unsigned char *pBuf); +STATIC int EgWriteSeqRam(EgLinkStruct *pParm, int channel, unsigned char *pBuf); +STATIC int EgDumpRegs(EgLinkStruct *pParm); +STATIC int SetupSeqRam(EgLinkStruct *pParm, int channel); +STATIC void SeqConfigMenu(void); +STATIC void PrintSeq(EgLinkStruct *pParm, int channel); +STATIC int ConfigSeq(EgLinkStruct *pParm, int channel); +STATIC void menu(void); +STATIC long EgCheckTaxi(EgLinkStruct *pParm); +STATIC long EgScheduleRamProgram(int card); +STATIC long EgGetMode(EgLinkStruct *pParm, int ram); +STATIC long EgGetRamEvent(EgLinkStruct *pParm, long Ram, long Addr); +STATIC long EgMasterEnableGet(EgLinkStruct *pParm); +STATIC long EgCheckFifo(EgLinkStruct *pParm); +STATIC long EgGetTrigger(EgLinkStruct *pParm, unsigned int Channel); +STATIC long EgGetEnableTrigger(EgLinkStruct *pParm, unsigned int Channel); +STATIC long EgGetBusyStatus(EgLinkStruct *pParm, int Ram); +STATIC long EgProgramRamEvent(EgLinkStruct *pParm, long Ram, long Addr, long Event); +STATIC long EgGetAltStatus(EgLinkStruct *pParm, int Ram); +STATIC long EgEnableAltRam(EgLinkStruct *pParm, int Ram); + +#define NUM_EG_LINKS 4 /* Total allowed number of EG boards */ + +/* Parms for the event generator task */ +#define EGRAM_NAME "EgRam" +#define EGRAM_PRI 100 +#define EGRAM_OPT VX_FP_TASK|VX_STDIO +#define EGRAM_STACK 4000 + +static EgLinkStruct EgLink[NUM_EG_LINKS]; +static int EgNumLinks = 0; +static SEM_ID EgRamTaskEventSem; +static int ConfigureLock = 0; + +/****************************************************************************** + * + * Routine used to verify that a given card number is valid. + * Returns zero if valid, nonzero otherwise. + * + ******************************************************************************/ +STATIC long EgCheckCard(int Card) +{ + if ((Card < 0)||(Card >= EgNumLinks)) + return(-1); + if (EgLink[Card].pEg == NULL) + return(-1); + return(0); +} + +/****************************************************************************** + * + * User configurable card addresses are saved in this array. + * To configure them, use the EgConfigure command from the startup script + * when booting Epics. + * + ******************************************************************************/ +int EgConfigure(int Card, unsigned long CardAddress) +{ + unsigned long Junk; + + if (ConfigureLock != 0) + { + epicsPrintf("devApsEg: Cannot change configuration after init. Request ignored\n"); + return(-1); + } + if (Card >= NUM_EG_LINKS) + { + epicsPrintf("devApsEg: Card number invalid, must be 0-%d\n", NUM_EG_LINKS); + return(-1); + } + if (CardAddress > 0xffff) + { + epicsPrintf("devApsEg: Card address invalid, must be 0x0000-0xffff\n"); + return(-1); + } + if(sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, (char*)CardAddress, (char**)&EgLink[Card].pEg)!=OK) + { + epicsPrintf("devApsEg: Failure mapping requested A16 address\n"); + EgLink[Card].pEg = NULL; + return(-1); + } + if (vxMemProbe((char*)&(EgLink[Card].pEg->Control), READ, sizeof(short), (char*)&Junk) != OK) + { + epicsPrintf("devApsEg: Failure probing for event receiver... Card disabled\n"); + EgLink[Card].pEg = NULL; + return(-1); + } + + if (Card >= EgNumLinks) + EgNumLinks = Card+1; + return(0); +} +/****************************************************************************** + * + * This is used to run thru the list of egevent records and dump their values + * into a sequence RAM. + * + * The caller of this function MUST hold the link-lock for the board holding + * the ram to be programmed. + * + ******************************************************************************/ +STATIC long EgLoadRamList(EgLinkStruct *pParm, long Ram) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + volatile unsigned short *pAddr; + volatile unsigned short *pData; + ELLNODE *pNode; + struct egeventRecord *pEgevent; + int LastRamPos = 0; + int AltFlag = 0; + double RamSpeed; + + if (Ram == 1) + RamSpeed = pParm->Ram1Speed; + else + RamSpeed = pParm->Ram2Speed; + + /* When in ALT mode, all event records have to be downloaded */ + if (EgGetMode(pParm, 1) == egMOD1_Alternate) + { + pNode = ellFirst(&pParm->EgEvent1); + RamSpeed = pParm->Ram1Speed; /* RAM1 clock used when in ALT mode */ + AltFlag = 1; + } + else + { + if (Ram == 1) + pNode = ellFirst(&pParm->EgEvent1); + else + pNode = ellFirst(&pParm->EgEvent2); + } + if (Ram == 1) + { + pAddr = &pEg->Seq1Addr; + pData = &pEg->Seq1Data; + } + else + { + pAddr = &pEg->Seq2Addr; + pData = &pEg->Seq2Data; + } + /* Get first egevent record from list */ + while (pNode != NULL) + { + pEgevent = ((EgEventNode *)pNode)->pRec; + pEgevent->apos = pEgevent->dpos; /* try to get the desired pos */ + + /* If RAM position already full, fine the next available hole */ + while ((pEgevent->apos < 0x7fff) && (EgGetRamEvent(pParm, Ram, pEgevent->apos) != 0)) + ++pEgevent->apos; + + if (pEgevent->apos < 0x7fff) + { + /* put the record's event code into the RAM */ + EgProgramRamEvent(pParm, Ram, pEgevent->apos, pEgevent->enm); + + /* Remember where the last event went into the RAM */ + if (pEgevent->apos > LastRamPos) + LastRamPos = pEgevent->apos; + } + else /* Overflow the event ram... toss it out. */ + { + pEgevent->apos = 0x7fff; + } + + /* get next record */ + pNode = ellNext(pNode); + + /* In alt mode, we need all from both lists */ + if ((pNode == NULL) && (AltFlag != 0)) + { + pNode = ellFirst(&pParm->EgEvent2); + AltFlag = 0; /* prevent endless loop on EgEvent2 list! */ + } + + /* check for divide by zero problems */ + if (RamSpeed > 0) + { + /* Figure out the actual position */ + switch (pEgevent->unit) + { + case REC_EGEVENT_UNIT_TICKS: + pEgevent->adly = pEgevent->apos; + break; + case REC_EGEVENT_UNIT_FORTNIGHTS: + pEgevent->adly = ((float)pEgevent->apos / (60.0 * 60.0 * 24.0 * 14.0)) / RamSpeed; + break; + case REC_EGEVENT_UNIT_WEEKS: + pEgevent->adly = ((float)pEgevent->apos / (60.0 * 60.0 * 24.0 * 7.0)) / RamSpeed; + break; + case REC_EGEVENT_UNIT_DAYS: + pEgevent->adly = ((float)pEgevent->apos / (60.0 * 60.0 * 24.0)) / RamSpeed; + break; + case REC_EGEVENT_UNIT_HOURS: + pEgevent->adly = ((float)pEgevent->apos / (60.0 * 60.0)) / RamSpeed; + break; + case REC_EGEVENT_UNIT_MINUITES: + pEgevent->adly = ((float)pEgevent->apos / 60.0) / RamSpeed; + break; + case REC_EGEVENT_UNIT_SECONDS: + pEgevent->adly = (float)pEgevent->apos / RamSpeed; + break; + case REC_EGEVENT_UNIT_MILLISECONDS: + pEgevent->adly = (float)pEgevent->apos * (1000.0 / RamSpeed); + break; + case REC_EGEVENT_UNIT_MICROSECONDS: + pEgevent->adly = (float)pEgevent->apos * (1000000.0 / RamSpeed); + break; + case REC_EGEVENT_UNIT_NANOSECONDS: + pEgevent->adly = (float)pEgevent->apos * (1000000000.0 / RamSpeed); + break; + } + } + else + pEgevent->adly = 0; + + if (pEgevent->tpro) + printf("EgLoadRamList(%s) adly %g ramspeed %g\n", pEgevent->name, pEgevent->adly, RamSpeed); + + /* Release database monitors for dpos, apos, and adly here */ + db_post_events(pEgevent, &pEgevent->adly, DBE_VALUE|DBE_LOG); + db_post_events(pEgevent, &pEgevent->dpos, DBE_VALUE|DBE_LOG); + db_post_events(pEgevent, &pEgevent->apos, DBE_VALUE|DBE_LOG); + } + EgProgramRamEvent(pParm, Ram, LastRamPos+1, EG_SEQ_RAM_EVENT_END); + + *pAddr = 0; /* set back to 0 so will be ready to run */ + + return(0); +} +/****************************************************************************** + * + * This task is used to do the actual manipulation of the sequence RAMs on + * the event generator cards. There is only one task on the crate for as many + * EG-cards that are used. + * + * The way this works is we wait on a semaphore that is given when ever the + * data values for the SEQ-rams is altered. (This data is left in the database + * record.) When this task wakes up, it runs thru a linked list (created at + * init time) of all the event-generator records for the RAM that was logically + * updated. While doing so, it sets the event codes in the RAM. + * + * The catch is that a given RAM can not be altered when it is enabled for + * event generation. If we find that the RAM needs updating, but is busy + * This task will poll the RAM until it is no longer busy, then download + * it. + * + * This task views the RAMs as being in one of two modes. Either alt-mode, or + * "the rest". + * + * When NOT in alt-mode, we simply wait for the required RAM to become disabled + * and non-busy and then download it. + * + * In alt-mode, we can download to either of the two RAMs and then tell the + * EG to start using that RAM. The EG can only use one RAM at a time in + * alt-mode, but we still have a problem when one RAM is running, and the other + * has ALREADY been downloaded and enabled... so they are both 'busy.' + * + ******************************************************************************/ +STATIC void EgRamTask(void) +{ + int j; + int Spinning = 0; + + for (;;) + { + if (Spinning != 0) + taskDelay(RAM_LOAD_SPIN_DELAY); + else + semTake(EgRamTaskEventSem, WAIT_FOREVER); + + Spinning = 0; + for (j=0;jout.value.vmeio.card) != 0) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEg::EgInitEgRec() bad card number"); + return(S_db_badField); + } + + if (EgLink[pRec->out.value.vmeio.card].pEgRec != NULL) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEg::EgInitEgRec() only one record allowed per card"); + return(S_db_badField); + } + pLink = &EgLink[pRec->out.value.vmeio.card]; + + pLink->pEgRec = pRec; + pLink->Ram1Speed = pRec->r1sp; + pLink->Ram2Speed = pRec->r2sp; + +#if 0 /* We decided to init the generator from record instead of v-v */ + /* Init the record to what the card's settings are */ + pRec->enab = EgMasterEnableGet(pLink); + pRec->lena = pRec->enab; + + pRec->lmd1 = pRec->mod1 = EgGetMode(pLink, 1); + pRec->lmd2 = pRec->mod2 = EgGetMode(pLink, 2); + + pRec->fifo = EgCheckFifo(pLink); + pRec->lffo = pRec->fifo; + + pRec->let0 = pRec->et0 = EgGetTrigger(pLink, 0); + pRec->let1 = pRec->et1 = EgGetTrigger(pLink, 1); + pRec->let2 = pRec->et2 = EgGetTrigger(pLink, 2); + pRec->let3 = pRec->et3 = EgGetTrigger(pLink, 3); + pRec->let4 = pRec->et4 = EgGetTrigger(pLink, 4); + pRec->let5 = pRec->et5 = EgGetTrigger(pLink, 5); + pRec->let6 = pRec->et6 = EgGetTrigger(pLink, 6); + pRec->let7 = pRec->et7 = EgGetTrigger(pLink, 7); + + pRec->ete0 = EgGetEnableTrigger(pLink, 0); + pRec->ete1 = EgGetEnableTrigger(pLink, 1); + pRec->ete2 = EgGetEnableTrigger(pLink, 2); + pRec->ete3 = EgGetEnableTrigger(pLink, 3); + pRec->ete4 = EgGetEnableTrigger(pLink, 4); + pRec->ete5 = EgGetEnableTrigger(pLink, 5); + pRec->ete6 = EgGetEnableTrigger(pLink, 6); + pRec->ete7 = EgGetEnableTrigger(pLink, 7); + + pRec->trg1 = 0; + pRec->trg2 = 0; + pRec->clr1 = 0; + pRec->clr2 = 0; + pRec->vme = 0; +#else + + /* Keep the thing off until we are dun setting it up */ + EgMasterDisable(pLink); + + pRec->lffo = pRec->fifo; + if (pRec->fifo) + EgEnableFifo(pLink); + else + EgDisableFifo(pLink); + + /* Disable these things so I can adjust them */ + EgEnableTrigger(pLink, 0, 0); + EgEnableTrigger(pLink, 1, 0); + EgEnableTrigger(pLink, 2, 0); + EgEnableTrigger(pLink, 3, 0); + EgEnableTrigger(pLink, 4, 0); + EgEnableTrigger(pLink, 5, 0); + EgEnableTrigger(pLink, 6, 0); + EgEnableTrigger(pLink, 7, 0); + + /* Set the trigger event codes */ + pRec->let0 = pRec->et0; + EgSetTrigger(pLink, 0, pRec->et0); + pRec->let1 = pRec->et1; + EgSetTrigger(pLink, 1, pRec->et1); + pRec->let2 = pRec->et2; + EgSetTrigger(pLink, 2, pRec->et2); + pRec->let3 = pRec->et3; + EgSetTrigger(pLink, 3, pRec->et3); + pRec->let4 = pRec->et4; + EgSetTrigger(pLink, 4, pRec->et4); + pRec->let5 = pRec->et5; + EgSetTrigger(pLink, 5, pRec->et5); + pRec->let6 = pRec->et6; + EgSetTrigger(pLink, 6, pRec->et6); + pRec->let7 = pRec->et7; + EgSetTrigger(pLink, 7, pRec->et7); + + /* Set enables for the triggers not that they have valid values */ + EgEnableTrigger(pLink, 0, pRec->ete0); + EgEnableTrigger(pLink, 1, pRec->ete1); + EgEnableTrigger(pLink, 2, pRec->ete2); + EgEnableTrigger(pLink, 3, pRec->ete3); + EgEnableTrigger(pLink, 4, pRec->ete4); + EgEnableTrigger(pLink, 5, pRec->ete5); + EgEnableTrigger(pLink, 6, pRec->ete6); + EgEnableTrigger(pLink, 7, pRec->ete7); + + /* These are one-shots... init them for future detection */ + pRec->trg1 = 0; + pRec->trg2 = 0; + pRec->clr1 = 0; + pRec->clr2 = 0; + pRec->vme = 0; + + /* BUG -- have to deal with ALT mode... if either is ALT, both must be ALT */ + pRec->lmd1 = pRec->mod1; + EgSetSeqMode(pLink, 1, pRec->mod1); + pRec->lmd2 = pRec->mod2; + EgSetSeqMode(pLink, 2, pRec->mod2); + + if (pRec->enab) + EgMasterEnable(pLink); + else + EgMasterDisable(pLink); + pRec->lena = pRec->enab; + +#endif + + if (EgCheckTaxi(pLink) != 0) + pRec->taxi = 1; + else + pRec->taxi = 0; + return(0); +} + +/****************************************************************************** + * + * Process an EG record. + * + ******************************************************************************/ +STATIC long EgProcEgRec(struct egRecord *pRec) +{ + EgLinkStruct *pLink = &EgLink[pRec->out.value.vmeio.card]; + + if (pRec->tpro > 10) + printf("devApsEg::proc(%s) link%d at %p\n", pRec->name, + pRec->out.value.vmeio.card, pLink); + + /* Check if the card is present */ + if (EgCheckCard(pRec->out.value.vmeio.card) != 0) + return(0); + + semTake (pLink->EgLock, WAIT_FOREVER); + +#if 0 /* This should not be in here */ + if (pRec->udf != 0) + { /* Record has garbage values in it... Read from card */ + if (pRec->tpro > 10) + printf("UDF is set, reading values from card\n"); + + pRec->enab = EgMasterEnableGet(pLink); + pRec->lena = pRec->enab; + + pRec->lmd1 = pRec->mod1 = EgGetMode(pLink, 1); + pRec->lmd2 = pRec->mod2 = EgGetMode(pLink, 2); + + pRec->fifo = EgCheckFifo(pLink); + pRec->lffo = pRec->fifo; + + pRec->let0 = pRec->et0 = EgGetTrigger(pLink, 0); + pRec->let1 = pRec->et1 = EgGetTrigger(pLink, 1); + pRec->let2 = pRec->et2 = EgGetTrigger(pLink, 2); + pRec->let3 = pRec->et3 = EgGetTrigger(pLink, 3); + pRec->let4 = pRec->et4 = EgGetTrigger(pLink, 4); + pRec->let5 = pRec->et5 = EgGetTrigger(pLink, 5); + pRec->let6 = pRec->et6 = EgGetTrigger(pLink, 6); + pRec->let7 = pRec->et7 = EgGetTrigger(pLink, 7); + + pRec->trg1 = 0; + pRec->trg2 = 0; + pRec->clr1 = 0; + pRec->clr2 = 0; + pRec->vme = 0; + + if (EgCheckTaxi(pLink) != 0) + pRec->taxi = 1; + else + pRec->taxi = 0; + + } + else +#endif + { + /* Master enable */ + /*if (pRec->enab != pRec->lena)*/ + if (pRec->enab != EgMasterEnableGet(pLink)) + { + if (pRec->enab == 0) + { + if (pRec->tpro > 10) + printf(", Master Disable"); + EgMasterDisable(pLink); + } + else + { + if (pRec->tpro > 10) + printf(", Master Enable"); + EgMasterEnable(pLink); + } + pRec->lena = pRec->enab; + } + + /* Check for a mode change. */ + if (pRec->mod1 != pRec->lmd1) + { + if (pRec->tpro > 10) + printf(", Mode1=%d", pRec->mod1); + if (pRec->mod1 == egMOD1_Alternate) + { + pRec->mod1 = egMOD1_Alternate; + pRec->lmd1 = egMOD1_Alternate; + pRec->mod2 = egMOD1_Alternate; + pRec->lmd2 = egMOD1_Alternate; + + pLink->Ram1Dirty = 1; + pLink->Ram2Dirty = 1; + } + else if (pRec->lmd1 == egMOD1_Alternate) + { + pRec->mod2 = egMOD1_Off; + pRec->lmd2 = egMOD1_Off; + EgSetSeqMode(pLink, 2, egMOD1_Off); + pLink->Ram1Dirty = 1; + pLink->Ram2Dirty = 1; + } + EgSetSeqMode(pLink, 1, pRec->mod1); + pRec->lmd1 = pRec->mod1; + } + if (pRec->mod2 != pRec->lmd2) + { + if (pRec->tpro > 10) + printf(", Mode2=%d", pRec->mod2); + if (pRec->mod2 == egMOD1_Alternate) + { + pRec->mod1 = egMOD1_Alternate; + pRec->lmd1 = egMOD1_Alternate; + pRec->mod2 = egMOD1_Alternate; + pRec->lmd2 = egMOD1_Alternate; + + pLink->Ram1Dirty = 1; + pLink->Ram2Dirty = 1; + } + else if (pRec->lmd2 == egMOD1_Alternate) + { + pRec->mod1 = egMOD1_Off; + pRec->lmd2 = egMOD1_Off; + EgSetSeqMode(pLink, 1, egMOD1_Off); + pLink->Ram1Dirty = 1; + pLink->Ram2Dirty = 1; + } + EgSetSeqMode(pLink, 2, pRec->mod2); + pRec->lmd2 = pRec->mod2; + } + /* Deal with FIFO enable flag */ + if (pRec->fifo != pRec->lffo) + { + if (pRec->fifo == 0) + { + if (pRec->tpro > 10) + printf(", FIFO Disable"); + EgDisableFifo(pLink); + } + else + { + if (pRec->tpro > 10) + printf(", FIFO Enable"); + EgEnableFifo(pLink); + } + pRec->lffo = pRec->fifo; + } + + /* We use the manual triggers as one-shots. They get reset to zero */ + if (pRec->trg1 != 0) + { + if (pRec->tpro > 10) + printf(", Trigger-1"); + EgSeqTrigger(pLink, 1); + pRec->trg1 = 0; + } + if (pRec->trg2 != 0) + { + if (pRec->tpro > 10) + printf(", Trigger-2"); + EgSeqTrigger(pLink, 2); + pRec->trg2 = 0; + } + + /* We use the clears as as one-shots. They get reset to zero */ + if (pRec->clr1 !=0) + { + if (pRec->tpro > 10) + printf(", clear-1"); + EgClearSeq(pLink, 1); + pRec->clr1 = 0; + } + if (pRec->clr2 !=0) + { + if (pRec->tpro > 10) + printf(", clear-2"); + EgClearSeq(pLink, 2); + pRec->clr2 = 0; + } + + /* We use the VME event trigger as a one-shot. It is reset to zero */ + if (pRec->vme != 0) + { + if (pRec->tpro > 10) + printf(", VME-%ld", pRec->vme); + EgGenerateVmeEvent(pLink, pRec->vme); + pRec->vme = 0; + } + + /* + * If any triggers are enabled... set their values. + * Otherwise, disable the associated trigger map register. + * + * NOTE: The EG board only allows changes to the trigger codes + * when the board is disabled. Users of these triggers must disable + * them, change the trigger event code and then re-enable them to + * get them to work. + */ + if (pRec->ete0) + { + if (pRec->et0 != EgGetTrigger(pLink, 0)) + { + EgEnableTrigger(pLink, 0, 0); + EgSetTrigger(pLink, 0, pRec->et0); + pRec->let0 = pRec->et0; + } + EgEnableTrigger(pLink, 0, 1); + } + else + EgEnableTrigger(pLink, 0, 0); + + if (pRec->ete1) + { + if (pRec->et1 != EgGetTrigger(pLink, 1)) + { + EgEnableTrigger(pLink, 1, 0); + EgSetTrigger(pLink, 1, pRec->et1); + pRec->let1 = pRec->et1; + } + EgEnableTrigger(pLink, 1, 1); + } + else + EgEnableTrigger(pLink, 1, 0); + + if (pRec->ete2) + { + if (pRec->et2 != EgGetTrigger(pLink, 2)) + { + EgEnableTrigger(pLink, 2, 0); + EgSetTrigger(pLink, 2, pRec->et2); + pRec->let2 = pRec->et2; + } + EgEnableTrigger(pLink, 2, 1); + } + else + EgEnableTrigger(pLink, 2, 0); + + if (pRec->ete3) + { + if (pRec->et3 != EgGetTrigger(pLink, 3)) + { + EgEnableTrigger(pLink, 3, 0); + EgSetTrigger(pLink, 3, pRec->et3); + pRec->let3 = pRec->et3; + } + EgEnableTrigger(pLink, 3, 1); + } + else + EgEnableTrigger(pLink, 3, 0); + + if (pRec->ete4) + { + if (pRec->et4 != EgGetTrigger(pLink, 4)) + { + EgEnableTrigger(pLink, 4, 0); + EgSetTrigger(pLink, 4, pRec->et4); + pRec->let4 = pRec->et4; + } + EgEnableTrigger(pLink, 4, 1); + } + else + EgEnableTrigger(pLink, 4, 0); + + if (pRec->ete5) + { + if (pRec->et5 != EgGetTrigger(pLink, 5)) + { + EgEnableTrigger(pLink, 5, 0); + EgSetTrigger(pLink, 5, pRec->et5); + pRec->let5 = pRec->et5; + } + EgEnableTrigger(pLink, 5, 1); + } + else + EgEnableTrigger(pLink, 5, 0); + + if (pRec->ete6) + { + if (pRec->et6 != EgGetTrigger(pLink, 6)) + { + EgEnableTrigger(pLink, 6, 0); + EgSetTrigger(pLink, 6, pRec->et6); + pRec->let6 = pRec->et6; + } + EgEnableTrigger(pLink, 6, 1); + } + else + EgEnableTrigger(pLink, 6, 0); + + if (pRec->ete7) + { + if (pRec->et7 != EgGetTrigger(pLink, 7)) + { + EgEnableTrigger(pLink, 7, 0); + EgSetTrigger(pLink, 7, pRec->et7); + pRec->let7 = pRec->et7; + } + EgEnableTrigger(pLink, 7, 1); + } + else + EgEnableTrigger(pLink, 7, 0); + + /* TAXI stuff? */ + if (EgCheckTaxi(pLink) != 0) + pRec->taxi = 1; + + if (pRec->tpro > 10) + printf("\n"); + } + semGive (pLink->EgLock); + EgScheduleRamProgram(pRec->out.value.vmeio.card); + pRec->udf = 0; + return(0); +} +struct { + long number; + long (*p1)(); + long (*p2)(); + long (*p3)(); + long (*p4)(); + long (*p5)(); +} devEg={ 5, NULL, EgInitDev, EgInitEgRec, NULL, EgProcEgRec}; + +/****************************************************************************** + * + * Support for initialization of egevent records. + * + ******************************************************************************/ +STATIC long EgInitEgEventRec(struct egeventRecord *pRec) +{ + if (EgCheckCard(pRec->out.value.vmeio.card) != 0) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEg::EgInitEgEventRec() bad card number"); + return(S_db_badField); + } + + pRec->self = pRec; + pRec->lram = pRec->ram; + pRec->levt = 0; /* force program on first process */ + + /* Put the event record in the proper list */ + semTake (EgLink[pRec->out.value.vmeio.card].EgLock, WAIT_FOREVER); + if (pRec->ram == egeventRAM_RAM_2) + { + ellAdd(&(EgLink[pRec->out.value.vmeio.card].EgEvent2), &(pRec->eln)); + EgLink[pRec->out.value.vmeio.card].Ram2Dirty = 1; + } + else /* RAM_1 */ + { + ellAdd(&(EgLink[pRec->out.value.vmeio.card].EgEvent1), &(pRec->eln)); + EgLink[pRec->out.value.vmeio.card].Ram1Dirty = 1; + } + semGive(EgLink[pRec->out.value.vmeio.card].EgLock); + return(0); +} +/****************************************************************************** + * + * Process an EGEVENT record. + * + ******************************************************************************/ +STATIC long EgProcEgEventRec(struct egeventRecord *pRec) +{ + ApsEgStruct *pLink = EgLink[pRec->out.value.vmeio.card].pEg; + double RamSpeed; + + if (pRec->tpro > 10) + printf("devApsEg::EgProcEgEventRec(%s) link%d at %p\n", pRec->name, + pRec->out.value.vmeio.card, pLink); + + /* Check if the card is present */ + if (EgCheckCard(pRec->out.value.vmeio.card) != 0) + return(0); + + /* Check for ram# change */ + if (pRec->ram != pRec->lram) + { + EgLink[pRec->out.value.vmeio.card].Ram1Dirty = 1; + EgLink[pRec->out.value.vmeio.card].Ram2Dirty = 1; + + if (pRec->tpro > 10) + printf("devApsEg::EgProcEgEventRec(%s) ram-%d\n", pRec->name, pRec->ram); + + semTake (EgLink[pRec->out.value.vmeio.card].EgLock, WAIT_FOREVER); + /* Move to proper linked list */ + if (pRec->ram == egeventRAM_RAM_2) + { + ellDelete(&(EgLink[pRec->out.value.vmeio.card].EgEvent1), &(pRec->eln)); + ellAdd(&(EgLink[pRec->out.value.vmeio.card].EgEvent2), &(pRec->eln)); + } + else /* RAM_1 */ + { + ellDelete(&(EgLink[pRec->out.value.vmeio.card].EgEvent2), &(pRec->eln)); + ellAdd(&(EgLink[pRec->out.value.vmeio.card].EgEvent1), &(pRec->eln)); + } + semGive(EgLink[pRec->out.value.vmeio.card].EgLock); + pRec->lram = pRec->ram; + } + + if (pRec->ram == egeventRAM_RAM_2) + RamSpeed = EgLink[pRec->out.value.vmeio.card].Ram2Speed; + else + RamSpeed = EgLink[pRec->out.value.vmeio.card].Ram1Speed; + + if (pRec->enm != pRec->levt) + { + if (pRec->ram == egeventRAM_RAM_2) + EgLink[pRec->out.value.vmeio.card].Ram2Dirty = 1; + else + EgLink[pRec->out.value.vmeio.card].Ram1Dirty = 1; + pRec->levt = pRec->enm; + } + /* Check for time/position change */ + if (pRec->dely != pRec->ldly) + { + /* Scale delay to actual position */ + switch (pRec->unit) + { + case REC_EGEVENT_UNIT_TICKS: + pRec->dpos = pRec->dely; + break; + case REC_EGEVENT_UNIT_FORTNIGHTS: + pRec->dpos = ((float)pRec->dely * 60.0 * 60.0 * 24.0 * 14.0) * RamSpeed; + break; + case REC_EGEVENT_UNIT_WEEKS: + pRec->dpos = ((float)pRec->dely * 60.0 * 60.0 * 24.0 * 7.0) * RamSpeed; + break; + case REC_EGEVENT_UNIT_DAYS: + pRec->dpos = ((float)pRec->dely * 60.0 * 60.0 * 24.0) * RamSpeed; + break; + case REC_EGEVENT_UNIT_HOURS: + pRec->dpos = ((float)pRec->dely * 60.0 *60.0) * RamSpeed; + break; + case REC_EGEVENT_UNIT_MINUITES: + pRec->dpos = ((float)pRec->dely * 60.0) * RamSpeed; + break; + case REC_EGEVENT_UNIT_SECONDS: + pRec->dpos = pRec->dely * RamSpeed; + break; + case REC_EGEVENT_UNIT_MILLISECONDS: + pRec->dpos = ((float)pRec->dely/1000.0) * RamSpeed; + break; + case REC_EGEVENT_UNIT_MICROSECONDS: + pRec->dpos = ((float)pRec->dely/1000000.0) * RamSpeed; + break; + case REC_EGEVENT_UNIT_NANOSECONDS: + pRec->dpos = ((float)pRec->dely/1000000000.0) * RamSpeed; + break; + } + if (pRec->tpro) + printf("EgProcEgEventRec(%s) dpos=%ld\n", pRec->name, pRec->dpos); + + pRec->ldly = pRec->dely; + if (pRec->ram == egeventRAM_RAM_2) + EgLink[pRec->out.value.vmeio.card].Ram2Dirty = 1; + else + EgLink[pRec->out.value.vmeio.card].Ram1Dirty = 1; + } + EgScheduleRamProgram(pRec->out.value.vmeio.card); + return(0); +} + +struct { + long number; + long (*p1)(); + long (*p2)(); + long (*p3)(); + long (*p4)(); + long (*p5)(); +} devEgEvent={ 5, NULL, EgInitDev, EgInitEgEventRec, NULL, EgProcEgEventRec}; + +/****************************************************************************** + * + * Driver support functions. + * + * These are service routines unes to support the record init and processing + * functions above. + * + ******************************************************************************/ + +/****************************************************************************** + * + * Return the event code from the requested RAM and physical position. + * + ******************************************************************************/ +STATIC long EgGetRamEvent(EgLinkStruct *pParm, long Ram, long Addr) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + if (EgSeqEnableCheck(pParm, Ram)) /* Can't alter a running RAM */ + return(-2); + + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x0600; /* shut off auto-inc */ + if (Ram == 1) + { + pEg->Seq1Addr = Addr; + return(pEg->Seq1Data&0xff); + } + else + { + pEg->Seq2Addr = Addr; + return(pEg->Seq2Data&0xff); + } + return(-1); +} +/****************************************************************************** + * + * Program a single evnet into a single RAM position. + * + ******************************************************************************/ +STATIC long EgProgramRamEvent(EgLinkStruct *pParm, long Ram, long Addr, long Event) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + +#ifdef EG_DEBUG + printf("EgProgramRamEvent() %d, %d, %d\n", Ram, Addr, Event); +#endif + if (EgSeqEnableCheck(pParm, Ram)) /* Can't alter a running RAM */ + return(-2); + + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x0600; /* shut off auto-inc */ + if (Ram == 1) + { + pEg->Seq1Addr = Addr; + if ((pEg->Seq1Data&0xff) != 0) + { +#ifdef EG_DEBUG + printf("Seq1 data at 0x%4.4X already 0x%2.2X\n", Addr, pEg->Seq1Data&0xff); +#endif + return(-1); + } + pEg->Seq1Data = Event; + } + else + { + pEg->Seq2Addr = Addr; + if ((pEg->Seq2Data&0xff) != 0) + { +#ifdef EG_DEBUG + printf("Seq2 data at 0x%4.4X already 0x%2.2X\n", Addr, pEg->Seq2Data&0xff); +#endif + return(-1); + } + pEg->Seq2Data = Event; + } + return(0); +} + +/****************************************************************************** + * + * Return a zero if no TAXI violation status set, one otherwise. + * + ******************************************************************************/ +STATIC long EgCheckTaxi(EgLinkStruct *pParm) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + return(pEg->Control & 0x0001); +} + +/****************************************************************************** + * + * Shut down the in-bound FIFO. + * + ******************************************************************************/ +STATIC long EgDisableFifo(EgLinkStruct *pParm) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x1000; /* Disable FIFO */ + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x2001; /* Reset FIFO (plus any taxi violations) */ + + return(0); +} + +/****************************************************************************** + * + * Turn on the in-bound FIFO. + * + ******************************************************************************/ +STATIC long EgEnableFifo(EgLinkStruct *pParm) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if (pEg->Control & 0x1000) /* If enabled already, forget it */ + { + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x2001; /* Reset FIFO & taxi */ + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x1000; /* Enable the FIFO */ + } + return(0); +} + +/****************************************************************************** + * + * Return a 1 if the FIFO is enabled and a zero otherwise. + * + ******************************************************************************/ +STATIC long EgCheckFifo(EgLinkStruct *pParm) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if (pEg->Control & 0x1000) + return(0); + return(1); +} + +/****************************************************************************** + * + * Turn on the master enable. + * + ******************************************************************************/ +STATIC long EgMasterEnable(EgLinkStruct *pParm) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x8000; /* Clear the disable bit */ + return(0); +} + +/****************************************************************************** + * + * Turn off the master enable. + * + ******************************************************************************/ +STATIC long EgMasterDisable(EgLinkStruct *pParm) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x8000; /* Set the disable bit */ + return(0); +} + +/****************************************************************************** + * + * Return a one of the master enable is on, and a zero otherwise. + * + ******************************************************************************/ +STATIC long EgMasterEnableGet(EgLinkStruct *pParm) +{ + if (pParm->pEg->Control&0x8000) + return(0); + + return(1); +} + +/****************************************************************************** + * + * Clear the requested sequence RAM. + * BUG -- should have an enableCheck + * + ******************************************************************************/ +STATIC long EgClearSeq(EgLinkStruct *pParm, int channel) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if (channel == 1) + { + while(pEg->Control & 0x0014) + taskDelay(1); /* Wait for running seq to finish */ + + pEg->EventMask &= ~0x0004; /* Turn off seq 1 */ + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0004; /* Reset seq RAM address */ + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0010; /* Assert the NULL fill command */ + + /* make sure we do not set both reset event and null fill at same time */ + + while(pEg->Control & 0x0010) + taskDelay(1); /* Wait for NULL fill to complete */ + } + else if(channel == 2) + { + while(pEg->Control & 0x000a) + taskDelay(1); + + pEg->EventMask &= ~0x0002; + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0002; + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0008; + + while(pEg->Control & 0x0008) + taskDelay(1); + } + return(0); +} + +/****************************************************************************** + * + * Set the trigger event code for a given channel number. + * + ******************************************************************************/ +STATIC long EgSetTrigger(EgLinkStruct *pParm, unsigned int Channel, unsigned short Event) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + volatile unsigned short *pShort; + + if(Channel > 7) + return(-1); + + pShort = &(pEg->Event0Map); + pShort[Channel] = Event; + + return(0); +} + +/****************************************************************************** + * + * Return the event code for the requested trigger channel. + * + ******************************************************************************/ +STATIC long EgGetTrigger(EgLinkStruct *pParm, unsigned int Channel) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if(Channel > 7) + return(0); + return(((unsigned short *)(&(pEg->Event0Map)))[Channel]); +} + +/****************************************************************************** + * + * Enable or disable event triggering for a given Channel. + * + ******************************************************************************/ +STATIC long EgEnableTrigger(EgLinkStruct *pParm, unsigned int Channel, int state) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + unsigned short j; + + if (Channel > 7) + return(-1); + + j = 0x08; + j <<= Channel; + + if (state) + pEg->EventMask |= j; + else + pEg->EventMask &= ~j; + + return(0); +} +STATIC long EgGetEnableTrigger(EgLinkStruct *pParm, unsigned int Channel) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + unsigned short j; + + if (Channel > 7) + return(0); + + j = 0x08; + j <<= Channel; + + return(pEg->EventMask & j ?1:0); +} +/****************************************************************************** + * + * Return a one if the request RAM is enabled or a zero otherwise. + * We use this function to make sure the RAM is disabled before we access it. + * + ******************************************************************************/ +STATIC int EgSeqEnableCheck(EgLinkStruct *pParm, unsigned int Seq) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if (Seq == 1) + return(pEg->EventMask & 0x0004); + return(pEg->EventMask & 0x0002); +} + +/****************************************************************************** + * + * This routine does a manual trigger of the requested SEQ RAM. + * + ******************************************************************************/ +STATIC long EgSeqTrigger(EgLinkStruct *pParm, unsigned int Seq) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if (Seq == 1) + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0100; + else if (Seq == 2) + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0080; + else + return(-1); + + return(0); +} +/****************************************************************************** + * + * Select mode of Sequence RAM operation. + * + * OFF: + * Stop the generation of all events from sequence RAMs. + * NORMAL: + * Set to cycle on every trigger. + * NORMAL_RECYCLE: + * Set to continuous run on first trigger. + * SINGLE: + * Set to disable self on an END event. + * ALTERNATE: + * Use one ram at a time, but use both to allow seamless modifications + * + ******************************************************************************/ +STATIC long EgSetSeqMode(EgLinkStruct *pParm, unsigned int Seq, int Mode) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + /* Stop and disable the sequence RAMs */ + if (Mode == egMOD1_Alternate) + { + pEg->EventMask &= ~0x3006; /* Disable *BOTH* RAMs */ + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x0066; + while(pEg->Control & 0x0006) + taskDelay(1); /* Wait until finish running */ + } + else if (Seq == 1) + { + pEg->EventMask &= ~0x2004; /* Disable SEQ 1 */ + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x0044; + while(pEg->Control & 0x0004) + taskDelay(1); /* Wait until finish running */ + pEg->EventMask &= ~0x0800; /* Kill ALT mode */ + } + else if (Seq == 2) + { + pEg->EventMask &= ~0x1002; /* Disable SEQ 2 */ + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x0022; + while(pEg->Control & 0x0002) + taskDelay(1); /* Wait until finish running */ + pEg->EventMask &= ~0x0800; /* Kill ALT mode */ + } + else + return(-1); + + switch (Mode) + { + case egMOD1_Off: + break; + + case egMOD1_Normal: + if (Seq == 1) + pEg->EventMask |= 0x0004; /* Enable Seq RAM 1 */ + else + pEg->EventMask |= 0x0002; /* Enable Seq RAM 2 */ + break; + + case egMOD1_Normal_Recycle: + if (Seq == 1) + { + pEg->EventMask |= 0x0004; /* Enable Seq RAM 1 */ + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0040; /* Set Seq 1 recycle */ + } + else + { + pEg->EventMask |= 0x0002; + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0020; + } + break; + + case egMOD1_Single: + if (Seq == 1) + pEg->EventMask |= 0x2004; /* Enable Seq RAM 1 in single mode */ + else + pEg->EventMask |= 0x1002; + break; + + case egMOD1_Alternate: /* The ram downloader does all the work */ + pEg->EventMask |= 0x0800; /* turn on the ALT mode bit */ + break; + + default: + return(-1); + } + return(-1); +} + +/****************************************************************************** + * + * Check to see if a sequence ram is currently running + * + ******************************************************************************/ +STATIC long EgGetBusyStatus(EgLinkStruct *pParm, int Ram) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if (Ram == 1) + { + if (pEg->Control & 0x0004) + return(1); + return(0); + } + if (pEg->Control & 0x0002) + return(1); + return(0); +} +/****************************************************************************** + * + * Ram is assumed to be in ALT mode, check to see if the requested RAM is + * available for downloading (Not enabled and idle.) + * + * Returns zero if RAM is available or nonzero otherwise. + * + ******************************************************************************/ +STATIC long EgGetAltStatus(EgLinkStruct *pParm, int Ram) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if (EgGetBusyStatus(pParm, Ram) != 0) + return(1); + + if (Ram == 1) + { + if (pEg->EventMask & 0x0004) + return(1); + } + else + { + if (pEg->EventMask & 0x0002) + return(1); + } + return(0); +} +/****************************************************************************** + * + * Return the operating mode of the requested sequence RAM. + * + ******************************************************************************/ +STATIC long EgGetMode(EgLinkStruct *pParm, int Ram) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + unsigned short Mask; + unsigned short Control; + + Mask = pEg->EventMask & 0x3806; + Control = pEg->Control & 0x0060; + + if (Mask & 0x0800) + return(egMOD1_Alternate); + + if (Ram == 1) + { + Mask &= 0x2004; + Control &= 0x0040; + + if ((Mask == 0) && (Control == 0)) + return(egMOD1_Off); + if ((Mask == 0x0004) && (Control == 0)) + return(egMOD1_Normal); + if ((Mask == 0x0004) && (Control == 0x0040)) + return(egMOD1_Normal_Recycle); + if (Mask & 0x2000) + return(egMOD1_Single); + } + else + { + Mask &= 0x1002; + Control &= 0x0020; + + if ((Mask == 0) && (Control == 0)) + return(egMOD1_Off); + if ((Mask == 0x0002) && (Control == 0)) + return(egMOD1_Normal); + if ((Mask == 0x0002) && (Control == 0x0020)) + return(egMOD1_Normal_Recycle); + if (Mask & 0x1000) + return(egMOD1_Single); + } + printf("EgGetMode() seqence RAM in invalid state %4.4X %4.4X\n", pEg->Control, pEg->EventMask); + return(-1); +} + +STATIC long EgEnableAltRam(EgLinkStruct *pParm, int Ram) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + unsigned short Mask = pEg->EventMask; + if (Ram == 1) + pEg->EventMask = (Mask & ~0x0002)|0x0004; + else + pEg->EventMask = (Mask & ~0x0004)|0x0002; + return(0); +} +/****************************************************************************** + * + * Enable or disable the generation of VME events. + * + ******************************************************************************/ +STATIC long EgEnableVme(EgLinkStruct *pParm, int state) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + if (state) + pEg->EventMask |= 0x0001; + else + pEg->EventMask &= ~0x0001; + + return(0); +} + +/****************************************************************************** + * + * Send the given event code out now. + * + ******************************************************************************/ +STATIC long EgGenerateVmeEvent(EgLinkStruct *pParm, int Event) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + pEg->VmeEvent = Event; + return(0); +} +/****************************************************************************** + * + * Disable and clear everything on the Event Generator + * + ******************************************************************************/ +STATIC long EgResetAll(EgLinkStruct *pParm) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + pEg->Control = 0x8000; /* Disable all local event generation */ + pEg->EventMask = 0; /* Disable all local event generation */ + + EgDisableFifo(pParm); + + EgClearSeq(pParm, 1); + EgClearSeq(pParm, 2); + + EgSetTrigger(pParm, 0, 0); /* Clear all trigger event numbers */ + EgSetTrigger(pParm, 1, 0); + EgSetTrigger(pParm, 2, 0); + EgSetTrigger(pParm, 3, 0); + EgSetTrigger(pParm, 4, 0); + EgSetTrigger(pParm, 5, 0); + EgSetTrigger(pParm, 6, 0); + EgSetTrigger(pParm, 7, 0); + + EgEnableVme(pParm, 1); /* There is no reason to disable VME events */ + + return(0); +} + +/****************************************************************************** + * + * Read the requested sequence RAM into the buffer passed in. + * + ******************************************************************************/ +STATIC int EgReadSeqRam(EgLinkStruct *pParm, int channel, unsigned char *pBuf) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + volatile unsigned short *pSeqData; + int j; + + if (EgSeqEnableCheck(pParm, channel)) + { + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x0600; + return(-1); + } + if (channel == 1) + { + pSeqData = &pEg->Seq1Data; + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0404; /* Auto inc the address */ + pEg->Seq1Addr = 0; + } + else if (channel == 2) + { + pSeqData = &pEg->Seq2Data; + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0202; /* Auto inc the address */ + pEg->Seq2Addr = 0; + } + else + return(-1); + + for(j=0;jControl = (pEg->Control&CTL_OR_MASK)&~0x0600; /* kill the auto-inc */ + + if (channel == 1) + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0004; + else + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0002; + + return(0); +} + +/****************************************************************************** + * + * Program the requested sequence RAM from the buffer passed in. + * + ******************************************************************************/ +STATIC int EgWriteSeqRam(EgLinkStruct *pParm, int channel, unsigned char *pBuf) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + volatile unsigned short *pSeqData; + int j; + + if (EgSeqEnableCheck(pParm, channel)) + { + pEg->Control = (pEg->Control&CTL_OR_MASK)&~0x0600; /* kill the auto-inc */ + return(-1); + } + + if (channel == 1) + { + pSeqData = &pEg->Seq1Data; + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0404; /* Auto inc the address */ + pEg->Seq1Addr = 0; + } + else if (channel == 2) + { + pSeqData = &pEg->Seq2Data; + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0202; /* Auto inc the address */ + pEg->Seq2Addr = 0; + } + else + return(-1); + +#ifdef EG_DEBUG + printf("ready to download ram\n"); +#endif + taskDelay(20); + for(j=0;jControl = (pEg->Control&CTL_OR_MASK)&~0x0600; /* kill the auto-inc */ + + if (channel == 1) /* reset the config'd channel */ + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0004; + else + pEg->Control = (pEg->Control&CTL_OR_MASK)|0x0002; + +#ifdef EG_DEBUG + printf("sequence ram downloaded\n"); +#endif + taskDelay(20); + return(0); +} + +/******************************************************************************/ +/******************************************************************************/ +/****************************************************************************** + * + * The following section is a console-run test program for the event generator + * card. It is crude, but it works. + * + ******************************************************************************/ +#ifdef EG_MONITOR + +STATIC unsigned char TestRamBuf[EG_SEQ_RAM_SIZE]; + +STATIC int EgDumpRegs(EgLinkStruct *pParm) +{ + volatile ApsEgStruct *pEg = pParm->pEg; + + printf("Control = %4.4X, Event Mask = %4.4X\n", pEg->Control, pEg->EventMask); + return(0); +} +STATIC int SetupSeqRam(EgLinkStruct *pParm, int channel) +{ + int j; + + if (EgSeqEnableCheck(pParm, channel)) + { + printf("Sequence ram %d is enabled, can not reconfigure\n", channel); + return(-1); + } + + for(j=0; j<=20; j++) + TestRamBuf[j] = 100-j; + + TestRamBuf[j] = EG_SEQ_RAM_EVENT_END; + + j++; + + for(;j +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +#ifdef ER_DEBUG +#define STATIC +#else +#define STATIC static +#endif + +typedef struct ApsErStruct +{ + unsigned short Control; + unsigned short EventRamAddr; + unsigned short EventRamData; + unsigned short OutputPulseEnables; + unsigned short OutputLevelEnables; + unsigned short TriggerEventEnables; + unsigned short EventCounterLo; + unsigned short EventCounterHi; + unsigned short TimeStampLo; + unsigned short TimeStampHi; + + unsigned short EventFifo; + unsigned short EventTimeHi; + unsigned short DelayPulseEnables; + unsigned short DelayPulseSelect; + unsigned short PulseDelay; + unsigned short PulseWidth; + unsigned short IrqVector; + unsigned short IrqEnables; + +} ApsErStruct; + + +/* + * CONTROL_REG_OR_STRIP = bits that we should never leave set when or-ing + * on other bits in the control register. + */ +#define CONTROL_REG_OR_STRIP (~0x3c9f) + +#define NUM_EVENTS 256 + +#define ER_IRQ_ALL 0x000f +#define ER_IRQ_OFF 0x0000 +#define ER_IRQ_TELL 0xffff +#define ER_IRQ_EVENT 0x0008 +#define ER_IRQ_HEART 0x0004 +#define ER_IRQ_FIFO 0x0002 +#define ER_IRQ_TAXI 0x0001 + +typedef struct ErLinkStruct +{ + struct erRecord *pRec; + int Card; + long IrqVector; + long IrqLevel; + ApsErStruct *pEr; + SEM_ID LinkLock; /* Lock for the card */ + unsigned short ErEventTab[NUM_EVENTS]; /* current view of the RAM */ + IOSCANPVT IoScanPvt[NUM_EVENTS]; /* event-based rec processing */ + EVENT_FUNC EventFunc; + ERROR_FUNC ErrorFunc; +} ErLinkStruct; + +#define NUM_ER_LINKS 4 +static int ErNumLinks = 0; /* User configurable link limit */ +static int ConfigureLock = 0; +STATIC ErLinkStruct ErLink[NUM_ER_LINKS]; +int ErDebug = 0; + +int ErStallIrqs = 1; + +STATIC long ErMasterEnableGet(ApsErStruct *pParm); +STATIC long ErMasterEnableSet(ApsErStruct *pParm, int Enable); +STATIC long ErSetTrg(ApsErStruct *pParm, int Channel, int Enable); +STATIC long ErSetOtp(ApsErStruct *pParm, int Channel, int Enable); +STATIC long ErSetOtl(ApsErStruct *pParm, int Channel, int Enable); +STATIC long ErSetDg(ApsErStruct *pParm, int Channel, int Enable, unsigned short Delay, unsigned short Width); +STATIC unsigned short ErEnableIrq(ApsErStruct *pParm, unsigned short Mask); +STATIC int ErRegisterIrq(ErLinkStruct *pLink, int IrqVector, int IrqLevel); +STATIC long ErCheckTaxi(ApsErStruct *pParm); +STATIC int ErGetRamStatus(ApsErStruct *pParm, int Ram); +STATIC int ErResetAll(ApsErStruct *pParm); +STATIC int ErUpdateRam(ApsErStruct *pParm, unsigned short *RamBuf); +STATIC int ErProgramRam(ApsErStruct *pParm, unsigned short *RamBuf, int Ram); +STATIC int ErEnableRam(ApsErStruct *pParm, int Ram); +STATIC long proc(struct erRecord *pRec); + +/****************************************************************************** + * + * Routine used to verify that a given card number is valid. + * Returns zero if valid, nonzero otherwise. + * + ******************************************************************************/ +long ErHaveReceiver(int Card) +{ + if ((Card < 0)||(Card >= ErNumLinks)) + return(-1); + if (ErLink[Card].pEr == NULL) + return(-1); + return(256); /* Return the number of possible event codes, 0-255 */ +} +/****************************************************************************** + * + * Register a listener for the event system. Every time we get an event from + * the event receiver, we will call the registered listener and pass in the + * event number received and the tick counter value when that event was + * received. + * + ******************************************************************************/ +long ErRegisterEventHandler(int Card, EVENT_FUNC func) +{ + if (ErDebug) + printf("ErRegisterEventHandler(%d, %p\n", Card, func); + + ErLink[Card].EventFunc = func; + return(0); +} +/****************************************************************************** + * + * Register a listener for the event system. Every time we get an event from + * the event receiver, we will call the registered listener and pass in the + * event number received and the tick counter value when that event was + * received. + * + ******************************************************************************/ +long ErRegisterErrorHandler(int Card, ERROR_FUNC func) +{ + if (ErDebug) + printf("ErRegisterEventHandler(%d, %p\n", Card, func); + + ErLink[Card].ErrorFunc = func; + return(0); +} +/****************************************************************************** + * + * Return the current tick counter value. + * + ******************************************************************************/ +long ErGetTicks(int Card, unsigned long *Ticks) +{ + if (ErHaveReceiver(Card) < 0) + return(-1); + + /* BUG -- Do we read the HI first or the low? */ + + *Ticks = ErLink[Card].pEr->EventCounterLo; + *Ticks += ErLink[Card].pEr->EventCounterHi << 16; + + return(0); +} + +/****************************************************************************** + * + * This routine is to be called in the startup script in order to init the + * card addresses and the associated IRQ vectors and levels. + * + * By default there are no cards configured. + * + ******************************************************************************/ +int ErConfigure(int Card, unsigned long CardAddress, unsigned int IrqVector, unsigned int IrqLevel) +{ + short Junk; + + if (ConfigureLock != 0) + { + epicsPrintf("devApsEr: Cannot change configuration after init. Request ignored\n"); + return(-1); + } + if (Card >= NUM_ER_LINKS) + { + epicsPrintf("devApsEr: Card number invalid, must be 0-%d\n", NUM_ER_LINKS); + return(-1); + } + if (CardAddress > 0xffff) + { + epicsPrintf("devApsEr: Card address invalid, must be 0x0000-0xffff\n"); + return(-1); + } + if(sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, (char*)CardAddress, (char**)&ErLink[Card].pEr)!=OK) + { + epicsPrintf("devApsEr: Failure mapping requested A16 address\n"); + ErLink[Card].pEr = NULL; + return(-1); + } + if (vxMemProbe((char*)&ErLink[Card].pEr->Control, READ, sizeof(short), (char*)&Junk) != OK) + { + epicsPrintf("devApsEr: Failure probing for event receiver... Card disabled\n"); + ErLink[Card].pEr = NULL; + return(-1); + } + ErLink[Card].IrqVector = IrqVector; + ErLink[Card].IrqLevel = IrqLevel; + + if (Card >= ErNumLinks) + ErNumLinks = Card+1; + + return(0); +} +/****************************************************************************** + * + * A function to shut up an event receiver in case we get a ^X style reboot. + * + ******************************************************************************/ +static void ErRebootFunc(void) +{ + int j = 0; + + while (j < ErNumLinks) + { + if (ErLink[j].pEr != NULL) + ErEnableIrq(ErLink[j].pEr, ER_IRQ_OFF); + ++j; + } + return; +} +/****************************************************************************** + * + * Register and init the IRQ handlers for each ER card. + * + ******************************************************************************/ +STATIC long ErInitDev(int pass) +{ + int j; + int k; + static int OneShotFlag = 1; + + if (ErDebug) + printf("ErInitDev(%d)\n", pass); + + if (OneShotFlag) + { + OneShotFlag = 0; + rebootHookAdd((FUNCPTR)ErRebootFunc); + + ConfigureLock = 1; /* Prevent any future ErConfigure's */ + + /* Clear the record pointers */ + for (j=0;j= 0) + { + if ((ErLink[j].LinkLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL)) == NULL) + return(-1); + for (k=0;k<256;k++) + { + ErLink[j].Card = j; + ErLink[j].ErEventTab[k] = 0; + /* ErLink[j].EventFunc = NULL; Should be NULL because is static */ + /* ErLink[j].ErrorFunc = NULL; */ + scanIoInit(&ErLink[j].IoScanPvt[k]); + } + ErLink[j].pRec = NULL; + ErResetAll(ErLink[j].pEr); + ErRegisterIrq(&ErLink[j], ErLink[j].IrqVector, ErLink[j].IrqLevel); + } + } + } + if (pass == 1) + { + for (j=0;j= 0) + ErEnableIrq(ErLink[j].pEr, ER_IRQ_ALL); + } + return(0); +} +#if 0 +scum() +{ + int j; + + for (j=0;j= 0) + ErEnableIrq(ErLink[j].pEr, ER_IRQ_ALL); +} +#endif +/****************************************************************************** + * + * Init routine for the ER record type. + * + ******************************************************************************/ +STATIC long init_record(struct erRecord *pRec) +{ + ErLinkStruct *pLink; + + if (ErDebug) + printf("devApsEr::init_record() entered\n"); + + if (ErHaveReceiver(pRec->out.value.vmeio.card) < 0) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEr::ErInitErRec() Invalid card number"); + return(S_db_badField); + } + pLink = &ErLink[pRec->out.value.vmeio.card]; + + /* Make sure we only have one record for a given ER card */ + if (pLink->pRec != NULL) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEr::ErInitErRec() onlyone record allowed per card"); + return(S_db_badField); + } + pLink->pRec = pRec; + + proc(pRec); + + return(0); +} +/****************************************************************************** + * + * Process routine for the ER record type. + * + ******************************************************************************/ +STATIC long proc(struct erRecord *pRec) +{ + ErLinkStruct *pLink = &ErLink[pRec->out.value.vmeio.card]; + + if (pRec->tpro > 10) + printf("devApsEr::proc(%s) entered\n", pRec->name); + + /* Make sure the card is present */ + if (ErHaveReceiver(pRec->out.value.vmeio.card) < 0) + return(0); + + semTake(pLink->LinkLock, WAIT_FOREVER); + + if (pRec->enab != ErMasterEnableGet(pLink->pEr)) + ErMasterEnableSet(pLink->pEr, pRec->enab); + + ErSetTrg(pLink->pEr, 0, pRec->trg0); + ErSetTrg(pLink->pEr, 1, pRec->trg1); + ErSetTrg(pLink->pEr, 2, pRec->trg2); + ErSetTrg(pLink->pEr, 3, pRec->trg3); + ErSetTrg(pLink->pEr, 4, pRec->trg4); + ErSetTrg(pLink->pEr, 5, pRec->trg5); + ErSetTrg(pLink->pEr, 6, pRec->trg6); + + ErSetOtp(pLink->pEr, 0, pRec->otp0); + ErSetOtp(pLink->pEr, 1, pRec->otp1); + ErSetOtp(pLink->pEr, 2, pRec->otp2); + ErSetOtp(pLink->pEr, 3, pRec->otp3); + ErSetOtp(pLink->pEr, 4, pRec->otp4); + ErSetOtp(pLink->pEr, 5, pRec->otp5); + ErSetOtp(pLink->pEr, 6, pRec->otp6); + ErSetOtp(pLink->pEr, 7, pRec->otp7); + ErSetOtp(pLink->pEr, 8, pRec->otp8); + ErSetOtp(pLink->pEr, 9, pRec->otp9); + ErSetOtp(pLink->pEr, 10, pRec->otpa); + ErSetOtp(pLink->pEr, 11, pRec->otpb); + ErSetOtp(pLink->pEr, 12, pRec->otpc); + ErSetOtp(pLink->pEr, 13, pRec->otpd); + + ErSetOtl(pLink->pEr, 0, pRec->otl0); + ErSetOtl(pLink->pEr, 1, pRec->otl1); + ErSetOtl(pLink->pEr, 2, pRec->otl2); + ErSetOtl(pLink->pEr, 3, pRec->otl3); + ErSetOtl(pLink->pEr, 4, pRec->otl4); + ErSetOtl(pLink->pEr, 5, pRec->otl5); + ErSetOtl(pLink->pEr, 6, pRec->otl6); + + ErSetDg(pLink->pEr, 0, pRec->dg0e, pRec->dg0d, pRec->dg0w); + ErSetDg(pLink->pEr, 1, pRec->dg1e, pRec->dg1d, pRec->dg1w); + ErSetDg(pLink->pEr, 2, pRec->dg2e, pRec->dg2d, pRec->dg2w); + ErSetDg(pLink->pEr, 3, pRec->dg3e, pRec->dg3d, pRec->dg3w); + + if (ErCheckTaxi(pLink->pEr) != 0) + pRec->taxi = 1; + else + pRec->taxi = 0; + + semGive(pLink->LinkLock); + + pRec->udf = 0; + return(0); +} +ErDsetStruct devEr={ 5, NULL, ErInitDev, init_record, NULL, proc}; + +/****************************************************************************** + * + * Init routine for the EREVENT record type. + * + ******************************************************************************/ +STATIC long ErEventInitRec(struct ereventRecord *pRec) +{ + if (ErDebug) + printf("ErEventInitRec(%s)\n", pRec->name); + + if (ErHaveReceiver(pRec->out.value.vmeio.card) < 0) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEr::ErEventInitRec() invalid card number in INP field"); + return(S_db_badField); + } + if ((pRec->out.value.vmeio.signal < 0)||(pRec->out.value.vmeio.signal > 255)) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEr::ErEventInitRec() invalid signal number in INP field"); + return(S_db_badField); + } + + pRec->lenm = 300; /* Force setting on first process */ + pRec->lout = 0; /* Clear the 'last' event mask */ + return(0); +} +/****************************************************************************** + * + * Process routine for the EREVENT record type. + * + ******************************************************************************/ +STATIC long ErEventProc(struct ereventRecord *pRec) +{ + ErLinkStruct *pLink = &ErLink[pRec->out.value.vmeio.card]; + int DownLoadRam = 0; + unsigned short Mask; + + if (pRec->tpro > 10) + printf("ErEventProc(%s) entered\n", pRec->name); + + /* Make sure the card is present */ + if (ErHaveReceiver(pRec->out.value.vmeio.card) < 0) + return(0); + + if (pRec->enab != 0) + { + if (pRec->tpro > 10) + printf("ErEventProc(%s) enable=true\n", pRec->name); + + semTake(pLink->LinkLock, WAIT_FOREVER); + if (pRec->enm != pRec->lenm) + { + if (pRec->tpro > 10) + printf("ErEventProc(%s) event number changed %ld-%ld\n", pRec->name, pRec->lenm, pRec->enm); + /* Transfer the event info to new position */ + if ((pRec->lenm < 256) && (pRec->lenm >= 0)) + pLink->ErEventTab[pRec->lenm] = 0; + + DownLoadRam = 1; + pRec->lenm = pRec->enm; + } + /* Build event mask */ + /* NOTE: that we never latch the time in the 32 bit latch */ + + Mask = 0; + if (pRec->out0 != 0) Mask |= 0x0001; + if (pRec->out1 != 0) Mask |= 0x0002; + if (pRec->out2 != 0) Mask |= 0x0004; + if (pRec->out3 != 0) Mask |= 0x0008; + if (pRec->out4 != 0) Mask |= 0x0010; + if (pRec->out5 != 0) Mask |= 0x0020; + if (pRec->out6 != 0) Mask |= 0x0040; + if (pRec->out7 != 0) Mask |= 0x0080; + if (pRec->out8 != 0) Mask |= 0x0100; + if (pRec->out9 != 0) Mask |= 0x0200; + if (pRec->outa != 0) Mask |= 0x0400; + if (pRec->outb != 0) Mask |= 0x0800; + if (pRec->outc != 0) Mask |= 0x1000; + if (pRec->outd != 0) Mask |= 0x2000; + if (pRec->vme != 0) Mask |= 0x8000; + + if (pRec->tpro > 10) + printf("ErEventProc(%s) New RAM mask is 0x%4.4X\n", pRec->name, Mask); + if (Mask != pRec->lout) + DownLoadRam = 1; + + if (DownLoadRam != 0) + { + if (pRec->enm != 0) + { + pLink->ErEventTab[pRec->enm] = Mask; + pRec->lout = Mask; + } + ErUpdateRam(pLink->pEr, pLink->ErEventTab); + } + if (pRec->tpro > 10) + printf("ErEventProc(%s) I/O operations complete\n", pRec->name); + semGive(pLink->LinkLock); + } + else + { + /* BUG kill event if was ever enabled! */ + } + + return(0); +} +ErDsetStruct devErevent={ 5, NULL, NULL, ErEventInitRec, NULL, ErEventProc}; +/****************************************************************************** + * + * Routine to initialize an event record. This is a regular EPICS event + * record!! Not an ER or EG event record. We allow the user to use the + * regular epics event records to request processing on an event that is + * received from the event receiver. + * + * All we gotta do here is set the dpvt field to point to the proper + * IOSCANEVENT field so that we can later return it on getIoScanInfo() calls. + * + ******************************************************************************/ +STATIC long ErEpicsEventInit(struct eventRecord *pRec) +{ + pRec->dpvt = NULL; /* In case problems arise below */ + + if(ErDebug) + printf("ErEpicsEventInit(%s) %d %d\n", pRec->name, pRec->inp.value.vmeio.card, pRec->inp.value.vmeio.signal); + + if (ErHaveReceiver(pRec->inp.value.vmeio.card) < 0) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEr::ErEventInitRec() invalid card number in INP field"); + return(S_db_badField); + } + if ((pRec->inp.value.vmeio.signal < 0)||(pRec->inp.value.vmeio.signal > 255)) + { + recGblRecordError(S_db_badField, (void *)pRec, "devApsEr::ErEventInitRec() invalid signal number in INP field"); + return(S_db_badField); + } + + pRec->dpvt = &ErLink[pRec->inp.value.vmeio.card].IoScanPvt[pRec->inp.value.vmeio.signal]; + return(0); +} +/****************************************************************************** + * + * Routine to get the IOSCANPVT value for an EVENT record type. + * + ******************************************************************************/ +STATIC long ErEpicsEventGetIoScan(int cmd, struct eventRecord *pRec, IOSCANPVT *pPvt) +{ + *pPvt = *((IOSCANPVT*)(pRec->dpvt)); + return(0); +} +ErDsetStruct devErEpicsEvent={5, NULL, NULL, ErEpicsEventInit, ErEpicsEventGetIoScan, NULL}; + +/****************************************************************************** + * + * Inquire as to if the card is enabled or not. + * + ******************************************************************************/ +STATIC long ErMasterEnableGet(ApsErStruct *pParm) +{ + volatile ApsErStruct *pEr = pParm; + return((pEr->Control & 0x8000) != 0); +} +/****************************************************************************** + * + * Enable/disable the card. + * + ******************************************************************************/ +STATIC long ErMasterEnableSet(ApsErStruct *pParm, int Enable) +{ + volatile ApsErStruct *pEr = pParm; + + if (Enable != 0) + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x8000; + else + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)&~0x8000; + return(0); +} +/****************************************************************************** + * + * Check to see if we have a taxi violation and reset it if so. + * + ******************************************************************************/ +STATIC long ErCheckTaxi(ApsErStruct *pParm) +{ + volatile ApsErStruct *pEr = pParm; + + if (pEr->Control & 0x0001) + { + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x0001; + return(1); + } + return(0); +} +/****************************************************************************** + * + * Set/clear an enable bit in the trigger mask. + * + ******************************************************************************/ +STATIC long ErSetTrg(ApsErStruct *pParm, int Channel, int Enable) +{ + volatile ApsErStruct *pEr = pParm; + unsigned short mask; + + mask = 1; + mask <<= Channel; + + if (Enable != 0) + pEr->TriggerEventEnables |= mask; + else + pEr->TriggerEventEnables &= ~mask; + return(0); +} +/****************************************************************************** + * + * Set/clear an enable bit in the one-shot mask. + * + ******************************************************************************/ +STATIC long ErSetOtp(ApsErStruct *pParm, int Channel, int Enable) +{ + volatile ApsErStruct *pEr = pParm; + unsigned short mask; + + mask = 1; + mask <<= Channel; + + if (Enable != 0) + pEr->OutputPulseEnables |= mask; + else + pEr->OutputPulseEnables &= ~mask; + return(0); +} +/****************************************************************************** + * + * Set/clear an enable bit in the level-trigger mask. + * + ******************************************************************************/ +STATIC long ErSetOtl(ApsErStruct *pParm, int Channel, int Enable) +{ + volatile ApsErStruct *pEr = pParm; + unsigned short mask; + + mask = 1; + mask <<= Channel; + + if (Enable != 0) + pEr->OutputLevelEnables |= mask; + else + pEr->OutputLevelEnables &= ~mask; + return(0); +} +/****************************************************************************** + * + * Set/clear an enable bit in the programmable pulse delay mask. If enabling + * a channel, the delay and width are also set. + * + ******************************************************************************/ +STATIC long ErSetDg(ApsErStruct *pParm, int Channel, int Enable, unsigned short Delay, unsigned short Width) +{ + volatile ApsErStruct *pEr = pParm; + unsigned short mask; + + mask = 1; + mask <<= Channel; + + if (Enable != 0) + { + pEr->DelayPulseSelect = Channel; + pEr->PulseDelay = Delay; + pEr->PulseWidth = Width; + pEr->DelayPulseEnables |= mask; + } + else + pEr->DelayPulseEnables &= ~mask; + return(0); +} +/****************************************************************************** + * + * A debugging aid that dumps out all the regs on the ER board. + * + ******************************************************************************/ +STATIC int ErDumpRegs(ApsErStruct *pParm) +{ + volatile ApsErStruct *pEr = pParm; + + printf("%4.4X %4.4X %4.4X %4.4X %4.4X %4.4X %4.4X %4.4X %4.4X %4.4X\n", + pEr->Control, pEr->EventRamAddr, pEr->EventRamData, pEr->OutputPulseEnables, + pEr->OutputLevelEnables, pEr->TriggerEventEnables, pEr->EventCounterLo, + pEr->EventCounterHi, pEr->TimeStampLo, pEr->TimeStampHi); + + printf("%4.4X %4.4X %4.4X %4.4X %4.4X %4.4X %4.4X %4.4X\n", + pEr->EventFifo, pEr->EventTimeHi, pEr->DelayPulseEnables, pEr->DelayPulseSelect, + pEr->PulseDelay, pEr->PulseWidth, pEr->IrqVector, pEr->IrqEnables); + + return(0); +} + +/****************************************************************************** + * + * Reset, clear and disable everything on the board. + * + ******************************************************************************/ +STATIC int ErResetAll(ApsErStruct *pParm) +{ + volatile ApsErStruct *pEr = pParm; + + pEr->Control = 0x201d; + pEr->Control = 0x208d; + + while(pEr->Control & 0x0080) + taskDelay(1); + + pEr->OutputPulseEnables = 0; + pEr->OutputLevelEnables = 0; + pEr->DelayPulseEnables = 0; + pEr->DelayPulseSelect = 0; + pEr->IrqEnables = 0; + + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x8000; + + return(0); +} +/****************************************************************************** + * + * Receive a hardware IRQ from an ER board. + * + * BUG -- should add errMessage calls for problem events & include storm + * control on them. + * + ******************************************************************************/ +STATIC void ErIrqHandler(ErLinkStruct *pLink) +{ + volatile ApsErStruct *pEr = pLink->pEr; + unsigned short mask; + unsigned short j; + unsigned short k; + short z; + unsigned long Time; + + mask = pEr->Control; + if(ErDebug > 9) + epicsPrintf("ErIrqHandler() control =%4.4X\n", mask); + + if (mask&0x1000) + { /* Got a lost heart beat */ + pEr->Control = (mask&CONTROL_REG_OR_STRIP)|0x1000; + + if (pLink->ErrorFunc != NULL) + (*pLink->ErrorFunc)(pLink->Card, ERROR_HEART); + + if(ErDebug) + epicsPrintf("ErIrqHandler() lost heart beat\n"); + } + + /* Read any stuff from the FIFO */ + if (mask&0x0800) + { + pEr->Control = (mask&CONTROL_REG_OR_STRIP)|0x0800; + if(ErDebug > 10) + epicsPrintf("ErIrqHandler() clearing event with %4.4X\n", (mask&CONTROL_REG_OR_STRIP)|0x0800); + + z = 10; /* Make sure we don't get into a major spin loop */ + while ((pEr->Control & 0x0002)&&(--z > 0)) + { + unsigned short EventNum; + + j = pEr->EventFifo; + k = pEr->EventTimeHi; + + /* Mark the event time in the proper array place */ + EventNum = j & 0x00ff; + Time = (k<<8)|(j>>8); + + if (pLink->EventFunc != NULL) + { + (*pLink->EventFunc)(pLink->Card, EventNum, Time); + if(ErDebug) + epicsPrintf("ErIrqHandler() Calling %p", pLink->EventFunc); + } + + if(ErDebug) + epicsPrintf("ErIrqHandler() %6.6X-%2.2X\n", Time, EventNum); + + /* Schedule processing for any event-driven records */ + scanIoRequest(pLink->IoScanPvt[EventNum]); + } + } + /* Kill any fifo overflow status */ + if (mask&0x0004) + { + pEr->Control = (mask&CONTROL_REG_OR_STRIP)|0x0004; + + if (pLink->ErrorFunc != NULL) + (*pLink->ErrorFunc)(pLink->Card, ERROR_LOST); + + if(ErDebug) + epicsPrintf("ErIrqHandler() FIFO overflow %4.4X\n", (mask&CONTROL_REG_OR_STRIP)|0x0004); + } + if (mask&0x0001) + { + pEr->Control = (mask&CONTROL_REG_OR_STRIP)|0x0001; + + if (pLink->ErrorFunc != NULL) + (*pLink->ErrorFunc)(pLink->Card, ERROR_TAXI); + + if(ErDebug) + epicsPrintf("ErIrqHandler() taxi violation %4.4X\n", pEr->Control = (mask&CONTROL_REG_OR_STRIP)|0x0001); + } + /* + * Disable and then re-enable the IRQs so board re-issues any + * that are still pending + */ + + pEr->Control = (mask&CONTROL_REG_OR_STRIP)&~0x4000; + pEr->Control = (mask&CONTROL_REG_OR_STRIP)| 0x4000; + + return; +} + +/****************************************************************************** + * + * Set up the IRQs for the receiver. + * (Should only be called once.) + * + ******************************************************************************/ +STATIC int ErRegisterIrq(ErLinkStruct *pLink, int IrqVector, int IrqLevel) +{ + volatile ApsErStruct *pEr = pLink->pEr; + + if (IrqVector != -1) + { + intConnect(INUM_TO_IVEC(IrqVector), ErIrqHandler, pLink); + sysIntEnable(IrqLevel); + pEr->IrqVector = IrqVector; + } + return(0); +} + +/****************************************************************************** + * + * Enable or disable the IRQs from the Event Receiver. + * + ******************************************************************************/ +STATIC unsigned short ErEnableIrq(ApsErStruct *pParm, unsigned short Mask) +{ + volatile ApsErStruct *pEr = pParm; + if (Mask == ER_IRQ_OFF) + { + pEr->IrqEnables = 0; + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) & ~0x4000; + } + else if (Mask == ER_IRQ_TELL) + { + if (pEr->Control & 0x4000) + return(pEr->IrqEnables & ER_IRQ_ALL); + } + else + { + pEr->IrqEnables = Mask; + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x4000; + } + + return(0); +} + +/****************************************************************************** + * + * We load what ever RAM is not running. And Enable it. + * + ******************************************************************************/ +STATIC int ErUpdateRam(ApsErStruct *pParm, unsigned short *RamBuf) +{ + int ChosenRam = 2; + + /* Find the idle RAM */ + if (ErGetRamStatus(pParm, 1) == 0) + ChosenRam = 1; /* RAM 1 is currently idle */ + + ErProgramRam(pParm, RamBuf, ChosenRam); + + ErEnableRam(pParm, ChosenRam); + return(0); +} +/****************************************************************************** + * + * Download the entire RAM from a buffer. + * + ******************************************************************************/ +STATIC int ErProgramRam(ApsErStruct *pParm, unsigned short *RamBuf, int Ram) +{ + volatile ApsErStruct *pEr = pParm; + int j; + + if(ErDebug) + printf("RAM download for RAM %d\n", Ram); + + if (Ram == 1) + { + if ((pEr->Control&0x0300) == 0x0200) + return(-1); /* RAM 1 is enabled */ + + /* select VME access to ram 1 */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) & ~0x0040; + } + else + if (Ram == 2) + { + if ((pEr->Control&0x0300) == 0x0300) + return(-1); /* RAM 2 is enabled */ + + /* select VME access to ram 2 */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x0040; + } + else + return(-1); + + /* Reset RAM address */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x0010; + + /* enable auto increment */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x0020; + + pEr->EventRamAddr = 0; + + for (j=0; j<256; j++) + { + pEr->EventRamData = RamBuf[j]; + if((ErDebug)&&(RamBuf[j] != 0)) + printf("%d: %d\n", j, RamBuf[j]); + } + /* Turn off auto-increment */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) & ~0x0020; + return(0); +} + +/****************************************************************************** + * + * Print the entire RAM from a buffer. We skip the null events. + * + ******************************************************************************/ +STATIC int ErDumpRam(ApsErStruct *pParm, int Ram) +{ + volatile ApsErStruct *pEr = pParm; + int j; + int x, y; + + if (Ram == 1) + { + if ((pEr->Control&0x0300) == 0x0200) + return(-1); /* RAM 1 is enabled */ + + /* select VME access to ram 1 */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) & ~0x0040; + } + else + if (Ram == 2) + { + if ((pEr->Control&0x0300) == 0x0300) + return(-1); /* RAM 2 is enabled */ + + /* select VME access to ram 2 */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x0040; + } + else + return(-1); + + /* Reset RAM address */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x0010; + + /* enable auto increment */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP)|0x0020; + + pEr->EventRamAddr = 0; + + for (j=0; j<256; j++) + { + x = pEr->EventRamAddr & 0x00ff; + y = pEr->EventRamData; + if (y != 0) + printf("RAM %d, %d\n", x, y); + } + + /* turn off auto-increment */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) & ~0x0020; + + return(0); +} + +/****************************************************************************** + * + * Select the specified RAM for operation + * + ******************************************************************************/ +STATIC int ErEnableRam(ApsErStruct *pParm, int Ram) +{ + volatile ApsErStruct *pEr = pParm; + + if (Ram == 0) + { + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) & ~0x0200; + return(0); + } + if (Ram == 1) + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) & ~0x0100; + else if (Ram == 2) + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) | 0x0100; + else + return(-1); + + /* Set the map enable bit */ + pEr->Control = (pEr->Control&CONTROL_REG_OR_STRIP) | 0x0200; + + return(0); +} +/****************************************************************************** + * + * Return 1 if the requested RAM is enabled, 0 otherwise. We return -1 on + * error. + * + ******************************************************************************/ +STATIC int ErGetRamStatus(ApsErStruct *pParm, int Ram) +{ + volatile ApsErStruct *pEr = pParm; + + /* Check if RAM map is not enabled */ + if ((pEr->Control & 0x0200) == 0) + return(0); + + if (Ram == 1) + return((pEr->Control & 0x0100) == 0); + + if (Ram == 2) + return((pEr->Control & 0x0100) != 0); + + return(-1); /* We should never get here, invalid RAM number */ +} + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + + +static int DumpEventFifo(ApsErStruct *pParm) +{ + unsigned short j; + unsigned short k; + volatile ApsErStruct *pEr = pParm; + + while (pEr->Control & 0x0002) + { + j = pEr->EventFifo; + k = pEr->EventTimeHi; + printf("FIFO event: %4.4X%4.4X\n", k, j); + } + return(0); +} + +static void MainMenu(void) +{ + printf("r - Reset everything on the event receiver\n"); + printf("f - drain the event FIFO\n"); + printf("1 - dump event RAM 1\n"); + printf("2 - dump event RAM 2\n"); + printf("z - Dump event receiver regs\n"); + printf("q - quit\n"); +} +int ER(void) +{ + static int Card = 0; + char buf[100]; + + printf("Event receiver testerizer\n"); + printf("Enter Card number [%d]:", Card); + fgets(buf, sizeof(buf), stdin); + sscanf(buf, "%d", &Card); + + if (ErHaveReceiver(Card) < 0) + { + printf("Invalid card number specified\n"); + return(-1); + } + printf("Card address: %p\n", ErLink[Card].pEr); + + while(1) + { + MainMenu(); + + if (fgets(buf, sizeof(buf), stdin) == NULL) + break; + + switch (buf[0]) + { + case 'r': ErResetAll(ErLink[Card].pEr); break; + case 'd': ErEnableRam(ErLink[Card].pEr, 0); break; + case 'f': DumpEventFifo(ErLink[Card].pEr); break; + case '1': ErDumpRam(ErLink[Card].pEr, 1); break; + case '2': ErDumpRam(ErLink[Card].pEr, 2); break; + case 'z': ErDumpRegs(ErLink[Card].pEr); break; + case 'q': return(0); + } + } + return(0); +} diff --git a/src/vxWorks/dev/apsDev/devApsEr.h b/src/vxWorks/dev/apsDev/devApsEr.h new file mode 100644 index 000000000..790a2b011 --- /dev/null +++ b/src/vxWorks/dev/apsDev/devApsEr.h @@ -0,0 +1,74 @@ +/* + * ***************************************************************** + * COPYRIGHT NOTIFICATION + * ***************************************************************** + * + * THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE, + * AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE + * AND IN ALL SOURCE LISTINGS OF THE CODE. + * + * (C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + * + * Argonne National Laboratory (ANL), with facilities in the States of + * Illinois and Idaho, is owned by the United States Government, and + * operated by the University of Chicago under provision of a contract + * with the Department of Energy. + * + * Portions of this material resulted from work developed under a U.S. + * Government contract and are subject to the following license: For + * a period of five years from March 30, 1993, the Government is + * granted for itself and others acting on its behalf a paid-up, + * nonexclusive, irrevocable worldwide license in this computer + * software to reproduce, prepare derivative works, and perform + * publicly and display publicly. With the approval of DOE, this + * period may be renewed for two additional five year periods. + * Following the expiration of this period or periods, the Government + * is granted for itself and others acting on its behalf, a paid-up, + * nonexclusive, irrevocable worldwide license in this computer + * software to reproduce, prepare derivative works, distribute copies + * to the public, perform publicly and display publicly, and to permit + * others to do so. + * + * ***************************************************************** + * DISCLAIMER + * ***************************************************************** + * + * NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR + * THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS, + * MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL + * LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR + * USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS + * DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY + * OWNED RIGHTS. + * + * ***************************************************************** + * LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY + * DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). + */ + +#ifndef EPICS_DEVAPSER_H +#define EPICS_DEVAPSER_H + +/* Error numbers passed to ERROR_FUNC routines */ +#define ERROR_TAXI 1 /* Taxi violation */ +#define ERROR_HEART 2 /* Lost the system heart beat */ +#define ERROR_LOST 3 /* Events were lost */ + +/* Globally reserved event numbers */ +#define ER_EVENT_NULL 0x00 /* NULL event */ +#define ER_EVENT_END 0x7f /* Event sequence end */ +#define ER_EVENT_FREEZE 0x7e /* Freeze the event sequence */ +#define ER_EVENT_RESET_TICK 0x7d /* Reset the tick counter */ +#define ER_EVENT_TICK 0x7c /* Add 1 to the tick counter */ +#define ER_EVENT_RESET_PRESCALERS 0x7b +#define ER_EVENT_HEARTBEAT 0x7a + +typedef void (*EVENT_FUNC)(int Card, int EventNum, unsigned long Ticks); +typedef void (*ERROR_FUNC)(int Card, int ErrorNum); + +long ErRegisterEventHandler(int Card, EVENT_FUNC func); +long ErRegisterErrorHandler(int Card, ERROR_FUNC func); +long ErGetTicks(int Card, unsigned long *Ticks); +long ErHaveReceiver(int Card); + +#endif diff --git a/src/vxWorks/dev/atDev/devAt5Vxi.c b/src/vxWorks/dev/atDev/devAt5Vxi.c new file mode 100644 index 000000000..63c172d56 --- /dev/null +++ b/src/vxWorks/dev/atDev/devAt5Vxi.c @@ -0,0 +1,584 @@ +/* devAt5Vxi.c */ +/* base/src/dev $Id$ */ + +/* devAt5Vxi.c - Device Support Routines */ +/* + * Original Author: Bob Dalesio + * Current Author: Marty Kraimer + * Date: 6-1-90 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * .01 08-21-92 mrk Replaces individual At5Vxi modules + * .02 05-27-93 joh changed linear conversion + * .03 09-01-93 joh expects EPICS status from driver + * .04 09-02-93 mcn added AT5VXI Timer support + * .05 10-08-93 mcn added support for Direct mbbo and mbbi + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* The following must match the definition in choiceGbl.ascii */ +#define LINEAR 1 + +static long init_ai(); +static long init_ao(); +static long init_bi(); +static long init_bo(); +static long init_mbbi(); +static long init_mbbiDirect(); +static long init_mbbo(); +static long init_mbboDirect(); +static long ai_ioinfo(); +static long bi_ioinfo(); +static long mbbi_ioinfo(); +static long mbbiDirect_ioinfo(); +static long read_timer(); +static long read_ai(); +static long write_ao(); +static long read_bi(); +static long write_timer(); +static long write_bo(); +static long read_mbbi(); +static long read_mbbiDirect(); +static long write_mbbo(); +static long write_mbboDirect(); +static long ai_lincvt(); +static long ao_lincvt(); + + +typedef struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_write; + DEVSUPFUN special_linconv;} AT5VXIDSET; + +AT5VXIDSET devAiAt5Vxi= {6, NULL, NULL, init_ai, ai_ioinfo, read_ai, ai_lincvt}; +AT5VXIDSET devAoAt5Vxi= {6, NULL, NULL, init_ao, NULL, write_ao, ao_lincvt}; +AT5VXIDSET devBiAt5Vxi= {6, NULL, NULL, init_bi, bi_ioinfo, read_bi, NULL}; +AT5VXIDSET devBoAt5Vxi= {6, NULL, NULL, init_bo, NULL, write_bo, NULL}; +AT5VXIDSET devMbbiAt5Vxi= {6, NULL, NULL, init_mbbi, mbbi_ioinfo, read_mbbi, NULL}; +AT5VXIDSET devMbbiDirectAt5Vxi= {6, NULL, NULL, init_mbbiDirect, mbbiDirect_ioinfo, read_mbbiDirect, NULL}; +AT5VXIDSET devMbboAt5Vxi= {6, NULL, NULL, init_mbbo, NULL, write_mbbo, NULL}; +AT5VXIDSET devMbboDirectAt5Vxi= {6, NULL, NULL, init_mbboDirect, NULL, write_mbboDirect, NULL}; + + /* DSET structure for timer records */ + typedef struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read; + DEVSUPFUN write;} AT5VXIDSET_TM; + +AT5VXIDSET_TM devTmAt5Vxi={6, NULL, NULL, NULL, NULL, read_timer, write_timer}; + +/* + * These constants are indexed by the time units field in the timer record. + * Values are converted to seconds. + */ +static double constants[] = {1e3,1e6,1e9,1e12}; + +static void localPostEvent (void *pParam); + +static long read_timer(struct timerRecord *ptimer) +{ + struct vmeio *pvmeio; + unsigned source; + unsigned ptst; + double time_pulse[2]; /* delay and width */ + double constant; + + /* only supports a one channel VME timer module !!!! */ + pvmeio = (struct vmeio *)(&ptimer->out.value); + + /* put the value to the ao driver */ + if (at5vxi_one_shot_read( + &ptst, /* pre-trigger state */ + &(time_pulse[0]), /* offset of pulse */ + &(time_pulse[1]), /* width of pulse */ + (int)pvmeio->card, /* card number */ + (int)pvmeio->signal, /* signal number */ + &source) != 0) { /* trigger source */ + return 1; + } + + /* convert according to time units */ + constant = constants[ptimer->timu]; + + /* timing pulse 1 is currently active */ + /* put its parameters into the database so that it will not change */ + /* when the timer record is written */ + ptimer->rdt1 = time_pulse[0] * constant; /* delay to trigger */ + ptimer->rpw1 = time_pulse[1] * constant; /* pulse width */ + + return 0; +} + +static long write_timer(struct timerRecord *ptimer) +{ + struct vmeio *pvmeio; + void (*pCB)(void *); + + pvmeio = (struct vmeio *)(&ptimer->out.value); + + if (ptimer->tevt) { + pCB = localPostEvent; + } + else { + pCB = NULL; + } + + /* put the value to the ao driver */ + return at5vxi_one_shot( + ptimer->ptst, /* pre-trigger state */ + ptimer->t1dl, /* pulse offset */ + ptimer->t1wd, /* pulse width */ + pvmeio->card, /* card number */ + pvmeio->signal, /* signal number */ + ptimer->tsrc, /* trigger source */ + pCB, /* addr of event post routine */ + ptimer); /* event to post on trigger */ +} + + +static void localPostEvent (void *pParam) +{ + struct timerRecord *ptimer = pParam; + + if (ptimer->tevt) { + post_event(ptimer->tevt); + } +} + + +static long init_ai( struct aiRecord *pai) +{ + unsigned short value; + struct vmeio *pvmeio; + long status; + + /* ai.inp must be an VME_IO */ + switch (pai->inp.type) { + case (VME_IO) : + break; + default : + recGblRecordError(S_db_badField,(void *)pai, + "devAiAt5Vxi (init_record) Illegal INP field"); + return(S_db_badField); + } + + /* set linear conversion slope*/ + pai->eslo = (pai->eguf -pai->egul)/0xffff; + + /* call driver so that it configures card */ + pvmeio = (struct vmeio *)&(pai->inp.value); + if(status=at5vxi_ai_driver(pvmeio->card,pvmeio->signal,&value)) { + recGblRecordError(status,(void *)pai, + "devAiAt5Vxi (init_record) at5vxi_ai_driver error"); + return(status); + } + return(0); +} + +static long ai_ioinfo( + int cmd, + struct aiRecord *pai, + IOSCANPVT *ppvt) +{ + return at5vxi_getioscanpvt(pai->inp.value.vmeio.card,ppvt); +} + +static long read_ai(struct aiRecord *pai) +{ + struct vmeio *pvmeio; + long status; + unsigned short value; + + + pvmeio = (struct vmeio *)&(pai->inp.value); + status = at5vxi_ai_driver(pvmeio->card,pvmeio->signal,&value); + if(status==0){ + pai->rval = value; + } + else{ + recGblSetSevr(pai,READ_ALARM,INVALID_ALARM); + } + return(status); +} + +static long ai_lincvt(struct aiRecord *pai, int after) +{ + + if(!after) return(0); + /* set linear conversion slope*/ + pai->eslo = (pai->eguf -pai->egul)/0xffff; + return(0); +} + +static long read_ao(); /* forward reference*/ + +static long init_ao(struct aoRecord *pao) +{ + + /* ao.out must be an VME_IO */ + switch (pao->out.type) { + case (VME_IO) : + break; + default : + recGblRecordError(S_db_badField,(void *)pao, + "devAoAt5Vxi (init_record) Illegal OUT field"); + return(S_db_badField); + } + + /* set linear conversion slope*/ + pao->eslo = (pao->eguf -pao->egul)/0xffff; + + /* call driver so that it configures card */ + return read_ao(pao); +} + +static long write_ao(struct aoRecord *pao) +{ + struct vmeio *pvmeio; + long status; + unsigned short value,rbvalue; + + + pvmeio = (struct vmeio *)&(pao->out.value); + value = pao->rval; + status = at5vxi_ao_driver(pvmeio->card,pvmeio->signal,&value,&rbvalue); + if(status == 0){ + pao->rbv = rbvalue; + } + else{ + recGblSetSevr(pao,WRITE_ALARM,INVALID_ALARM); + } + return(status); +} + +static long ao_lincvt( struct aoRecord *pao, int after) +{ + + if(!after) return(0); + /* set linear conversion slope*/ + pao->eslo = (pao->eguf -pao->egul)/0xffff; + return(0); +} + +static long read_ao(pao) +struct aoRecord *pao; +{ + long status; + unsigned short value; + struct vmeio *pvmeio = &pao->out.value.vmeio; + + /* get the value from the ao driver */ + status = at5vxi_ao_read(pvmeio->card,pvmeio->signal,&value); + if(status == 0){ + pao->rbv = pao->rval = value; + } + return status; +} + +static long init_bi( struct biRecord *pbi) +{ + struct vmeio *pvmeio; + + + /* bi.inp must be an VME_IO */ + switch (pbi->inp.type) { + case (VME_IO) : + pvmeio = (struct vmeio *)&(pbi->inp.value); + pbi->mask=1; + pbi->mask <<= pvmeio->signal; + break; + default : + recGblRecordError(S_db_badField,(void *)pbi, + "devBiAt5Vxi (init_record) Illegal INP field"); + return(S_db_badField); + } + return(0); +} + +static long bi_ioinfo( + int cmd, + struct biRecord *pbi, + IOSCANPVT *ppvt) +{ + return at5vxi_getioscanpvt(pbi->inp.value.vmeio.card,ppvt); +} + +static long read_bi(struct biRecord *pbi) +{ + struct vmeio *pvmeio; + long status; + unsigned long value; + + + pvmeio = (struct vmeio *)&(pbi->inp.value); + status = at5vxi_bi_driver(pvmeio->card,pbi->mask,&value); + if(status==0) { + pbi->rval = value; + } else { + recGblSetSevr(pbi,READ_ALARM,INVALID_ALARM); + } + return status; +} + +static long init_bo(struct boRecord *pbo) +{ + unsigned long value; + long status=0; + struct vmeio *pvmeio; + + /* bo.out must be an VME_IO */ + switch (pbo->out.type) { + case (VME_IO) : + pvmeio = (struct vmeio *)&(pbo->out.value); + pbo->mask = 1; + pbo->mask <<= pvmeio->signal; + status = at5vxi_bi_driver(pvmeio->card,pbo->mask,&value); + if(status == 0){ + pbo->rbv = pbo->rval = value; + } + break; + default : + status = S_db_badField; + recGblRecordError(status,(void *)pbo, + "devBoAt5Vxi (init_record) Illegal OUT field"); + } + return(status); +} + +static long write_bo(struct boRecord *pbo) +{ + struct vmeio *pvmeio; + long status; + + + pvmeio = (struct vmeio *)&(pbo->out.value); + status = at5vxi_bo_driver(pvmeio->card,pbo->rval,pbo->mask); + if(status!=0) { + recGblSetSevr(pbo,WRITE_ALARM,INVALID_ALARM); + } + return(status); +} + +static long init_mbbi(struct mbbiRecord *pmbbi) +{ + + /* mbbi.inp must be an VME_IO */ + switch (pmbbi->inp.type) { + case (VME_IO) : + pmbbi->shft = pmbbi->inp.value.vmeio.signal; + pmbbi->mask <<= pmbbi->shft; + break; + default : + recGblRecordError(S_db_badField,(void *)pmbbi, + "devMbbiAt5Vxi (init_record) Illegal INP field"); + return(S_db_badField); + } + return(0); +} + +static long init_mbbiDirect(struct mbbiDirectRecord *pmbbi) +{ + + /* mbbi.inp must be an VME_IO */ + switch (pmbbi->inp.type) { + case (VME_IO) : + pmbbi->shft = pmbbi->inp.value.vmeio.signal; + pmbbi->mask <<= pmbbi->shft; + break; + default : + recGblRecordError(S_db_badField,(void *)pmbbi, + "devMbbiDirectAt5Vxi (init_record) Illegal INP field"); + return(S_db_badField); + } + return(0); +} + +static long mbbi_ioinfo( + int cmd, + struct mbbiRecord *pmbbi, + IOSCANPVT *ppvt) +{ + return at5vxi_getioscanpvt(pmbbi->inp.value.vmeio.card,ppvt); +} + +static long mbbiDirect_ioinfo( + int cmd, + struct mbbiDirectRecord *pmbbi, + IOSCANPVT *ppvt) +{ + return at5vxi_getioscanpvt(pmbbi->inp.value.vmeio.card,ppvt); +} + +static long read_mbbi(struct mbbiRecord *pmbbi) +{ + struct vmeio *pvmeio; + long status; + unsigned long value; + + + pvmeio = (struct vmeio *)&(pmbbi->inp.value); + status = at5vxi_bi_driver(pvmeio->card,pmbbi->mask,&value); + if(status==0) { + pmbbi->rval = value; + } else { + recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM); + } + return(status); +} + +static long read_mbbiDirect(struct mbbiDirectRecord *pmbbi) +{ + struct vmeio *pvmeio; + long status; + unsigned long value; + + + pvmeio = (struct vmeio *)&(pmbbi->inp.value); + status = at5vxi_bi_driver(pvmeio->card,pmbbi->mask,&value); + if(status==0) { + pmbbi->rval = value; + } else { + recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM); + } + return(status); +} + +static long init_mbbo(struct mbboRecord *pmbbo) +{ + unsigned long value; + struct vmeio *pvmeio; + long status = 0; + + /* mbbo.out must be an VME_IO */ + switch (pmbbo->out.type) { + case (VME_IO) : + pvmeio = &(pmbbo->out.value.vmeio); + pmbbo->shft = pvmeio->signal; + pmbbo->mask <<= pmbbo->shft; + status = at5vxi_bi_driver(pvmeio->card,pmbbo->mask,&value); + if(status==0) pmbbo->rbv = pmbbo->rval = value; + break; + default : + status = S_db_badField; + recGblRecordError(status,(void *)pmbbo, + "devMbboAt5Vxi (init_record) Illegal OUT field"); + } + return(status); +} + +static long init_mbboDirect(struct mbboDirectRecord *pmbbo) +{ + unsigned long value; + struct vmeio *pvmeio; + long status = 0; + + /* mbbo.out must be an VME_IO */ + switch (pmbbo->out.type) { + case (VME_IO) : + pvmeio = &(pmbbo->out.value.vmeio); + pmbbo->shft = pvmeio->signal; + pmbbo->mask <<= pmbbo->shft; + status = at5vxi_bi_driver(pvmeio->card,pmbbo->mask,&value); + if(status==0) pmbbo->rbv = pmbbo->rval = value; + break; + default : + status = S_db_badField; + recGblRecordError(status,(void *)pmbbo, + "devMbboDirectAt5Vxi (init_record) Illegal OUT field"); + } + return(status); +} + +static long write_mbbo(struct mbboRecord *pmbbo) +{ + struct vmeio *pvmeio; + long status; + unsigned long value; + + + pvmeio = &(pmbbo->out.value.vmeio); + status = at5vxi_bo_driver(pvmeio->card,pmbbo->rval,pmbbo->mask); + if(status==0) { + status = at5vxi_bi_driver(pvmeio->card,pmbbo->mask,&value); + if(status==0) pmbbo->rbv = value; + else recGblSetSevr(pmbbo,READ_ALARM,INVALID_ALARM); + } else { + recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM); + } + return(status); +} + +static long write_mbboDirect(struct mbboDirectRecord *pmbbo) +{ + struct vmeio *pvmeio; + long status; + unsigned long value; + + + pvmeio = &(pmbbo->out.value.vmeio); + status = at5vxi_bo_driver(pvmeio->card,pmbbo->rval,pmbbo->mask); + if(status==0) { + status = at5vxi_bi_driver(pvmeio->card,pmbbo->mask,&value); + if(status==0) pmbbo->rbv = value; + else recGblSetSevr(pmbbo,READ_ALARM,INVALID_ALARM); + } else { + recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM); + } + return(status); +} + diff --git a/src/vxWorks/dev/atDev/devAt8Fp.c b/src/vxWorks/dev/atDev/devAt8Fp.c new file mode 100644 index 000000000..624afaef6 --- /dev/null +++ b/src/vxWorks/dev/atDev/devAt8Fp.c @@ -0,0 +1,251 @@ +/* devAt8At8Fp.c */ +/* base/src/dev $Id$ */ + +/* + * Original Author: Bob Dalesio + * Current Author: Marty Kraimer + * Date: 09-02-92 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * .01 08-02-92 mrk Original version + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static long init_bi(); +static long init_bo(); +static long init_mbbi(); +static long init_mbbo(); +static long bi_ioinfo(); +static long mbbi_ioinfo(); +static long read_bi(); +static long write_bo(); +static long read_mbbi(); +static long write_mbbo(); + + +typedef struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_write; + } BINARYDSET; + + +BINARYDSET devBiAt8Fp= {6,NULL,NULL,init_bi, bi_ioinfo, read_bi}; +BINARYDSET devBoAt8Fp= {6,NULL,NULL,init_bo, NULL, write_bo}; +BINARYDSET devMbbiAt8Fp={6,NULL,NULL,init_mbbi,mbbi_ioinfo,read_mbbi}; +BINARYDSET devMbboAt8Fp={6,NULL,NULL,init_mbbo, NULL,write_mbbo}; + +static long init_bi( struct biRecord *pbi) +{ + struct vmeio *pvmeio; + + + /* bi.inp must be an VME_IO */ + switch (pbi->inp.type) { + case (VME_IO) : + pvmeio = (struct vmeio *)&(pbi->inp.value); + pbi->mask=1; + pbi->mask <<= pvmeio->signal; + break; + default : + recGblRecordError(S_db_badField,(void *)pbi, + "devBiAt8Fp (init_record) Illegal INP field"); + return(S_db_badField); + } + return(0); +} + +static long bi_ioinfo( + int cmd, + struct biRecord *pbi, + IOSCANPVT *ppvt) +{ + fp_getioscanpvt(pbi->inp.value.vmeio.card,ppvt); + return(0); +} + +static long read_bi(struct biRecord *pbi) +{ + struct vmeio *pvmeio; + int status; + long value; + + + pvmeio = (struct vmeio *)&(pbi->inp.value); + status = fp_read(pvmeio->card,pbi->mask,&value); + if(status==0) { + pbi->rval = value; + return(0); + } else { + recGblSetSevr(pbi,READ_ALARM,INVALID_ALARM); + return(2); + } +} + +static long init_bo(struct boRecord *pbo) +{ + unsigned int value; + int status=0; + struct vmeio *pvmeio; + + /* bo.out must be an VME_IO */ + switch (pbo->out.type) { + case (VME_IO) : + pvmeio = (struct vmeio *)&(pbo->out.value); + pbo->mask = 1; + pbo->mask <<= pvmeio->signal; + status = fp_read(pvmeio->card,pbo->mask,&value); + if(status == 0) pbo->rbv = pbo->rval = value; + else status = 2; + break; + default : + status = S_db_badField; + recGblRecordError(status,(void *)pbo, + "devBoAt8Fp (init_record) Illegal OUT field"); + } + return(status); +} + +static long write_bo(struct boRecord *pbo) +{ + struct vmeio *pvmeio; + int status; + + + pvmeio = (struct vmeio *)&(pbo->out.value); + status = fp_driver(pvmeio->card,pbo->rval,pbo->mask); + if(status!=0) { + recGblSetSevr(pbo,WRITE_ALARM,INVALID_ALARM); + } + return(status); +} + +static long init_mbbi(struct mbbiRecord *pmbbi) +{ + + /* mbbi.inp must be an VME_IO */ + switch (pmbbi->inp.type) { + case (VME_IO) : + pmbbi->shft = pmbbi->inp.value.vmeio.signal; + pmbbi->mask <<= pmbbi->shft; + break; + default : + recGblRecordError(S_db_badField,(void *)pmbbi, + "devMbbiAt8Fp (init_record) Illegal INP field"); + return(S_db_badField); + } + return(0); +} + +static long mbbi_ioinfo( + int cmd, + struct mbbiRecord *pmbbi, + IOSCANPVT *ppvt) +{ + fp_getioscanpvt(pmbbi->inp.value.vmeio.card,ppvt); + return(0); +} + +static long read_mbbi(struct mbbiRecord *pmbbi) +{ + struct vmeio *pvmeio; + int status; + unsigned long value; + + + pvmeio = (struct vmeio *)&(pmbbi->inp.value); + status = fp_read(pvmeio->card,pmbbi->mask,&value); + if(status==0) { + pmbbi->rval = value; + } else { + recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM); + } + return(status); +} + +static long init_mbbo(struct mbboRecord *pmbbo) +{ + unsigned long value; + struct vmeio *pvmeio; + int status = 0; + + /* mbbo.out must be an VME_IO */ + switch (pmbbo->out.type) { + case (VME_IO) : + pvmeio = &(pmbbo->out.value.vmeio); + pmbbo->shft = pvmeio->signal; + pmbbo->mask <<= pmbbo->shft; + status = fp_read(pvmeio->card,pmbbo->mask,&value); + if(status==0) pmbbo->rbv = pmbbo->rval = value; + else status = 2; + break; + default : + status = S_db_badField; + recGblRecordError(status,(void *)pmbbo, + "devMbboAt8Fp (init_record) Illegal OUT field"); + } + return(status); +} + +static long write_mbbo(struct mbboRecord *pmbbo) +{ + struct vmeio *pvmeio; + int status; + unsigned long value; + + + pvmeio = &(pmbbo->out.value.vmeio); + status = fp_driver(pvmeio->card,pmbbo->rval,pmbbo->mask); + if(status==0) { + status = fp_read(pvmeio->card,pmbbo->mask,&value); + if(status==0) pmbbo->rbv = value; + else recGblSetSevr(pmbbo,READ_ALARM,INVALID_ALARM); + } else { + recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM); + } + return(status); +} diff --git a/src/vxWorks/dev/compumotorDev/devSmCompumotor1830.c b/src/vxWorks/dev/compumotorDev/devSmCompumotor1830.c new file mode 100644 index 000000000..153ec1175 --- /dev/null +++ b/src/vxWorks/dev/compumotorDev/devSmCompumotor1830.c @@ -0,0 +1,82 @@ +/* devSmCompumotor1830.c */ +/* base/src/dev $Id$ */ + +/* devSmCompumotor1830.c - Device Support Routines */ +/* + * Original Author: Bob Dalesio + * Current Author: Marty Kraimer + * Date: 3/6/91 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * .01 04-08092 mrk Moved from record support + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Create the dset for */ +static long sm_command(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN sm_command; +}devSmCompumotor1830={ + 6, + NULL, + NULL, + NULL, + NULL, + sm_command}; + +static long sm_command(psm,command,arg1,arg2) + struct steppermotorRecord *psm; + short command; + int arg1; + int arg2; +{ + short card,channel; + + card = psm->out.value.vmeio.card; + channel = psm->out.value.vmeio.signal; + compu_driver(card,channel,command,arg1,arg2); + return(0); +} diff --git a/src/vxWorks/dev/gpibDev/devCommonGpib.c b/src/vxWorks/dev/gpibDev/devCommonGpib.c new file mode 100644 index 000000000..b47096cb2 --- /dev/null +++ b/src/vxWorks/dev/gpibDev/devCommonGpib.c @@ -0,0 +1,2638 @@ +/* devCommonGpib.c */ +/* base/src/dev $Id$ */ + +/* + * $Log$ + * Revision 1.36 1998/01/20 22:08:59 mrk + * cleanup includes + * + * Revision 1.35 1997/06/30 12:53:06 mrk + * GPIBEFASTO: Last fix was TOO strict + * + * Revision 1.34 1997/04/30 18:58:03 mrk + * Fixed most compiler warning messages + * + * Revision 1.33 1997/04/09 19:50:39 mrk + * Forgot to compile before committing + * + * Revision 1.32 1997/04/09 19:35:56 mrk + * makesure GPIBFASTO has val in range + * + * Revision 1.31 1997/04/09 18:33:49 mrk + * Restore original + * + * Revision 1.29 1996/06/12 20:04:51 winans + * Added better debugging code to the initXX logic. + * + * Revision 1.28 1996/06/06 14:35:41 winans + * Fixed external reference to GPIB driver's DRVET + * + * Revision 1.27 1996/02/16 22:04:58 jba + * Changed field reference from val to oval in devGpibLib_aoGpibWork + * + * Revision 1.26 1995/11/27 22:13:22 winans + * Added raw reading capability to the waveform record support. + * + * Revision 1.25 1995/07/31 19:44:08 winans + * Changed the parameter table and associated support routines to support + * buffer length specifications of size long instead of short. + * + * Revision 1.24 1995/03/10 16:55:40 winans + * Added waveform writing support + * + * Revision 1.23 1995/01/06 16:55:52 winans + * Added the log parameter to the doc + * + * + * Author: John Winans + * Origional Author: Ned D. Arnold + * Date: 11-20-91 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1988, 1989, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * All rights reserved. No part of this publication may be reproduced, + * stored in a retrieval system, transmitted, in any form or by any + * means, electronic, mechanical, photocopying, recording, or otherwise + * without prior written permission of Los Alamos National Laboratory + * and Argonne National Laboratory. + * + * Modification Log: + * ----------------- + * .01 05-30-91 nda Initial Release + * .02 06-18-91 nda init_rec_mbbo must return(2) if no init value + * .03 07-02-91 nda renamed String/StringOut DSET's to Si/So + * .04 07-11-91 jrw added the callbackRequest to process() + * .05 07-15-91 jrw redesigned init processing... more generic + * .06 11-01-91 jrw major rework to fit into new GPIB driver + * .07 11-11-91 jrw added new version of SRQ support + * .08 11-17-91 jrw changed to support SR620 + * .09 11-20-91 jrw redesigned as a library + * .10 11-22-91 jrw removed output formatting for all but GPIBWRITEs + * .11 01-10-92 jrw changed return from GPIBSOFT (propagated, was 0) + * .12 02-05-92 jba Changed process parameter from precord->pdba to precord + * .13 02-18-92 jrw Changed return from the AO init function to 2 + * .14 02-26-92 jrw added return codes to the output work functions + * .15 02-27-92 jrw added the setting of PACT to 1 when init fails + * .16 04-08-92 jrw reordered initXx to clean up SRQ init code + * .17 04-30-92 jrw added waveform record support + * .18 07-10-92 jrw initXx endless loop looking for hwpvt + * + * WISH LIST: + * It would be nice to read and write directly to/from the val field + * when operating on SI and SO records. The strncpy looks like a waste. + */ + +/* This MUST be deleted when the new dbScanner stuff is put into EPICS! */ +/* any existing databases will also have to be changed from passive, to */ +/* I/O event scanned for magic SRQ processing */ +#define SCAN_IO_EVENT 0 /* This should be in an epicsH header file */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef VALID_ALARM +#define VALID_ALARM INVALID_ALARM +#endif + +/* + * This external structure contains the entry points to the GPIB drver. + */ + +#if 0 /* WHAT IS THIS DUMB THING DOING HERE? */ +extern struct { + long number; + DRVSUPFUN report; /* call this to get stats about the link */ + DRVSUPFUN init; /* do NOT call this... epics calls it */ + int (*qGpibReq)(); + int (*registerSrqCallback)(); + int (*writeIb)(); + int (*readIb)(); + int (*readIbEos)(); + int (*writeIbCmd)(); + int (*ioctl)(); +} drvGpib; +#else +extern struct drvGpibSet drvGpib; +#endif + +extern int ibSrqDebug; + +int checkEnums(char *msg, char **enums); + +/****************************************************************************** + * + * Print a report of operating statistics for all devices supported by this + * module. + * + ******************************************************************************/ + +long +devGpibLib_report(dset) +gDset *dset; +{ + struct hwpvt *phwpvt; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(dset->funPtr[dset->number]); + phwpvt = parmBlock->hwpvtHead; + + while (phwpvt != NULL) + { + if (phwpvt->linkType == GPIB_IO) + printf(" NI-link %d, node %d, timeouts %ld\n", phwpvt->link, phwpvt->device, phwpvt->tmoCount); + else if (phwpvt->linkType == BBGPIB_IO) + printf(" BB-link %d, bug %d, node %d, timeouts %ld\n", phwpvt->link, phwpvt->bug, phwpvt->device, phwpvt->tmoCount); + + phwpvt = phwpvt->next; + } + return(0); +} + +/****************************************************************************** + * + * Initialization for device support + * This is called one time before any records are initialized with a parm + * value of 0. And then again AFTER all record-level init is complete + * with a param value of 1. + * + ******************************************************************************/ + +long +devGpibLib_initDevSup(parm, dset) +int parm; /* set to 0 on pre-rec init call, and 1 on post-rec init call */ +gDset *dset; /* pointer to dset used to reference the init function */ +{ + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(dset->funPtr[dset->number]); + + if ((parm == 0) && *parmBlock->debugFlag) + printf("%s: Device Support Initializing ...\n", parmBlock->name); + + return(OK); +} + +static void RegisterProcessCallback(CALLBACK *pCallback, int Priority, void *Parm) +{ + callbackSetCallback(devGpibLib_processCallback, pCallback); + callbackSetPriority(Priority, pCallback); + callbackSetUser(Parm, pCallback); + callbackRequest(pCallback); + return; +} + +/****************************************************************************** + * + * Initialization routines. + * + ******************************************************************************/ +/****************************************************************************** + * + * ai record init + * + ******************************************************************************/ + +long +devGpibLib_initAi(pai, process) +struct aiRecord *pai; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pai->dset))->funPtr[pai->dset->number]); + + /* Do common initialization */ + if (result = devGpibLib_initXx((caddr_t) pai, &pai->inp)) + { + return(result); + } + + /* make sure the command type makes sendse for the record type */ + + if (parmBlock->gpibCmds[((struct gpibDpvt *)pai->dpvt)->parm].type != GPIBREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pai->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pai->dpvt)->parm].type != GPIBRAWREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pai->dpvt)->parm].type != GPIBREADW) + { + sprintf(message, "%s: devGpibLib_initAi: invalid command type for an AI record in param %d\n", pai->name, ((struct gpibDpvt *)pai->dpvt)->parm); + errMessage(S_db_badField, message); + pai->pact = TRUE; + return(S_db_badField); + } + return(0); +} + +/****************************************************************************** + * + * ao record init + * + ******************************************************************************/ + +long +devGpibLib_initAo(pao, process) +struct aoRecord *pao; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pao->dset))->funPtr[pao->dset->number]); + + /* do common initialization */ + if (result = devGpibLib_initXx((caddr_t) pao, &pao->out)) + { + return(result); + } + /* make sure the command type makes sendse for the record type */ + + if (parmBlock->gpibCmds[((struct gpibDpvt *)pao->dpvt)->parm].type != GPIBWRITE && + parmBlock->gpibCmds[((struct gpibDpvt *)pao->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pao->dpvt)->parm].type != GPIBCMD && + parmBlock->gpibCmds[((struct gpibDpvt *)pao->dpvt)->parm].type != GPIBCNTL) + { + sprintf(message, "%s: devGpibLib_initAo: invalid command type for an AO record in param %d\n", pao->name, ((struct gpibDpvt *)pao->dpvt)->parm); + errMessage(S_db_badField, message); + pao->pact = TRUE; + return(S_db_badField); + } + return(2); /* Don't let record processing do an RVAL to VAL conversion */ +} + +/****************************************************************************** + * + * li record init + * + ******************************************************************************/ + +long +devGpibLib_initLi(pli, process) +struct longinRecord *pli; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pli->dset))->funPtr[pli->dset->number]); + + /* Do common initialization */ + if (result = devGpibLib_initXx((caddr_t) pli, &pli->inp)) + { + return(result); + } + + /* make sure the command type makes sendse for the record type */ + + if (parmBlock->gpibCmds[((struct gpibDpvt *)pli->dpvt)->parm].type != GPIBREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pli->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pli->dpvt)->parm].type != GPIBRAWREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pli->dpvt)->parm].type != GPIBREADW) + { + sprintf(message, "%s: devGpibLib_initLi: invalid command type for an LI record in param %d\n", pli->name, ((struct gpibDpvt *)pli->dpvt)->parm); + errMessage(S_db_badField, message); + pli->pact = TRUE; + return(S_db_badField); + } + + return(0); +} + +/****************************************************************************** + * + * lo record init + * + ******************************************************************************/ + +long +devGpibLib_initLo(plo, process) +struct longoutRecord *plo; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(plo->dset))->funPtr[plo->dset->number]); + + /* do common initialization */ + if (result = devGpibLib_initXx((caddr_t) plo, &plo->out)) + { + return(result); + } + if (parmBlock->gpibCmds[((struct gpibDpvt *)plo->dpvt)->parm].type != GPIBWRITE && + parmBlock->gpibCmds[((struct gpibDpvt *)plo->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)plo->dpvt)->parm].type != GPIBCMD && + parmBlock->gpibCmds[((struct gpibDpvt *)plo->dpvt)->parm].type != GPIBCNTL) + { + sprintf(message, "%s: devGpibLib_initLo: invalid command type for an LO record in param %d\n", plo->name, ((struct gpibDpvt *)plo->dpvt)->parm); + errMessage(S_db_badField, message); + plo->pact = TRUE; + return(S_db_badField); + } + + return(0); +} + +/****************************************************************************** + * + * bi record init + * + ******************************************************************************/ + +long +devGpibLib_initBi(pbi, process) +struct biRecord *pbi; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset *)(pbi->dset))->funPtr[pbi->dset->number]); + + /* Do common initialization */ + if (result = devGpibLib_initXx((caddr_t) pbi, &pbi->inp)) + { + return(result); + } + /* make sure the command type makes sendse for the record type */ + + if (parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].type != GPIBREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].type != GPIBEFASTI && + parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].type != GPIBEFASTIW && + parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].type != GPIBRAWREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].type != GPIBREADW) + { + sprintf(message, "%s: devGpibLib_initLi: invalid command type for an BI record in param %d\n", pbi->name, ((struct gpibDpvt *)pbi->dpvt)->parm); + errMessage(S_db_badField, message); + pbi->pact = TRUE; + return(S_db_badField); + } + + /* See if there are names asociated with the record that should */ + /* be filled in */ + if (parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist != NULL) + { + if (pbi->znam[0] == '\0') + { + strcpy(pbi->znam, parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist->item[0]); + } + if (pbi->onam[0] == '\0') + { + strcpy(pbi->onam, parmBlock->gpibCmds[((struct gpibDpvt *)pbi->dpvt)->parm].namelist->item[1]); + } + } + return(0); +} + +/****************************************************************************** + * + * bo record init + * + ******************************************************************************/ + +long +devGpibLib_initBo(pbo, process) +struct boRecord *pbo; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset *)(pbo->dset))->funPtr[pbo->dset->number]); + + /* do common initialization */ + if (result = devGpibLib_initXx((caddr_t) pbo, &pbo->out)) + { + return(result); + } + if (parmBlock->gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].type != GPIBWRITE && + parmBlock->gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].type != GPIBCMD && + parmBlock->gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].type != GPIBEFASTO && + parmBlock->gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].type != GPIBCNTL) + { + sprintf(message, "%s: devGpibLib_initBo: invalid command type for an BO record in param %d\n", pbo->name, ((struct gpibDpvt *)pbo->dpvt)->parm); + errMessage(S_db_badField, message); + pbo->pact = TRUE; + return(S_db_badField); + } + /* see if there are names asociated with the record that should */ + /* be filled in */ + if (parmBlock->gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist != NULL) + { + if (pbo->znam[0] == '\0') + { + strcpy(pbo->znam, parmBlock->gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist->item[0]); + } + if (pbo->onam[0] == '\0') + { + strcpy(pbo->onam, parmBlock->gpibCmds[((struct gpibDpvt *)pbo->dpvt)->parm].namelist->item[1]); + } + } + return(0); +} + +/****************************************************************************** + * + * mbbi record init + * + ******************************************************************************/ + +long +devGpibLib_initMbbi(pmbbi, process) +struct mbbiRecord *pmbbi; +void (*process)(); +{ + long result; + char message[100]; + struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ + int name_ct; /* for filling in the name strings */ + char *name_ptr; /* index into name list array */ + unsigned long *val_ptr; /* indev into the value list array */ + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pmbbi->dset))->funPtr[pmbbi->dset->number]); + + /* do common initialization */ + + if (result = devGpibLib_initXx((caddr_t)pmbbi, &pmbbi->inp)) + { + return(result); + } + /* make sure the command type makes sendse for the record type */ + + if (parmBlock->gpibCmds[((struct gpibDpvt *)pmbbi->dpvt)->parm].type != GPIBREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbi->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbi->dpvt)->parm].type != GPIBEFASTI && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbi->dpvt)->parm].type != GPIBEFASTIW && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbi->dpvt)->parm].type != GPIBRAWREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbi->dpvt)->parm].type != GPIBREADW) + { + sprintf(message, "%s: devGpibLib_initLi: invalid command type for an MBBI record in param %d\n", pmbbi->name, ((struct gpibDpvt *)pmbbi->dpvt)->parm); + errMessage(S_db_badField, message); + pmbbi->pact = TRUE; + return(S_db_badField); + } + + + dpvt = (struct gpibDpvt *)pmbbi->dpvt; /* init pointer to gpibDpvt */ + + /* do initialization of other fields in the record that are unique + * to this record type */ + + /* see if there are names asociated with the record that should */ + /* be filled in */ + if (parmBlock->gpibCmds[dpvt->parm].namelist != NULL) + { + if (parmBlock->gpibCmds[dpvt->parm].namelist->value == NULL) + { + sprintf(message, "%s: init_rec_mbbi: MBBI value list wrong for param #%d\n", pmbbi->name, dpvt->parm); + errMessage(S_db_badField, message); + pmbbi->pact = TRUE; + return(S_db_badField); + } + pmbbi->nobt = parmBlock->gpibCmds[dpvt->parm].namelist->nobt; + name_ct = 0; /* current name string element */ + name_ptr = pmbbi->zrst; /* first name string element */ + val_ptr = &(pmbbi->zrvl); /* first value element */ + while (name_ct < parmBlock->gpibCmds[dpvt->parm].namelist->count) + { + if (name_ptr[0] == '\0') + { + strcpy(name_ptr, parmBlock->gpibCmds[dpvt->parm].namelist->item[name_ct]); + *val_ptr = parmBlock->gpibCmds[dpvt->parm].namelist->value[name_ct]; + } + name_ct++; + name_ptr += sizeof(pmbbi->zrst); + val_ptr++; + } + } + return(0); +} + +/****************************************************************************** + * + * mbbo record init + * + ******************************************************************************/ + +long +devGpibLib_initMbbo(pmbbo, process) +struct mbboRecord *pmbbo; +void (*process)(); +{ + long result; + char message[100]; + struct gpibDpvt *dpvt; /* pointer to gpibDpvt, not yet assigned */ + int name_ct; /* for filling in the name strings */ + char *name_ptr; /* index into name list array */ + unsigned long *val_ptr; /* index into the value list array */ + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pmbbo->dset))->funPtr[pmbbo->dset->number]); + + /* do common initialization */ + if (result = devGpibLib_initXx((caddr_t)pmbbo, &pmbbo->out)) + { + return(result); + } + if (parmBlock->gpibCmds[((struct gpibDpvt *)pmbbo->dpvt)->parm].type != GPIBWRITE && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbo->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbo->dpvt)->parm].type != GPIBCMD && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbo->dpvt)->parm].type != GPIBEFASTO && + parmBlock->gpibCmds[((struct gpibDpvt *)pmbbo->dpvt)->parm].type != GPIBCNTL) + { + sprintf(message, "%s: devGpibLib_initMbbo: invalid command type for an MBBO record in param %d\n", pmbbo->name, ((struct gpibDpvt *)pmbbo->dpvt)->parm); + errMessage(S_db_badField, message); + pmbbo->pact = TRUE; + return(S_db_badField); + } + + dpvt = (struct gpibDpvt *)pmbbo->dpvt; /* init pointer to gpibDpvt */ + + /* do initialization of other fields in the record that are unique + * to this record type */ + + /* see if there are names asociated with the record that should */ + /* be filled in */ + if (parmBlock->gpibCmds[dpvt->parm].namelist != NULL) + { + if (parmBlock->gpibCmds[dpvt->parm].namelist->value == NULL) + { + sprintf(message, "%s: init_rec_mbbo: MBBO value list wrong for param #%d\n", pmbbo->name, dpvt->parm); + errMessage(S_db_badField, message); + pmbbo->pact = TRUE; + return(S_db_badField); + } + + pmbbo->nobt = parmBlock->gpibCmds[dpvt->parm].namelist->nobt; + name_ct = 0; /* current name string element */ + name_ptr = pmbbo->zrst; /* first name string element */ + val_ptr = &(pmbbo->zrvl); /* first value element */ + while (name_ct < parmBlock->gpibCmds[dpvt->parm].namelist->count) + { + if (name_ptr[0] == '\0') + { + strcpy(name_ptr, parmBlock->gpibCmds[dpvt->parm].namelist->item[name_ct]); + *val_ptr = parmBlock->gpibCmds[dpvt->parm].namelist->value[name_ct]; + } + name_ct++; + name_ptr += sizeof(pmbbo->zrst); + val_ptr++; + } + } + return(2); +} + +/****************************************************************************** + * + * stringin record init + * + ******************************************************************************/ + +long +devGpibLib_initSi(psi, process) +struct stringinRecord *psi; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(psi->dset))->funPtr[psi->dset->number]); + + /* do common initialization */ + if (result = devGpibLib_initXx((caddr_t) psi, &psi->inp)) + { + return(result); + } + /* make sure the command type makes sendse for the record type */ + + if (parmBlock->gpibCmds[((struct gpibDpvt *)psi->dpvt)->parm].type != GPIBREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)psi->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)psi->dpvt)->parm].type != GPIBRAWREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)psi->dpvt)->parm].type != GPIBREADW) + { + sprintf(message, "%s: devGpibLib_initLi: invalid command type for an SI record in param %d\n", psi->name, ((struct gpibDpvt *)psi->dpvt)->parm); + errMessage(S_db_badField, message); + psi->pact = TRUE; + return(S_db_badField); + } + return(0); +} + +/****************************************************************************** + * + * stringout record init + * + ******************************************************************************/ + +long +devGpibLib_initSo(pso, process) +struct stringoutRecord *pso; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pso->dset))->funPtr[pso->dset->number]); + + /* do common initialization */ + if (result = devGpibLib_initXx((caddr_t) pso, &pso->out)) + { + return(result); + } + /* do initialization of other fields in the record that are unique + * to this record type */ + + if (parmBlock->gpibCmds[((struct gpibDpvt *)pso->dpvt)->parm].type != GPIBWRITE && + parmBlock->gpibCmds[((struct gpibDpvt *)pso->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pso->dpvt)->parm].type != GPIBCMD && + parmBlock->gpibCmds[((struct gpibDpvt *)pso->dpvt)->parm].type != GPIBCNTL) + { + sprintf(message, "%s: devGpibLib_initSo: invalid command typefor a SO record in param %d\n", pso->name, ((struct gpibDpvt *)pso->dpvt)->parm); + errMessage(S_db_badField, message); + pso->pact = TRUE; + return(S_db_badField); + } + + return(0); +} + +/****************************************************************************** + * + * This init routine is common to all record types + * + ******************************************************************************/ +long +devGpibLib_initXx(prec, plink) +struct dbCommon *prec; +struct link *plink; +{ + struct devGpibParmBlock *parmBlock; + struct gpibDpvt *pdpvt; + struct dbCommon *pdbCommon = (struct dbCommon *)prec; + char message[100]; + struct gpibCmd *pCmd; + char foundIt; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(prec->dset))->funPtr[prec->dset->number]); + + if (*parmBlock->debugFlag) + printf("initXx dealing with record >%s< device >%s<\n", prec->name, parmBlock->name); + /* allocate space for the private structure */ + pdpvt = (struct gpibDpvt *) malloc(sizeof(struct gpibDpvt)); + prec->dpvt = (void *) pdpvt; + + pdpvt->head.dmaTimeout = parmBlock->dmaTimeout; + + pdpvt->precord = prec; + pdpvt->parm = -1; /* In case the sscanf fails */ + pdpvt->linkType = plink->type; + + switch (plink->type) { + case GPIB_IO: /* Is a straight Network Instruments link */ + pdpvt->head.link = plink->value.gpibio.link; /* NI link number */ + pdpvt->head.device = plink->value.gpibio.addr; /* gpib dev address */ + sscanf(plink->value.gpibio.parm, "%hd", &(pdpvt->parm)); + pdpvt->head.bitBusDpvt = NULL; /* no bitbus data needed */ + if (*parmBlock->debugFlag > 5) + { + printf("initXx GPIB_IO link info for record '%s':\n", prec->name); + printf(" link: '%d'\n", plink->value.gpibio.link); + printf(" addr: '%d'\n", plink->value.gpibio.addr); + printf(" parm: '%s'\n", plink->value.gpibio.parm); + } + break; + + case BBGPIB_IO: /* Is a bitbus -> gpib link */ + pdpvt->head.device = plink->value.bbgpibio.gpibaddr; /* dev address */ + sscanf(plink->value.bbgpibio.parm, "%hd", &(pdpvt->parm)); + pdpvt->head.bitBusDpvt = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead)); + pdpvt->head.bitBusDpvt->txMsg.data = (unsigned char *) malloc(BB_MAX_DAT_LEN); + pdpvt->head.bitBusDpvt->rxMsg.data = (unsigned char *) malloc(BB_MAX_DAT_LEN); + pdpvt->head.bitBusDpvt->txMsg.node = plink->value.bbgpibio.bbaddr; /* bug node address */ + pdpvt->head.bitBusDpvt->link = plink->value.bbgpibio.link; /* bug link number */ + pdpvt->head.link = plink->value.bbgpibio.link; + pdpvt->head.bitBusDpvt->rxMaxLen = sizeof(struct bitBusMsg); + if (*parmBlock->debugFlag > 5) + { + printf("initXx BBGPIB_IO link info for record '%s':\n", prec->name); + printf(" link: '%d'\n", plink->value.bbgpibio.link); + printf(" bbaddr: '%d'\n", plink->value.bbgpibio.bbaddr); + printf(" gpibaddr: '%d'\n", plink->value.bbgpibio.gpibaddr); + printf(" parm: '%s'\n", plink->value.bbgpibio.parm); + } + break; + + default: + strcpy(message, pdbCommon->name); + sprintf(message,": init_record : GPIB link type %ld is invalid", plink->type); + errMessage(S_db_badField, message); + prec->pact = TRUE; /* keep record from being processed */ + return(S_db_badField); + break; + } + /* Try to find the hardware private structure */ + + if (*parmBlock->debugFlag > 5) + printf("%s: looking for hwpvt structure for link %d device %d\n", + parmBlock->name, pdpvt->head.link, pdpvt->head.device); + + foundIt = 0; + pdpvt->phwpvt = parmBlock->hwpvtHead; + while ((pdpvt->phwpvt != NULL) && !foundIt) + { + if (*parmBlock->debugFlag > 5) + printf("%s: Checking hwpvt %p, type %d, link %d, device %d\n", + parmBlock->name, pdpvt->phwpvt, pdpvt->phwpvt->linkType, + pdpvt->phwpvt->link, pdpvt->phwpvt->device); + + if (pdpvt->phwpvt->linkType == plink->type && + pdpvt->phwpvt->link == pdpvt->head.link && + pdpvt->phwpvt->device == pdpvt->head.device) + if (plink->type == BBGPIB_IO) + { + if (pdpvt->phwpvt->bug == pdpvt->head.bitBusDpvt->txMsg.node) + foundIt = 1; + else + pdpvt->phwpvt = pdpvt->phwpvt->next; + } + else + foundIt = 1; + else + pdpvt->phwpvt = pdpvt->phwpvt->next; /* check the next one */ + } + if (!foundIt) + { /* I couldn't find it. Allocate a new one */ + + if (*parmBlock->debugFlag) + printf("%s: allocating a hwpvt structure for link %d device %d\n", + parmBlock->name, pdpvt->head.link, pdpvt->head.device); + + pdpvt->phwpvt = (struct hwpvt *) malloc(sizeof (struct hwpvt)); + pdpvt->phwpvt->next = parmBlock->hwpvtHead; /* put in the list */ + parmBlock->hwpvtHead = pdpvt->phwpvt; + + pdpvt->phwpvt->linkType = plink->type; + pdpvt->phwpvt->link = pdpvt->head.link; + pdpvt->phwpvt->device = pdpvt->head.device; + + if (pdpvt->phwpvt->linkType == BBGPIB_IO) + pdpvt->phwpvt->bug = pdpvt->head.bitBusDpvt->txMsg.node; + + pdpvt->phwpvt->tmoVal = 0; + pdpvt->phwpvt->tmoCount = 0; + pdpvt->phwpvt->srqCallback = NULL; + pdpvt->phwpvt->unsolicitedDpvt = NULL; + pdpvt->phwpvt->parm = (caddr_t)NULL; + + if (*parmBlock->debugFlag) + printf("issuing IBGENLINK ioctl for link %d\n", pdpvt->phwpvt->link); + + /* Tell the driver we are going to use this link some time */ + (*(drvGpib.ioctl))(pdpvt->phwpvt->linkType, pdpvt->phwpvt->link, pdpvt->phwpvt->bug, IBGENLINK, -1, NULL); + } + /* Fill in the dpvt->ibLink field (The driver uses it) */ + + if (*parmBlock->debugFlag) + printf("initXx doing an ioctl-IBGETLINK for record >%s< device >%s<\n", prec->name, parmBlock->name); + + (*(drvGpib.ioctl))(pdpvt->phwpvt->linkType, pdpvt->phwpvt->link, pdpvt->phwpvt->bug, IBGETLINK, -1, &(pdpvt->head.pibLink)); + + if (*parmBlock->debugFlag) + printf("ioctl-IBGETLINK returned %p\n", pdpvt->head.pibLink); + + if (*parmBlock->debugFlag > 5) + printf("initXx checking GPIB address for record >%s< device >%s<\n", prec->name, parmBlock->name); + + /* Check for valid GPIB address */ + if ((pdpvt->head.device < 0) || (pdpvt->head.device >= IBAPERLINK)) + { + strcpy(message, pdbCommon->name); + strcat(message,": init_record : GPIB address out of range"); + errMessage(S_db_badField,message); + prec->pact = TRUE; /* keep record from being processed */ + return(S_db_badField); + } + + if (*parmBlock->debugFlag > 5) + printf("initXx checking param entry for record >%s< device >%s< parsed parm number %d\n", prec->name, parmBlock->name, pdpvt->parm); + + /* Check for valid param entry */ + if ((pdpvt->parm < 0) || (pdpvt->parm > parmBlock->numparams)) + { + strcpy(message, pdbCommon->name); + strcat(message,": init_record : GPIB parameter # out of range"); + errMessage(S_db_badField,message); + prec->pact = TRUE; /* keep record from being processed */ + return(S_db_badField); + } + + if (*parmBlock->debugFlag > 5) + printf("initXx checking record coherency for record >%s< device >%s<\n", prec->name, parmBlock->name); + + /* make sure that the record type matches the GPIB port type (jrw) */ + if (parmBlock->gpibCmds[pdpvt->parm].rec_typ != (gDset *)prec->dset ) + { + sprintf(message, "%s: init_record: record type invalid for spec'd GPIB param #%d", pdbCommon->name, pdpvt->parm); + errMessage(S_db_badField,message); + prec->pact = TRUE; /* keep record from being processed */ + return(S_db_badField); + } + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + if(pCmd->msgLen > 0) + pdpvt->msg = (char *)(malloc(pCmd->msgLen)); + if(pCmd->rspLen > 0) + pdpvt->rsp = (char *)(malloc(pCmd->rspLen)); + + if(parmBlock->srqHandler != NULL) + { + /* If user spec'd the process on unsolicited SRQ parameter mark it */ + if (pdpvt->parm == parmBlock->magicSrq) + { + if (pdpvt->phwpvt->unsolicitedDpvt != NULL) + { + strcpy(message, pdbCommon->name); + strcat(message,": init_record: can only have 1 SRQ scanned record per GPIB device"); + errMessage(S_db_badField,message); + prec->pact = TRUE; /* keep record from being processed */ + return(S_db_badField); + } + if (pdbCommon->scan == SCAN_IO_EVENT) + { + pdpvt->phwpvt->unsolicitedDpvt = pdpvt; + } + } + + /* + * Ok to re-register a handler for the same device. + * Just don't do it after init time is over! + */ + (*(drvGpib.registerSrqCallback))(pdpvt->head.pibLink, pdpvt->head.device, parmBlock->srqHandler, pdpvt->phwpvt); + } + + /* fill in the work routine pointer */ + pdpvt->head.workStart = (int (*)()) (((gDset*)(prec->dset))->funPtr[(((gDset*)(prec->dset))->number) + 1]); + return(0); +} + +/****************************************************************************** + * + * These are the functions that are called to actually communicate with + * the GPIB device. + * + * They are called by record-processing to perform an I/O operation. In the + * GPIB case, all I/O is done via anynchronous processing, so all these + * functions do is queue requests for the driver to take care of when it is + * ready. + * + ******************************************************************************/ +/****************************************************************************** + * + * read_ai() + * + ******************************************************************************/ + +long +devGpibLib_readAi(pai) +struct aiRecord *pai; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pai->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pai->dset))->funPtr[pai->dset->number]); + + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + if (pai->pact) + { + return(2); /* work is all done, return '2' to indicate val */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dpvt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pai,MAJOR_ALARM,VALID_ALARM); + return(0); + } + pai->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * write_ao() + * + ******************************************************************************/ + +long +devGpibLib_writeAo(pao) +struct aoRecord *pao; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pao->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pao->dset))->funPtr[pao->dset->number]); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + + if (pao->pact) + { + return(0); /* work is all done, finish processing */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dvpt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pao,WRITE_ALARM,VALID_ALARM); + return(0); + } + pao->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * read_li() + * + ******************************************************************************/ + +long +devGpibLib_readLi(pli) +struct longinRecord *pli; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pli->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pli->dset))->funPtr[pli->dset->number]); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + if (pli->pact) + { + return(2); /* work is all done, return '2' to indicate val */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dpvt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pli,MAJOR_ALARM,VALID_ALARM); + return(0); + } + pli->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * write_lo() + * + ******************************************************************************/ + +long +devGpibLib_writeLo(plo) +struct longoutRecord *plo; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(plo->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(plo->dset))->funPtr[plo->dset->number]); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + + if (plo->pact) + { + return(0); /* work is all done, finish processing */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dvpt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(plo,WRITE_ALARM,VALID_ALARM); + return(0); + } + plo->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * read_bi() + * + ******************************************************************************/ + +long +devGpibLib_readBi(pbi) +struct biRecord *pbi; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pbi->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pbi->dset))->funPtr[pbi->dset->number]); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + + if (pbi->pact) + { + return(0); /* work is all done, finish processing */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dvpt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM); + return(0); + } + pbi->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * write_bo() + * + ******************************************************************************/ + +long +devGpibLib_writeBo(pbo) +struct boRecord *pbo; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pbo->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pbo->dset))->funPtr[pbo->dset->number]); + + if (*parmBlock->debugFlag) + printf("devGpibLib_writeBo() entered\n"); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + + if (pbo->pact) + { + return(0); /* work is all done, finish processing */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dvpt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pbo,WRITE_ALARM,VALID_ALARM); + return(0); + } + pbo->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * read_mbbi() + * + ******************************************************************************/ + +long +devGpibLib_readMbbi(pmbbi) +struct mbbiRecord *pmbbi; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pmbbi->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pmbbi->dset))->funPtr[pmbbi->dset->number]); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + + if (pmbbi->pact) + { + return(0); /* work is all done, finish processing */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dvpt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM); + return(0); + } + pmbbi->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * write_mbbo() + * + ******************************************************************************/ + +long +devGpibLib_writeMbbo(pmbbo) +struct mbboRecord *pmbbo; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pmbbo->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pmbbo->dset))->funPtr[pmbbo->dset->number]); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + + if (pmbbo->pact) + { + return(0); /* work is all done, finish processing */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dvpt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM); + return(0); + } + pmbbo->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * read_stringin() + * + ******************************************************************************/ + +long +devGpibLib_readSi(psi) +struct stringinRecord *psi; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(psi->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(psi->dset))->funPtr[psi->dset->number]); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + if (psi->pact) + { + return(2); /* work is all done, return '2' to indicate val */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dvpt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(psi,MAJOR_ALARM,VALID_ALARM); + return(0); + } + psi->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * write_stringout() + * + ******************************************************************************/ + +long +devGpibLib_writeSo(pso) +struct stringoutRecord *pso; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pso->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pso->dset))->funPtr[pso->dset->number]); + + pCmd = &parmBlock->gpibCmds[pdpvt->parm]; + + if (pso->pact) + { + return(0); /* work is all done, finish processing */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dvpt field on transaction fifo */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pso,WRITE_ALARM,VALID_ALARM); + return(0); + } + pso->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * Routines that do the actual GPIB work. They are called by the linkTask in + * response to work requests passed in from the read_xx and write_xx functions + * above. + * + ******************************************************************************/ +/****************************************************************************** + * + * devGpibLib_aiGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_aiGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + struct aiRecord *pai= ((struct aiRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pai->dset))->funPtr[pai->dset->number]); + + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* go send predefined cmd msg and read response into msg[] */ + + if(*(parmBlock->debugFlag)) + printf("devGpibLib_aiGpibWork: starting ...command type = %d\n",pCmd->type); + + if (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR) + { + devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + else + { + if (pCmd->type != GPIBREADW) + devGpibLib_aiGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ + else + { + if (*(parmBlock->debugFlag) || ibSrqDebug) + printf("%s: marking srq Handler for READW operation\n", parmBlock->name); + pdpvt->phwpvt->srqCallback = (int (*)())(((gDset*)(pai->dset))->funPtr[pai->dset->number + 2]); + pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ + return(BUSY); /* indicate device still in use */ + } + } + return(IDLE); /* indicate device is now idle */ +} + +/****************************************************************************** + * + * devGpibLib_aiGpibSrq() + * + ******************************************************************************/ + +int +devGpibLib_aiGpibSrq(pdpvt, srqStatus) +struct gpibDpvt *pdpvt; +int srqStatus; +{ + struct aiRecord *pai= ((struct aiRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pai->dset))->funPtr[pai->dset->number]); + + if (*parmBlock->debugFlag || ibSrqDebug) + printf("devGpibLib_aiGpibSrq(%p, 0x%2.2X): processing srq\n", pdpvt, srqStatus); + + pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ + pdpvt->phwpvt->parm = (caddr_t)NULL; + + /* read the response back */ + if (devGpibLib_xxGpibWork(pdpvt, GPIBRAWREAD, -1) == ERROR) + { + devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + + devGpibLib_aiGpibFinish(pdpvt); /* and finish the processing */ + return(IDLE); /* indicate device now idle */ +} + +/****************************************************************************** + * + * devGpibLib_aiGpibFinish() + * + ******************************************************************************/ + +int +devGpibLib_aiGpibFinish(pdpvt) +struct gpibDpvt *pdpvt; +{ + double value; + struct aiRecord *pai = ((struct aiRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + struct gpibCmd *pCmd; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pai->dset))->funPtr[pai->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + if (pCmd->convert != NULL) + { + if(*parmBlock->debugFlag) + printf("devGpibLib_aiGpibWork: calling convert ...\n"); + + (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* interpret msg with predefined format and write into .val */ + { + /* scan response string, return value will be 1 if successful */ + if(sscanf(pdpvt->msg,pCmd->format,&value)) + { + pai->val = value; + pai->udf = FALSE; + } + else /* sscanf did not find or assign the parameter */ + { + devGpibLib_setPvSevr(pai,READ_ALARM,VALID_ALARM); + } + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(0); +} + +/****************************************************************************** + * + * devGpibLib_aoGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_aoGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + int cnvrtStat = OK; + struct aoRecord *pao= ((struct aoRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + struct gpibCmd *pCmd; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pao->dset))->funPtr[pao->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* generate command string to be sent */ + + /* call convert routine, if defined */ + if (pCmd->convert != NULL) + { + cnvrtStat = (*(pCmd->convert))(pdpvt, pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* generate msg using predefined format and current val */ + { + if (pCmd->type == GPIBWRITE) /* only if needs formatting */ + sprintf(pdpvt->msg, pCmd->format, pao->oval); + } + + /* go access board with this message, unless convert was unsuccessful */ + if ((cnvrtStat == ERROR) || (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR)) + { + devGpibLib_setPvSevr(pao,WRITE_ALARM,VALID_ALARM); + } + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(IDLE); +} + +/****************************************************************************** + * + * devGpibLib_liGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_liGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + struct longinRecord *pli= ((struct longinRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + struct gpibCmd *pCmd; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pli->dset))->funPtr[pli->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* go send predefined cmd msg and read response into msg[] */ + + if(*parmBlock->debugFlag) + printf("devGpibLib_liGpibWork: starting ...\n"); + + if (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR) + { + devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + else + { + if (pCmd->type != GPIBREADW) + devGpibLib_liGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ + else + { + pdpvt->phwpvt->srqCallback = (int(*)())(((gDset*)(pli->dset))->funPtr[pli->dset->number + 2]); + pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ + return(BUSY); /* indicate device still in use */ + } + } + return(IDLE); /* indicate device is now idle */ +} + +/****************************************************************************** + * + * devGpibLib_liGpibSrq() + * + ******************************************************************************/ + +int +devGpibLib_liGpibSrq(pdpvt, srqStatus) +struct gpibDpvt *pdpvt; +int srqStatus; +{ + struct longinRecord *pli= ((struct longinRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pli->dset))->funPtr[pli->dset->number]); + + if (*parmBlock->debugFlag || ibSrqDebug) + printf("devGpibLib_liGpibSrq(%p, 0x%2.2X): processing srq\n", pdpvt, srqStatus); + + pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ + pdpvt->phwpvt->parm = (caddr_t)NULL; + + /* do actual SRQ processing in here */ + + /* read the response back */ + if (devGpibLib_xxGpibWork(pdpvt, GPIBRAWREAD, -1) == ERROR) + { + devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + + devGpibLib_liGpibFinish(pdpvt); /* and finish the processing */ + return(IDLE); /* indicate device now idle */ +} + +/****************************************************************************** + * + * devGpibLib_liGpibFinish() + * + ******************************************************************************/ + +int +devGpibLib_liGpibFinish(pdpvt) +struct gpibDpvt *pdpvt; +{ + unsigned long value; + struct longinRecord *pli = ((struct longinRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pli->dset))->funPtr[pli->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + if (pCmd->convert != NULL) + { + if(*parmBlock->debugFlag) + printf("devGpibLib_liGpibWork: calling convert ...\n"); + (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* interpret msg with predefined format and write into .val */ + { + /* scan response string, return value will be 1 if successful */ + if(sscanf(pdpvt->msg,pCmd->format,&value)) + { + pli->val = value; + pli->udf = FALSE; + } + else /* sscanf did not find or assign the parameter */ + { + devGpibLib_setPvSevr(pli,READ_ALARM,VALID_ALARM); + } + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(0); +} + +/****************************************************************************** + * + * devGpibLib_loGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_loGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + int cnvrtStat = OK; + struct longoutRecord *plo= ((struct longoutRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(plo->dset))->funPtr[plo->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* generate command string to be sent */ + + /* call convert routine, if defined */ + if (pCmd->convert != NULL) + { + cnvrtStat = (*(pCmd->convert))(pdpvt, pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* generate msg using predefined format and current val */ + { + if (pCmd->type == GPIBWRITE) /* only if needs formatting */ + sprintf(pdpvt->msg, pCmd->format, plo->val); + } + + /* go access board with this message, unless convert was unsuccessful */ + if ((cnvrtStat == ERROR) || (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR)) + { + devGpibLib_setPvSevr(plo,WRITE_ALARM,VALID_ALARM); + } + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + return(IDLE); +} + +/****************************************************************************** + * + * devGpibLib_biGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_biGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + struct biRecord *pbi= ((struct biRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pbi->dset))->funPtr[pbi->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* go send predefined cmd msg and read response into msg[] */ + + if (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR) + { + devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + else /* interpret response that came back */ + { + if (pCmd->type != GPIBREADW && pCmd->type != GPIBEFASTIW) + devGpibLib_biGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ + else + { + pdpvt->phwpvt->srqCallback = (int(*)())(((gDset*)(pbi->dset))->funPtr[pbi->dset->number + 2]); + pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ + return(BUSY); /* indicate device still in use */ + } + } + return(IDLE); +} + +/****************************************************************************** + * + * devGpibLib_biGpibSrq() + * + ******************************************************************************/ + +int +devGpibLib_biGpibSrq(pdpvt, srqStatus) +struct gpibDpvt *pdpvt; +int srqStatus; +{ + struct biRecord *pbi= ((struct biRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pbi->dset))->funPtr[pbi->dset->number]); + + if (*parmBlock->debugFlag || ibSrqDebug) + printf("devGpibLib_biGpibSrq(%p, 0x%2.2X): processing srq\n", pdpvt, srqStatus); + + pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ + pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ + + /* read the response back */ + if (devGpibLib_xxGpibWork(pdpvt, GPIBRAWREAD, -1) == ERROR) + { + devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + + devGpibLib_biGpibFinish(pdpvt); /* and finish the processing */ + return(IDLE); /* indicate device now idle */ +} + +/****************************************************************************** + * + * devGpibLib_biGpibFinish() + * + ******************************************************************************/ + +int +devGpibLib_biGpibFinish(pdpvt) +struct gpibDpvt *pdpvt; +{ + unsigned long value; + int status; + struct biRecord *pbi= ((struct biRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pbi->dset))->funPtr[pbi->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + if (pCmd->convert != NULL) + { + (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* interpret msg with predefined format and write into .rval */ + { + if (pCmd->type == GPIBEFASTI || pCmd->type == GPIBEFASTIW) + { /* Check the response against enumerations */ + if ((status = checkEnums(pdpvt->msg, pCmd->P3)) >= 0) + pbi->rval = status; + else + devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM); + } + else + { /* Scan response string, return value will be 1 if successful */ + if(sscanf(pdpvt->msg,pCmd->format, &value)) + pbi->rval = value; + else /* sscanf did not find or assign the parameter */ + devGpibLib_setPvSevr(pbi,READ_ALARM,VALID_ALARM); + } + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(0); +} + +/****************************************************************************** + * + * devGpibLib_boGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_boGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + int cnvrtStat = OK; + struct boRecord *pbo= ((struct boRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pbo->dset))->funPtr[pbo->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* generate command string to be sent */ + + /* call convert routine, if defined */ + if (pCmd->convert != NULL) + { + cnvrtStat = (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* generate msg using predefined format and current val */ + { + if (pCmd->type == GPIBWRITE) /* only if needs formatting */ + sprintf(pdpvt->msg, pCmd->format, (unsigned int)pbo->val); + } + + /* go access board with this message, unless convert was unsuccessful */ + if ((cnvrtStat == ERROR) || (devGpibLib_xxGpibWork(pdpvt, pCmd->type, pbo->val? 1 : 0) == ERROR)) + { + devGpibLib_setPvSevr(pbo,WRITE_ALARM,VALID_ALARM); + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(IDLE); +} + +/****************************************************************************** + * + * devGpibLib_mbbiGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_mbbiGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + struct mbbiRecord *pmbbi= ((struct mbbiRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pmbbi->dset))->funPtr[pmbbi->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* go send predefined cmd msg and read string response into msg[] */ + + if (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR) + { + devGpibLib_setPvSevr(pmbbi,WRITE_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + else + { + if (pCmd->type != GPIBREADW) + devGpibLib_mbbiGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ + else + { + pdpvt->phwpvt->srqCallback = (int(*)())(((gDset*)(pmbbi->dset))->funPtr[pmbbi->dset->number + 2]); + pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ + return(BUSY); /* indicate device still in use */ + } + } + return(IDLE); +} + +/****************************************************************************** + * + * devGpibLib_mbbiGpibSrq() + * + ******************************************************************************/ + +int +devGpibLib_mbbiGpibSrq(pdpvt, srqStatus) +struct gpibDpvt *pdpvt; +int srqStatus; +{ + struct mbbiRecord *pmbbi= ((struct mbbiRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pmbbi->dset))->funPtr[pmbbi->dset->number]); + + if (*parmBlock->debugFlag || ibSrqDebug) + printf("devGpibLib_mbbiGpibSrq(%p, 0x%2.2X): processing srq\n", pdpvt, srqStatus); + + /* do actual SRQ processing in here */ + + pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ + pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ + + /* read the response back */ + if (devGpibLib_xxGpibWork(pdpvt, GPIBRAWREAD, -1) == ERROR) + { + devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + + devGpibLib_mbbiGpibFinish(pdpvt); /* and finish the processing */ + return(IDLE); /* indicate device now idle */ +} + +/****************************************************************************** + * + * devGpibLib_mbbiGpibFinish() + * + ******************************************************************************/ + +int +devGpibLib_mbbiGpibFinish(pdpvt) +struct gpibDpvt *pdpvt; +{ + unsigned long value; + int status; + struct mbbiRecord *pmbbi= ((struct mbbiRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pmbbi->dset))->funPtr[pmbbi->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + if (pCmd->convert != NULL) + { + (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* interpret msg with predefined format and write into .rval */ + { + if (pCmd->type == GPIBEFASTI || pCmd->type == GPIBEFASTIW) + { /* Check the response against enumerations */ + if ((status = checkEnums(pdpvt->msg, pCmd->P3)) >= 0) + pmbbi->rval = status; + else + devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM); + } + else + { /* Scan response string, return value will be 1 if successful */ + if(sscanf(pdpvt->msg, pCmd->format, &value)) + pmbbi->rval = value; + else /* sscanf did not find or assign the parameter */ + devGpibLib_setPvSevr(pmbbi,READ_ALARM,VALID_ALARM); + } + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(0); +} + +/****************************************************************************** + * + * devGpibLib_mbboGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_mbboGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + int cnvrtStat = OK; + struct mbboRecord *pmbbo= ((struct mbboRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pmbbo->dset))->funPtr[pmbbo->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* generate command string to be sent */ + + /* call convert routine, if defined */ + if (pCmd->convert != NULL) + { + cnvrtStat = (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* generate msg using predefined format and current val */ + { + if (pCmd->type == GPIBWRITE) /* only if needs formatting */ + sprintf(pdpvt->msg, pCmd->format, (unsigned int)pmbbo->rval); + } + + /* go access board with this message, unless convert was unsuccessful */ + /* NOTE the use of val instead of rval for the EFASTO operation index! */ + if ((cnvrtStat == ERROR) || (devGpibLib_xxGpibWork(pdpvt, pCmd->type, pmbbo->val) == ERROR)) + { + devGpibLib_setPvSevr(pmbbo,WRITE_ALARM,VALID_ALARM); + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(IDLE); +} + +/****************************************************************************** + * + * devGpibLib_stringinGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_stringinGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + struct stringinRecord *psi=((struct stringinRecord*)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(psi->dset))->funPtr[psi->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* go send predefined cmd msg and read response into msg[] */ + + if(*parmBlock->debugFlag) + printf("devGpibLib_stringinGpibWork: starting ...\n"); + + if (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR) + { + devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + else + { + if (pCmd->type != GPIBREADW) + devGpibLib_stringinGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ + else + { + pdpvt->phwpvt->srqCallback = (int(*)())(((gDset*)(psi->dset))->funPtr[psi->dset->number + 2]); + pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ + return(BUSY); /* indicate device still in use */ + } + } + return(IDLE); +} + +/****************************************************************************** + * + * devGpibLib_stringinGpibSrq() + * + ******************************************************************************/ + +int +devGpibLib_stringinGpibSrq(pdpvt, srqStatus) +struct gpibDpvt *pdpvt; +int srqStatus; +{ + struct stringinRecord *psi= ((struct stringinRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(psi->dset))->funPtr[psi->dset->number]); + + if (*parmBlock->debugFlag || ibSrqDebug) + printf("devGpibLib_stringinGpibSrq(%p, 0x%2.2X): processing srq\n", pdpvt, srqStatus); + + /* do actual SRQ processing in here */ + + pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ + pdpvt->phwpvt->parm = (caddr_t)NULL; /* unmark the handler */ + + /* read the response back */ + if (devGpibLib_xxGpibWork(pdpvt, GPIBRAWREAD, -1) == ERROR) + { + devGpibLib_setPvSevr(psi,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + + devGpibLib_stringinGpibFinish(pdpvt); /* and finish the processing */ + return(IDLE); /* indicate device now idle */ +} + +/****************************************************************************** + * + * devGpibLib_stringinGpibFinish() + * + ******************************************************************************/ + +int +devGpibLib_stringinGpibFinish(pdpvt) +struct gpibDpvt *pdpvt; +{ + struct stringinRecord *psi=((struct stringinRecord*)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(psi->dset))->funPtr[psi->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + if (pCmd->convert != NULL) + { + (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + } + else + { /* BUG -- why can't we just read it into the val field? */ + /* BUG -- length should not be hard coded here */ + + strncpy(psi->val,pdpvt->msg,39); + psi->val[40] = '\0'; + psi->udf = FALSE; + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(0); +} + +/****************************************************************************** + * + * devGpibLib_stringoutGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_stringoutGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + int cnvrtStat = OK; + struct stringoutRecord *pso= ((struct stringoutRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pso->dset))->funPtr[pso->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* generate command string to be sent */ + + /* call convert routine, if defined */ + if (pCmd->convert != NULL) + { + cnvrtStat = (*(pCmd->convert))(pdpvt, pCmd->P1, pCmd->P2, pCmd->P3); + } + else + { /* BUG -- why can't we just write it from the val field? */ + strncpy(pdpvt->msg, pso->val, 40); + } + + /* go access board with this message, unless convert was unsuccessful */ + if ((cnvrtStat == ERROR) || (devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1) == ERROR)) + { + devGpibLib_setPvSevr(pso,WRITE_ALARM,VALID_ALARM); + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(IDLE); +} + +/****************************************************************************** + * + * devGpibLib_xxGpibWork() + * + * Generic function used to read and write strings to the GPIB instruments + * by calling the device driver. + * + ******************************************************************************/ + +int +devGpibLib_xxGpibWork(pdpvt, cmdType, val) +struct gpibDpvt *pdpvt; +int cmdType; +unsigned short val; /* used for EFAST operations only */ +{ + int status = OK; + short ibnode = pdpvt->head.device; + short bbnode = -1; /* In case is a bitbus->gpib type link */ + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pdpvt->precord->dset))->funPtr[pdpvt->precord->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* If is a BBGPIB_IO link, the bug address is needed */ + if (pdpvt->linkType == BBGPIB_IO) + bbnode = pdpvt->head.bitBusDpvt->txMsg.node; + + /* + * check to see if this node has timed out within last ticks + */ + if(tickGet() < (pdpvt->phwpvt->tmoVal + parmBlock->timeWindow) ) + { + if (*parmBlock->debugFlag) + printf("devGpibLib_xxGpibWork(): timeout flush\n"); + + return(ERROR); + } + switch (cmdType) { + case GPIBWRITE: /* write the message to the GPIB listen adrs */ + + status = (*(drvGpib.writeIb))(pdpvt->head.pibLink, ibnode, pdpvt->msg, + strlen(pdpvt->msg), pdpvt->head.dmaTimeout); + + + if ((status != ERROR) && (parmBlock->respond2Writes) != -1) + { /* device responds to write commands, read the response */ + if (parmBlock->respond2Writes > 0) + { + taskDelay(parmBlock->respond2Writes); + } + + status = (*(drvGpib.readIb))(pdpvt->head.pibLink, ibnode, pdpvt->rsp, + pCmd->rspLen, pdpvt->head.dmaTimeout); + + /* if user specified a secondary convert routine, call it */ + + if (parmBlock->wrConversion != NULL) + status = (*(parmBlock->wrConversion))(status, pdpvt); + } + break; + + case GPIBREAD: /* write the command string */ + case GPIBEFASTI: + + status = (*(drvGpib.writeIb))(pdpvt->head.pibLink, ibnode, pCmd->cmd, + strlen(pCmd->cmd), pdpvt->head.dmaTimeout); + if (status == ERROR) + { + break; + } + + /* This is probably not the best way to do this... */ + /* because the read turnaround time delay should be independant of */ + /* the responds to writes flag. */ + + if (parmBlock->respond2Writes > 0) + { + taskDelay(parmBlock->respond2Writes); + } + + /* NOTICE -- This falls thru to the raw read code below! */ + + case GPIBRAWREAD: /* for SRQs, read the data w/o a sending a command */ + + /* read the instrument */ + status = (*(drvGpib.readIb))(pdpvt->head.pibLink, ibnode, pdpvt->msg, + pCmd->msgLen, pdpvt->head.dmaTimeout); + if (status == ERROR) + { + break; + } + else if (status >( (pCmd->msgLen) - 1) ) /* check length of resp */ + { /* This may or may not be an error */ + + printf("GPIB Response length equaled allocated space !!!\n"); + pdpvt->msg[(pCmd->msgLen)-1] = '\0'; /* place \0 at end */ + } + else + { + pdpvt->msg[status] = '\0'; /* terminate response with \0 */ + } + break; + + case GPIBREADW: /* for SRQs, write the command first */ + case GPIBEFASTIW: + status = (*(drvGpib.writeIb))(pdpvt->head.pibLink, ibnode, pCmd->cmd, + strlen(pCmd->cmd), pdpvt->head.dmaTimeout); + break; + + case GPIBCMD: /* write the cmd to the GPIB listen adrs */ + status = (*(drvGpib.writeIb))(pdpvt->head.pibLink, ibnode, pCmd->cmd, + strlen(pCmd->cmd), pdpvt->head.dmaTimeout); + + if ((status != ERROR) && (parmBlock->respond2Writes) != -1) + { /* device responds to write commands, read the response */ + if (parmBlock->respond2Writes > 0) + { + taskDelay(parmBlock->respond2Writes); + } + + + status = (*(drvGpib.readIb))(pdpvt->head.pibLink, ibnode, pdpvt->rsp, + pCmd->rspLen, pdpvt->head.dmaTimeout); + + /* if user specified a secondary convert routine, call it */ + + if (parmBlock->wrConversion != NULL) + status = (*(parmBlock->wrConversion))(status, pdpvt); + } + break; + case GPIBCNTL: /* send cmd with atn line active */ + status = (*(drvGpib.writeIbCmd))(pdpvt->head.pibLink, pCmd->cmd, + strlen(pCmd->cmd)); + break; + case GPIBEFASTO: /* write the enumerated cmd from the P3 array */ + if(pCmd->P3==NULL) { + epicsPrintf("%s devSup : GPIBEFASTO specified but no EFAST Table\n", + pdpvt->precord->name); + return(ERROR); + } + if(val>15) { + epicsPrintf("%s devSup : GPIBEFASTO specified but val = %hu\n", + pdpvt->precord->name,val); + return(ERROR); + } + if (pCmd->P3[val] != NULL) + { + status = (*(drvGpib.writeIb))(pdpvt->head.pibLink,ibnode, + pCmd->P3[val],strlen(pCmd->P3[val]), pdpvt->head.dmaTimeout); + if ((status != ERROR) && (parmBlock->respond2Writes) != -1) + { /* device responds to write commands, read the response */ + if (parmBlock->respond2Writes > 0) + { + taskDelay(parmBlock->respond2Writes); + } + + status = (*(drvGpib.readIb))(pdpvt->head.pibLink, ibnode, + pdpvt->rsp, pCmd->rspLen, pdpvt->head.dmaTimeout); + + /* if user specified a secondary convert routine, call it */ + + if (parmBlock->wrConversion != NULL) + status = (*(parmBlock->wrConversion))(status, pdpvt); + } + } + break; + } + if(*parmBlock->debugFlag) + printf("devGpibLib_xxGpibWork : done, status = %d\n",status); + + /* if error occurrs then mark it with time */ + if(status == ERROR) + { + (pdpvt->phwpvt->tmoCount)++; /* count number of timeouts */ + pdpvt->phwpvt->tmoVal = tickGet(); /* set last timeout time */ + } + return(status); +} + +/****************************************************************************** + * + * This function is called by the callback task. The callback task + * calls it after being given the 'go ahead' by callbackRequest() + * function calls made in the GpibWork routines defined above. + * + * The reason it is done this way is because the process() call may + * recursively call itself when records are chained and the callback + * task's stack is larger... just for that reason. + * + ******************************************************************************/ + +void +devGpibLib_processCallback(CALLBACK *pCallback) +{ + struct gpibDpvt *pDpvt; + callbackGetUser(pDpvt, pCallback); + + dbScanLock(pDpvt->precord); + (*(struct rset *)(pDpvt->precord->rset)).process(pDpvt->precord); + dbScanUnlock(pDpvt->precord); +} + +/****************************************************************************** + * + * This function is used to set alarm status information. + * + ******************************************************************************/ +long +devGpibLib_setPvSevr(pPv, status, severity) +struct dbCommon *pPv; +unsigned short severity; +short status; +{ + if (severity > pPv->nsev ) + { + pPv->nsta = status; + pPv->nsev = severity; + } + return(0); +} + +/****************************************************************************** + * + * This function is used to parse enumerated response strings. + * + * Only as many bytes as are found in the enums array elements are compared + * when searching for a match. The \0 at the end of the enums array elements + * is not considered in the comparison. + * + ******************************************************************************/ +int checkEnums(char *msg, char **enums) +{ + int i; + int j; + + i = 0; + while (enums[i] != NULL) /* check each enum until match found */ + { /* will stop on first match */ + + j = 0; /* only check as much as found in enums[i] */ + while (enums[i][j] && enums[i][j] == msg[j]) + j++; + + if (enums[i][j] == '\0') + return(i); /* found, return index */ + + i++; + } + return(-1); /* not found, return error */ +} + +/****************************************************************************** + * + * wf record init + * + ******************************************************************************/ + +long +devGpibLib_initWf(pwf, process) +struct waveformRecord *pwf; +void (*process)(); +{ + long result; + char message[100]; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pwf->dset))->funPtr[pwf->dset->number]); + + /* Do common initialization */ + if (result = devGpibLib_initXx((caddr_t) pwf, &(pwf->inp) )) + { + return(result); + } + + /* make sure the command type makes sendse for the record type */ + + if (parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBREAD && + parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBWRITE && + parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBSOFT && + parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBREADW && + parmBlock->gpibCmds[((struct gpibDpvt *)pwf->dpvt)->parm].type != GPIBRAWREAD) + { + sprintf(message, "%s: devGpibLib_initWf: invalid command type for an WF record in param %d\n", pwf->name, ((struct gpibDpvt *)pwf->dpvt)->parm); + errMessage(S_db_badField, message); + pwf->pact = TRUE; + return(S_db_badField); + } + return(0); + } + +/****************************************************************************** + * + * These are the functions that are called to actually communicate with + * the GPIB device. + * + * They are called by record-processing to perform an I/O operation. In the + * GPIB case, all I/O is done via anynchronous processing, so all these + * functions do is queue requests for the driver to take care of when it is + * ready. + * + ******************************************************************************/ +/****************************************************************************** + * + * read_wf() + * + ******************************************************************************/ + +long +devGpibLib_readWf(pwf) +struct waveformRecord *pwf; +{ + struct gpibDpvt *pdpvt = (struct gpibDpvt *)(pwf->dpvt); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pwf->dset))->funPtr[pwf->dset->number]); + + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + if (pwf->pact) + { + return(2); /* work is all done, return '2' to indicate val */ + } + else if (pCmd->type == GPIBSOFT) + { + return((*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3)); + } + else + { /* put pointer to dpvt field on ring buffer */ + if((*(drvGpib.qGpibReq))(pdpvt, pCmd->pri) == ERROR) + { + devGpibLib_setPvSevr(pwf,MAJOR_ALARM,VALID_ALARM); + return(0); + } + pwf->pact = TRUE; + return(0); + } +} + +/****************************************************************************** + * + * Routines that do the actual GPIB work. They are called by the linkTask in + * response to work requests passed in from the read_xx and write_xx functions + * above. + * + ******************************************************************************/ +/****************************************************************************** + * + * devGpibLib_wfGpibWork() + * + ******************************************************************************/ + +int +devGpibLib_wfGpibWork(pdpvt) +struct gpibDpvt *pdpvt; +{ + int OperationStatus; + struct waveformRecord *pwf= ((struct waveformRecord *)(pdpvt->precord)); + struct gpibCmd *pCmd; + struct devGpibParmBlock *parmBlock; + short ibnode = pdpvt->head.device; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pwf->dset))->funPtr[pwf->dset->number]); + + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + /* go send predefined cmd msg and read response into msg[] */ + + if(*(parmBlock->debugFlag)) + printf("devGpibLib_wfGpibWork: starting ...command type = %d\n",pCmd->type); + + + /**** Handle writes internally... the generic routine will not work ****/ + if (pCmd->type == GPIBWRITE) + { + if(tickGet() < (pdpvt->phwpvt->tmoVal + parmBlock->timeWindow) ) + { + if (*parmBlock->debugFlag) + printf("devGpibLib_xxGpibWork(): timeout flush\n"); + + OperationStatus = ERROR; + } + else if (pCmd->convert == NULL) + { + if (*parmBlock->debugFlag) + printf("devGpibLib_xxGpibWork(): Waveform write command w/o conversion routine spec'd\n"); + + OperationStatus = ERROR; + } + else + { + if(*parmBlock->debugFlag) + printf("devGpibLib_wfGpibWork: calling convert ...\n"); + + (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + + OperationStatus = (*(drvGpib.writeIb))(pdpvt->head.pibLink, + ibnode, pdpvt->msg, pwf->nord, pdpvt->head.dmaTimeout); + + if(*parmBlock->debugFlag) + printf("devGpibLib_xxGpibWork : done, status = %d\n",OperationStatus); + } + /* if error occurrs then mark it with time */ + if(OperationStatus == ERROR) + { + (pdpvt->phwpvt->tmoCount)++; /* count timeouts */ + pdpvt->phwpvt->tmoVal = tickGet(); /* set last timeout time */ + } + } + else + { + OperationStatus = devGpibLib_xxGpibWork(pdpvt, pCmd->type, -1); + } + + if (OperationStatus == ERROR) + { + devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM); + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + else + { + if (pCmd->type != GPIBREADW) + devGpibLib_wfGpibFinish(pdpvt); /* If not waiting on SRQ, finish */ + else + { + if (*(parmBlock->debugFlag) || ibSrqDebug) + printf("%s: marking srq Handler for READW operation\n", parmBlock->name); + pdpvt->phwpvt->srqCallback = (int (*)())(((gDset*)(pwf->dset))->funPtr[pwf->dset->number + 2]); + pdpvt->phwpvt->parm = (caddr_t)pdpvt; /* mark the handler */ + return(BUSY); /* indicate device still in use */ + } + } + return(IDLE); /* indicate device is now idle */ +} + +/****************************************************************************** + * + * devGpibLib_wfGpibSrq() + * + ******************************************************************************/ + +int +devGpibLib_wfGpibSrq(pdpvt, srqStatus) +struct gpibDpvt *pdpvt; +int srqStatus; +{ + struct waveformRecord *pwf= ((struct waveformRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pwf->dset))->funPtr[pwf->dset->number]); + + if (*parmBlock->debugFlag || ibSrqDebug) + printf("devGpibLib_wfGpibSrq(%p, 0x%2.2X): processing srq\n", pdpvt, srqStatus); + + pdpvt->phwpvt->srqCallback = NULL; /* unmark the handler */ + pdpvt->phwpvt->parm = (caddr_t)NULL; + + /* read the response back */ + if (devGpibLib_xxGpibWork(pdpvt, GPIBRAWREAD, -1) == ERROR) + { + devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM); + + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + } + + devGpibLib_wfGpibFinish(pdpvt); /* and finish the processing */ + return(IDLE); /* indicate device now idle */ +} + +/****************************************************************************** + * + * devGpibLib_wfGpibFinish() + * + ******************************************************************************/ + +int +devGpibLib_wfGpibFinish(pdpvt) +struct gpibDpvt *pdpvt; +{ + struct waveformRecord *pwf = ((struct waveformRecord *)(pdpvt->precord)); + struct devGpibParmBlock *parmBlock; + struct gpibCmd *pCmd; + + parmBlock = (struct devGpibParmBlock *)(((gDset*)(pwf->dset))->funPtr[pwf->dset->number]); + pCmd = &(parmBlock->gpibCmds[pdpvt->parm]); + + if (pCmd->type != GPIBWRITE) + { + if (pCmd->convert != NULL) + { + if(*parmBlock->debugFlag) + printf("devGpibLib_wfGpibWork: calling convert ...\n"); + + (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); + } + else /* for waveforms no standard conversion is supplied */ + { + devGpibLib_setPvSevr(pwf,READ_ALARM,VALID_ALARM); + } + } + RegisterProcessCallback(&pdpvt->head.callback, priorityLow, pdpvt); + + return(0); +} diff --git a/src/vxWorks/dev/gpibDev/devCommonGpib.h b/src/vxWorks/dev/gpibDev/devCommonGpib.h new file mode 100644 index 000000000..77cb9de68 --- /dev/null +++ b/src/vxWorks/dev/gpibDev/devCommonGpib.h @@ -0,0 +1,348 @@ +/* devCommonGpib.h */ +/* share/epicsH/devCommonGpib.h $Id$ */ +/* + * Author: John Winans + * Date: 11-19-91 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1988, 1989, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * All rights reserved. No part of this publication may be reproduced, + * stored in a retrieval system, transmitted, in any form or by any + * means, electronic, mechanical, photocopying, recording, or otherwise + * without prior written permission of Los Alamos National Laboratory + * and Argonne National Laboratory. + * + * Modification Log: + * ----------------- + * .01 11-19-91 jrw Initial release + * .02 02-26-92 jrw removed declaration of callbackRequest() + * .03 05-11-92 jrw Added waveform record support + */ + +#ifndef DEVCOMMONGPIB_H +#define DEVCOMMONGPIB_H + +long devGpibLib_report(); +long devGpibLib_initDevSup(); +long devGpibLib_initAi(); +long devGpibLib_initAo(); +long devGpibLib_initLi(); +long devGpibLib_initLo(); +long devGpibLib_initBi(); +long devGpibLib_initBo(); +long devGpibLib_initMbbo(); +long devGpibLib_initMbbi(); +long devGpibLib_initSi(); +long devGpibLib_initSo(); +long devGpibLib_initXx(); +long devGpibLib_readAi(); +long devGpibLib_writeAo(); +long devGpibLib_readLi(); +long devGpibLib_writeLo(); +long devGpibLib_readBi(); +long devGpibLib_writeBo(); +long devGpibLib_readMbbi(); +long devGpibLib_writeMbbo(); +long devGpibLib_readSi(); +long devGpibLib_writeSo(); + +int devGpibLib_aiGpibWork(); +int devGpibLib_aiGpibSrq(); +int devGpibLib_aiGpibFinish(); +int devGpibLib_aoGpibWork(); +int devGpibLib_liGpibWork(); +int devGpibLib_liGpibSrq(); +int devGpibLib_liGpibFinish(); +int devGpibLib_loGpibWork(); +int devGpibLib_biGpibWork(); +int devGpibLib_biGpibSrq(); +int devGpibLib_biGpibFinish(); +int devGpibLib_boGpibWork(); +int devGpibLib_mbbiGpibWork(); +int devGpibLib_mbbiGpibSrq(); +int devGpibLib_mbbiGpibFinish(); +int devGpibLib_mbboGpibWork(); +int devGpibLib_stringinGpibWork(); +int devGpibLib_stringinGpibSrq(); +int devGpibLib_stringinGpibFinish(); +int devGpibLib_stringoutGpibWork(); +int devGpibLib_xxGpibWork(); + +int devGpibLib_wfGpibFinish(); +int devGpibLib_wfGpibSrq(); +int devGpibLib_wfGpibWork(); +long devGpibLib_readWf(); +long devGpibLib_initWf(); + +void devGpibLib_processCallback(); +long devGpibLib_setPvSevr(); + +typedef struct { + long number; + DEVSUPFUN funPtr[20]; +} gDset; + +/****************************************************************************** + * + * This structure holds device-related data on a per-device basis and is + * referenced by the gpibDpvt structures. They are built using a linked + * list entered from hwpvtHead. This linked list is only for this specific + * device type (other gpib devices may have their own lists.) + * + * The srqCallback() and parm fields are used for GPIBREADW type calls. They + * should place the address of the appropriate function (aiGpibSrq if an AI + * record is being processed) into the srqCallback() field and the pdpvt + * field for the device into the parm field. This allows the SrqHandler() + * function to locate the proper function and work areas to complete the + * GPIBREADW operation. + * + * The unsolicitedDpvt field is used if the user specifies a record with + * the parm number associated with handleing unsolicited SRQ interrupts. + * What is done, is that the record will be processed when an SRQ is + * detected for reasons other than GPIBREADW-related reasons. There may + * be at most, 1 single record in hte database that can specify the 'magic' + * parm number. If you need more, forward link it to a fanout record. + * + ******************************************************************************/ +struct hwpvt { + struct hwpvt *next; /* to next structure for same type device */ + + int linkType; /* is a GPIB_IO, BBGPIB_IO... from link.h */ + int link; /* link number */ + int bug; /* used only on BBGPIB_IO links */ + int device; /* gpib device number */ + + unsigned long tmoVal; /* time last timeout occurred */ + unsigned long tmoCount; /* total number of timeouts since boot time */ + + /* No semaphore guards here because can inly be mod'd by the linkTask */ + int (*srqCallback)(); /* filled by cmds expecting SRQ callbacks */ + caddr_t parm; /* filled in by cmds expecting SRQ callbacks */ + + struct gpibDpvt *unsolicitedDpvt; /* filled in if database calls for it */ + caddr_t pupvt; /* user defined pointer */ +}; + +/****************************************************************************** + * + * This structure will be attached to each pv (via psub->dpvt) to store the + * appropriate head.workStart pointer, callback address to record support, + * gpib link #, device address, and command information. + * + ******************************************************************************/ + +struct gpibDpvt { + struct dpvtGpibHead head; /* fields used by the GPIB driver */ + + short parm; /* parameter index into gpib commands */ + char *rsp; /* for read/write message error Responses*/ + char *msg; /* for read/write messages */ + struct dbCommon *precord; /* record this dpvt is part of */ + void (*process)(); /* callback to perform forward db processing */ + int processPri; /* process callback's priority */ + long linkType; /* GPIB_IO, BBGPIB_IO... */ + struct hwpvt *phwpvt; /* pointer to per-device private area */ + caddr_t pupvt; /* user defined pointer */ +}; + +#define GET_GPIB_HW_PVT(pGpibDpvt) (((struct gpibDpvt*)(pGpibDpvt))->phwpvt->pupvt) +#define SET_GPIB_HW_PVT(pGpibDpvt, value) (((struct gpibDpvt*)(pGpibDpvt))->phwpvt->pupvt = value) + +/****************************************************************************** + * + * This is used to define the strings that are used for button labels. + * These strings are put into the record's znam & onam foelds if the + * record is a BI or BO type and into the zrst, onst... fields of an + * MBBI or MBBO record. + * + * Before these strings are placed into the record, the record is + * check to see if there is already a string defined (could be user-entered + * with DCT.) If there is already a string present, it will be preserved. + * + * There MUST ALWAYS be 2 and only 2 entries in the names.item list + * for BI and BO records if a name list is being specified for them here. + * The names.count field is ignored for BI and BO record types, but + * should be properly specified as 2 for future compatibility. + * + * NOTE: + * If a name string is filled in an an MBBI/MBBO record, it's corresponding + * value will be filled in as well. For this reason, there MUST be + * a value array and a valid nobt value for every MBBI/MBBO record that + * contains an item array! + * + ******************************************************************************/ + +struct devGpibNames { + int count; /* CURRENTLY only used for MBBI and MBBO */ + char **item; + unsigned long *value; /* CURRENTLY only used for MBBI and MBBO */ + short nobt; /* CURRENTLY only used for MBBI and MBBO */ +}; + +/****************************************************************************** + * + * Enumeration of gpib command types supported. + * + * Each transaction type is described below : + * + * GPIBREAD : (1) The cmd string is sent to the instrument + * (2) Data is read from the inst into a buffer (gpibDpvt.msg) + * (3) The important data is extracted from the buffer using the + * format string. + * + * GPIBWRITE: (1) An ascii string is generated using the format string and + * contents of the gpibDpvt->dbAddr->precord->val + * (2) The ascii string is sent to the instrument + * + * GPIBCMD : (1) The cmd string is sent to the instrument + * + * GPIBCNTL : (1) The control string is sent to the instrument (ATN active) + * + * GPIBSOFT : (1) No GPIB activity involved - normally retrieves internal data + * + * GPIBREADW : (1) The cmd string is sent to the instrument + * (2) Wait for SRQ + * (3) Data is read from the inst into a buffer (gpibDpvt.msg) + * (4) The important data is extracted from the buffer using the + * format string. + * + * GPIBRAWREAD: Used internally with GPIBREADW. Not useful from cmd table. + * + * + * The following is only supported on mbbo and bo record types. + * + * GPIBEFASTO: (1) Sends out the string pointed to by p3[VAL] w/o formating + * + * The following are only supported on mbbi and bi record types. + * + * GPIBEFASTI: (1) Send out the cmd string + * (2) Data is read from the inst into a buffer (gpibDpvt.msg) + * (3) Check the response against P3[0..?] + * (4) Set the value field to index when response = P3[index] + * + * GPIBEFASTIW: (1) Send out the cmd string + * (2) Wait for SRQ + * (3) Data is read from the inst into a buffer (gpibDpvt.msg) + * (4) Check the response against P3[0..?] + * (5) Set the value field to index when response = P3[index] + * + * If a particular GPIB message does not fit one of these formats, a custom + * routine may be provided. Store a pointer to this routine in the + * gpibCmd.convert field to use it rather than the above approaches. + * + ******************************************************************************/ + +#define GPIBREAD 1 +#define GPIBWRITE 2 +#define GPIBCMD 3 +#define GPIBCNTL 4 +#define GPIBSOFT 5 +#define GPIBREADW 6 +#define GPIBRAWREAD 7 +#define GPIBEFASTO 8 +#define GPIBEFASTI 9 +#define GPIBEFASTIW 10 + + +struct gpibCmd { + gDset *rec_typ; /* used to indicate record type supported */ + int type; /* enum - GPIBREAD, GPIBWRITE, GPIBCMND */ + short pri; /* request priority--IB_Q_HIGH or IB_Q_LOW*/ + char *cmd; /* CONSTANT STRING to send to instrument */ + char *format; /* string used to generate or interpret msg*/ + long rspLen; /* room for response error message*/ + long msgLen; /* room for return data message length*/ + + int (*convert)(); /* custom routine for conversions */ + int P1; /* user defined parameter used in convert() */ + int P2; /* user defined parameter used in convert() */ + char **P3; /* user defined parameter used in convert() */ + + struct devGpibNames *namelist; /* pointer to name strings */ + + int companion; /* companion command (used at init time) */ +}; + +#define FILL {0,0,0,NULL,NULL,0,0,NULL,0,0,NULL,NULL,-1} +#define FILL10 FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL + +/****************************************************************************** + * + * debugFlag: + * Must point to a flag used to request debugging traces for the device + * while executing library code. + * + * respond2Writes: + * Set to TRUE if the device responds to write operations. This causes + * a read operation to follow each write operation. (See also wrConversion) + * + * timeWindow: + * Set to the number of system ticks that should be skipped after a timeout + * is detected on a device. All commands issued within this time window + * will be aborted and returned as errors. + * + * hwpvtHead: + * This is the root pointer for the per-hardware device private structure + * list. It should ALWAYS be initialized to NULL. + * + * gpibCmds: + * Pointer to the gpibCmds array. + * + * numparams: + * The number of parameters described in the gpibCmds array. + * + * magicSrq: + * Set to the parameter number that should be processed if an unsolicited + * SRQ is detected. + * + * name: + * Must point to a string containing the device name (used for + * debug messages.) + * + * srqHandler: + * Must point to the SRQ handler for the device support module if SRQs are + * supported or NULL if not. + * + * wrConversion: + * If not set to NULL and respond2Writes is true and a GPIBWRITE or GPIBCMD + * operation has completed it's read portion, this secondary conversion + * routine is called. + * + ******************************************************************************/ + +typedef struct devGpibParmBlock { + int *debugFlag; /* pointer to debug flag */ + int respond2Writes; /* set to true if a device responds to writes */ + int timeWindow; /* clock ticks to skip after a timeout */ + struct hwpvt *hwpvtHead; /* pointer to the hwpvt list for device type */ + struct gpibCmd *gpibCmds; /* pointer to gpib command list */ + int numparams; /* number of elements in the command list */ + int magicSrq; /* magic parm to handle unsolicited SRQs */ + char *name; /* pointer to a string containing device type */ + int dmaTimeout; /* clock ticks to wait for DMA to complete */ + + int (*srqHandler)(); /* user SRQ handler or NULL if not supported */ + + int (*wrConversion)(); /* secondary conversion routine */ +} devGpibParmBlockStruct; + +#endif diff --git a/src/vxWorks/dev/joergerDev/devWfJoergerVtr1.c b/src/vxWorks/dev/joergerDev/devWfJoergerVtr1.c new file mode 100644 index 000000000..c21bb4352 --- /dev/null +++ b/src/vxWorks/dev/joergerDev/devWfJoergerVtr1.c @@ -0,0 +1,167 @@ +/* devWfJoergerVtr1.c */ +/* base/src/dev $Id$ */ + +/* devWfJoergerVtr1.c - Device Support Routines */ +/* + * Original Author: Bob Dalesio + * Current Author: Marty Kraimer + * Date: 6-1-90 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * .01 11-11-91 jba Moved set of alarm stat and sevr to macros + * .02 12-02-91 jba Added cmd control to io-interrupt processing + * .03 12-12-91 jba Set cmd to zero in io-interrupt processing + * .04 02-05-92 jba Changed function arguments from paddr to precord + * .05 02-28-92 jba Changed callback handling, ANSI C changes + * .06 03-13-92 jba ANSI C changes + * .07 04-10-92 jba pact now used to test for asyn processing, not return value + * .08 04-18-92 jba removed process from init_record parms + * .09 09-01-93 joh expects EPICS standard status + * ... + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static long init_record(); +static long read_wf(); +static long arm_wf(); + + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_wf; +} devWfJoergerVtr1={ + 5, + NULL, + NULL, + init_record, + NULL, + read_wf}; + + +static void myCallback(pwf,no_read,pdata) + struct waveformRecord *pwf; + int no_read; + unsigned short *pdata; +{ + struct rset *prset=(struct rset *)(pwf->rset); + short ftvl = pwf->ftvl; + long i; + + if(!pwf->busy) return; + dbScanLock((struct dbCommon *)pwf); + pwf->busy = FALSE; + if(no_read>pwf->nelm)no_read = pwf->nelm; + if(ftvl==DBF_CHAR || ftvl==DBF_UCHAR) { + unsigned char *pdest=(unsigned char *)pwf->bptr; + + for(i=0; inord = no_read; /* number of values read */ + } else if(ftvl==DBF_SHORT || ftvl==DBF_USHORT) { + unsigned short *pdest=(unsigned short *)pwf->bptr; + + for(i=0; inord = no_read; /* number of values read */ + } else { + recGblRecordError(S_db_badField,(void *)pwf, + "read_wf - illegal ftvl"); + recGblSetSevr(pwf,READ_ALARM,INVALID_ALARM); + } + (*prset->process)(pwf); + dbScanUnlock((struct dbCommon *)pwf); +} + +static long init_record(pwf) + struct waveformRecord *pwf; +{ + + /* wf.inp must be an VME_IO */ + switch (pwf->inp.type) { + case (VME_IO) : + break; + default : + recGblRecordError(S_db_badField,(void *)pwf, + "devWfJoergerVtr1 (init_record) Illegal INP field"); + return(S_db_badField); + } + return(0); +} + +static long read_wf(pwf) + struct waveformRecord *pwf; +{ + + /* determine if wave form is to be rearmed*/ + /* If not active then request rearm */ + if(!pwf->pact) arm_wf(pwf); + /* if already active then call is from myCallback. check rarm*/ + else if(pwf->rarm) { + (void)arm_wf(pwf); + } + return(0); +} + +static long arm_wf(pwf) +struct waveformRecord *pwf; +{ + long status; + struct vmeio *pvmeio = (struct vmeio *)&(pwf->inp.value); + + pwf->busy = TRUE; + status = jgvtr1_driver(pvmeio->card,myCallback,pwf); + if(status!=0){ + errMessage(status, NULL); + recGblSetSevr(pwf,READ_ALARM,INVALID_ALARM); + pwf->busy = FALSE; + return(0); + } + pwf->pact=TRUE; + return(0); +}