From 0ceb42cc745cd7de05d16fb3250f152e866178ab Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Mon, 21 Dec 1998 20:59:31 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'B3.13'. --- config.hkv2f.mk | 5 - config.mk | 1 - config.mv147.mk | 5 - config.mv167.mk | 5 - config.sun4.mk | 13 - config/CONFIG.LynxOS | 136 + src/ca/ca_printf.c | 71 - src/db/setMasterTimeToSelf.c | 99 - src/dev/devAllenBradley.c | 1377 ---- src/dev/devMbbiDirectTestAsyn.c | 148 - src/dev/devMbboDirectTestAsyn.c | 146 - src/drv/Makefile.Vx | 85 - src/drv/TODO | 8 - src/drv/VXI_SETUP_README | 30 - src/drv/drvAb.c | 2505 ------- src/drv/drvAb.h | 348 - src/drv/drvAt5Vxi.c | 1482 ---- src/drv/drvAt5Vxi.h | 93 - src/drv/drvBB232.c | 598 -- src/drv/drvBBMsg.c | 590 -- src/drv/drvBb902.c | 202 - src/drv/drvBb910.c | 212 - src/drv/drvBitBus.c | 2616 ------- src/drv/drvBitBus.h | 303 - src/drv/drvCaenV265.c | 807 --- src/drv/drvComet.c | 639 -- src/drv/drvCompuSm.c | 972 --- src/drv/drvDvx.c | 1400 ---- src/drv/drvEpvxi.c | 4448 ------------ src/drv/drvEpvxiMsg.c | 1537 ----- src/drv/drvExampleVxi.c | 237 - src/drv/drvFp.c | 526 -- src/drv/drvFpm.c | 432 -- src/drv/drvGpib.c | 2593 ------- src/drv/drvGpib.h | 315 - src/drv/drvHp1404a.c | 408 -- src/drv/drvHp1404a.h | 74 - src/drv/drvHpe1368a.c | 359 - src/drv/drvHpe1368a.h | 60 - src/drv/drvHpe1445a.c | 1185 ---- src/drv/drvJgvtr1.c | 641 -- src/drv/drvJgvtr1.h | 43 - src/drv/drvKscV215.c | 484 -- src/drv/drvKscV215.h | 56 - src/drv/drvMsg.c | 1437 ---- src/drv/drvMvme162.c | 683 -- src/drv/drvMz8310.c | 628 -- src/drv/drvMz8310.h | 74 - src/drv/drvOms.c | 685 -- src/drv/drvOms.h | 74 - src/drv/drvPEPBitBus.c | 1300 ---- src/drv/drvPEPBitBus.h | 121 - src/drv/drvRs232.c | 550 -- src/drv/drvStc.c | 290 - src/drv/drvStc.h | 107 - src/drv/drvTime.c | 246 - src/drv/drvVmi4100.c | 203 - src/drv/drvXy010.c | 179 - src/drv/drvXy210.c | 185 - src/drv/drvXy220.c | 220 - src/drv/drvXy240.c | 526 -- src/drv/drvXy566.c | 1148 ---- src/drv/module_types.c | 241 - src/drv/old/VXI_SETUP_README | 30 - src/drv/old/drvAt5Vxi.c | 1482 ---- src/drv/old/drvAt5Vxi.h | 93 - src/drv/old/drvCaenV265.c | 807 --- src/drv/old/drvEpvxi.c | 4448 ------------ src/drv/old/drvEpvxiMsg.c | 1537 ----- src/drv/old/drvHp1404a.c | 408 -- src/drv/old/drvHp1404a.h | 74 - src/drv/old/drvHpe1368a.c | 359 - src/drv/old/drvHpe1368a.h | 60 - src/drv/old/drvHpe1445a.c | 1185 ---- src/drv/old/drvKscV215.c | 484 -- src/drv/old/drvKscV215.h | 56 - src/drv/old/drvMz8310.c | 628 -- src/drv/old/drvMz8310.h | 74 - src/drv/old/drvStc.c | 290 - src/drv/old/drvStc.h | 107 - src/drv/old/drvTime.c | 246 - src/drv/steppermotor.h | 64 - src/include/asDbLib.h | 45 - src/include/asLib.h | 192 - src/include/cadef.h | 1184 ---- src/include/caerr.h | 235 - src/include/caeventmask.h | 36 - src/include/devSup.h | 66 - src/include/drvSup.h | 52 - src/include/drvTS.h | 252 - src/include/fast_lock.h | 191 - src/libCom/Makefile.Unix | 139 - src/libCom/ansidecl.h | 108 - src/libCom/arAccessLib.c | 2915 -------- src/libCom/arCSCheck.c | 133 - src/libCom/arChanIO.c | 1638 ----- src/libCom/bdt.c | 613 -- src/libCom/bfSubr.c | 1584 ----- src/libCom/bucketLib/bucketLib.c | 607 -- src/libCom/bucketLib/bucketLib.h | 125 - src/libCom/calc/calcPerform.c | 545 -- src/libCom/calc/postfix.c | 576 -- src/libCom/calc/postfix.h | 49 - src/libCom/calc/postfixPvt.h | 123 - src/libCom/calc/sCalcPerform.c | 1458 ---- src/libCom/calc/sCalcPostfix.c | 723 -- src/libCom/calc/sCalcPostfix.h | 48 - src/libCom/calc/sCalcPostfixPvt.h | 115 - src/libCom/cmdSubr.c | 315 - src/libCom/createSoftLinks.sh | 47 - src/libCom/cvtFast/cvtFast.c | 621 -- src/libCom/cvtFast/cvtFast.h | 123 - src/libCom/cvtNumbers.c | 397 -- src/libCom/cxxTemplates/README | 56 - src/libCom/cxxTemplates/resourceLib.h | 787 --- src/libCom/cxxTemplates/test/Makefile | 7 - src/libCom/cxxTemplates/test/minmaxTest.cc | 30 - .../cxxTemplates/test/resourceLibTest.cc | 254 - src/libCom/cxxTemplates/test/tsBTreeBench.cc | 83 - src/libCom/cxxTemplates/test/tsBTreeTest.cc | 80 - src/libCom/cxxTemplates/test/tsDLListBench.cc | 61 - src/libCom/cxxTemplates/test/tsDLListTest.cc | 102 - src/libCom/cxxTemplates/test/tsSLListBench.cc | 75 - src/libCom/cxxTemplates/test/tsSLListTest.cc | 103 - src/libCom/cxxTemplates/tsBTree.h | 261 - src/libCom/cxxTemplates/tsDLList.h | 873 --- src/libCom/cxxTemplates/tsMinMax.h | 18 - src/libCom/cxxTemplates/tsSLList.h | 362 - src/libCom/dbmf/dbmf.c | 225 - src/libCom/dbmf/dbmf.h | 27 - src/libCom/ellLib/ellLib.c | 830 --- src/libCom/ellLib/ellLib.h | 145 - src/libCom/env/bldEnvData.pl | 150 - src/libCom/env/envDefs.h | 141 - src/libCom/env/envSubr.c | 506 -- src/libCom/epicsEnvParams.h | 18 - src/libCom/error/epicsPrint.h | 9 - src/libCom/error/errMdef.h | 125 - src/libCom/error/errSymLib.c | 456 -- src/libCom/error/errSymTbl.h | 24 - src/libCom/error/errlog.c | 481 -- src/libCom/error/errlog.h | 108 - src/libCom/error/error.h | 74 - src/libCom/error/makeStatTbl.pl | 118 - src/libCom/ezsSockSubr.c | 538 -- src/libCom/fdmgr/fdManager.cpp | 432 -- src/libCom/fdmgr/fdManager.h | 198 - src/libCom/fdmgr/fdmgr.h | 236 - src/libCom/freeList/freeList.h | 67 - src/libCom/freeList/freeListLib.c | 207 - src/libCom/genSubr.c | 415 -- src/libCom/genTaskSubr.c | 348 - src/libCom/gpHash/gpHash.h | 80 - src/libCom/gpHash/gpHashLib.c | 324 - src/libCom/helpSubr.c | 285 - src/libCom/macLib/macCore.c | 784 --- src/libCom/macLib/macLib.h | 225 - src/libCom/macLib/macLibNOTES | 160 - src/libCom/macLib/macLibREADME | 294 - src/libCom/macLib/macUtil.c | 282 - src/libCom/misc/aToIPAddr.c | 136 - src/libCom/misc/adjustment.c | 69 - src/libCom/misc/adjustment.h | 19 - src/libCom/misc/createSoftLinks.sh | 12 - src/libCom/misc/dbDefs.h | 125 - src/libCom/misc/epicsString.c | 84 - src/libCom/misc/epicsString.h | 28 - src/libCom/misc/epicsTypes.h | 255 - src/libCom/misc/gsd_sync_defs.h | 55 - src/libCom/misc/makeEpicsVersion.pl | 45 - src/libCom/misc/shareLib.h | 159 - src/libCom/misc/truncateFile.c | 128 - src/libCom/misc/truncateFile.h | 17 - src/libCom/misc/unixFileName.h | 13 - src/libCom/mprintf.c | 305 - src/libCom/osi/epicsAssert.h | 91 - src/libCom/osi/os/Linux/osdSock.h | 71 - src/libCom/osi/os/Linux/osiFileName.h | 12 - src/libCom/osi/os/VMS/osiFileName.h | 13 - src/libCom/osi/os/VMS/osiSock.h | 161 - src/libCom/osi/os/VMS/ucx.h | 101 - src/libCom/osi/os/WIN32/dllmain.cpp | 79 - src/libCom/osi/os/WIN32/getopt.c | 736 -- src/libCom/osi/os/WIN32/getopt.h | 134 - src/libCom/osi/os/WIN32/osdSock.h | 46 - src/libCom/osi/os/WIN32/osdTime.cpp | 108 - src/libCom/osi/os/WIN32/osiFileName.h | 13 - src/libCom/osi/os/alpha/osdSock.h | 65 - src/libCom/osi/os/alpha/osiFileName.h | 12 - src/libCom/osi/os/cygwin32/osdSock.h | 83 - src/libCom/osi/os/cygwin32/osiFileName.h | 13 - src/libCom/osi/os/hpux/osdSock.h | 67 - src/libCom/osi/os/hpux/osiFileName.h | 12 - src/libCom/osi/os/sgi/osdSock.h | 64 - src/libCom/osi/os/sgi/osiFileName.h | 12 - src/libCom/osi/os/solaris/osdSock.h | 75 - src/libCom/osi/os/solaris/osiFileName.h | 12 - src/libCom/osi/os/sun4/osdSock.h | 131 - src/libCom/osi/os/sun4/osiFileName.h | 12 - src/libCom/osi/os/vxWorks/osdSock.h | 62 - src/libCom/osi/os/vxWorks/osiFileName.h | 12 - src/libCom/sydSubr.c | 4069 ----------- src/libCom/sydSubrCA.c | 537 -- src/libCom/sydSubrCF.c | 398 -- src/libCom/sydSubrPFO.c | 227 - src/libCom/sydSubrSSF.c | 1094 --- src/libCom/timer/osiTimer.cpp | 424 -- src/libCom/timer/osiTimer.h | 163 - src/misc/epicsEnvParams.c | 57 - src/misc/epicsEnvParams.h | 14 - src/rec/caMonitor.c | 152 - src/rec/caMonitor.h | 9 - src/util/apCreateShadow.c | 389 -- src/util/apStatusSync.c | 576 -- src/util/bfRing.c | 229 - src/util/calcTest.c | 173 - src/util/checkDvlNode.c | 312 - src/util/cmdClient.c | 321 - src/util/cmdProto.c | 678 -- src/util/extrDoc.c | 195 - src/util/guiSubr.c | 3446 ---------- src/util/guiTest.icon | 66 - src/util/in.calcTest | 333 - src/util/lopi.c | 2472 ------- src/util/lopi_def.h | 225 - src/util/pprPlot.c | 6060 ----------------- src/util/pprPlot.man | 1769 ----- src/util/racPrint.c | 714 -- src/util/recListProg.c | 934 --- src/util/recordTest.c | 340 - src/util/sydPlot.c | 4081 ----------- src/vxWorks/db/devLib.c | 1336 ---- src/vxWorks/db/devLib.h | 234 - src/vxWorks/db/devLibVxWorks.c | 430 -- src/vxWorks/db/drvTS.c | 1948 ------ src/vxWorks/db/drvTS.h | 252 - 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 - src/vxWorks/devOpt/devAnalytekGpib.c | 818 --- src/vxWorks/devOpt/devGpibInteract.c | 775 --- src/vxWorks/devOpt/devK486Gpib.c | 326 - src/vxWorks/devOpt/devXxBugRac.c | 536 -- src/vxWorks/devOpt/devXxDc5009Gpib.c | 406 -- src/vxWorks/devOpt/devXxDg535Gpib.c | 898 --- src/vxWorks/devOpt/devXxHvpsGpib.c | 1606 ----- src/vxWorks/devOpt/devXxK196Gpib.c | 299 - src/vxWorks/devOpt/devXxK263Gpib.c | 235 - src/vxWorks/devOpt/devXxSkeletonGpib.c | 419 -- src/vxWorks/devOpt/devXxSoftMsg.c | 254 - src/vxWorks/devOpt/devXxSr620Gpib.c | 324 - src/vxWorks/drv/ansi/drvAt5Vxi.c | 1414 ---- src/vxWorks/drv/ansi/drvAt5Vxi.h | 94 - src/vxWorks/drv/ansi/drvHp1404a.c | 414 -- src/vxWorks/drv/ansi/drvHp1404a.h | 74 - src/vxWorks/drv/ansi/drvHpe1368a.c | 361 - src/vxWorks/drv/ansi/drvHpe1368a.h | 60 - src/vxWorks/drv/ansi/drvHpe1445a.c | 1188 ---- src/vxWorks/drv/ansi/drvStc.c | 316 - src/vxWorks/drv/ansi/drvStc.h | 116 - src/vxWorks/drv/old/drvComet.c | 636 -- src/vxWorks/drv/old/drvCompuSm.c | 868 --- src/vxWorks/drv/old/drvFp.c | 532 -- src/vxWorks/drv/old/drvFpm.c | 440 -- src/vxWorks/drv/old/drvJgvtr1.c | 641 -- src/vxWorks/drv/old/drvJgvtr1.h | 43 - src/vxWorks/drv/old/module_types.c | 241 - src/vxWorks/include/camacLib.h | 74 - src/vxWorks/include/fast_lock.h | 191 - src/vxWorks/include/module_types.h | 586 -- src/vxWorks/include/task_params.h | 267 - src/vxWorks/libvxWorks/epicsDynLink.c | 53 - src/vxWorks/libvxWorks/epicsDynLink.h | 33 - src/vxWorks/libvxWorks/veclist.c | 231 - 280 files changed, 136 insertions(+), 137642 deletions(-) delete mode 100644 config.hkv2f.mk delete mode 100644 config.mk delete mode 100644 config.mv147.mk delete mode 100644 config.mv167.mk delete mode 100644 config.sun4.mk create mode 100644 config/CONFIG.LynxOS delete mode 100644 src/ca/ca_printf.c delete mode 100644 src/db/setMasterTimeToSelf.c delete mode 100644 src/dev/devAllenBradley.c delete mode 100644 src/dev/devMbbiDirectTestAsyn.c delete mode 100644 src/dev/devMbboDirectTestAsyn.c delete mode 100644 src/drv/Makefile.Vx delete mode 100644 src/drv/TODO delete mode 100644 src/drv/VXI_SETUP_README delete mode 100644 src/drv/drvAb.c delete mode 100644 src/drv/drvAb.h delete mode 100644 src/drv/drvAt5Vxi.c delete mode 100644 src/drv/drvAt5Vxi.h delete mode 100644 src/drv/drvBB232.c delete mode 100644 src/drv/drvBBMsg.c delete mode 100644 src/drv/drvBb902.c delete mode 100644 src/drv/drvBb910.c delete mode 100644 src/drv/drvBitBus.c delete mode 100644 src/drv/drvBitBus.h delete mode 100644 src/drv/drvCaenV265.c delete mode 100644 src/drv/drvComet.c delete mode 100644 src/drv/drvCompuSm.c delete mode 100644 src/drv/drvDvx.c delete mode 100644 src/drv/drvEpvxi.c delete mode 100644 src/drv/drvEpvxiMsg.c delete mode 100644 src/drv/drvExampleVxi.c delete mode 100644 src/drv/drvFp.c delete mode 100644 src/drv/drvFpm.c delete mode 100644 src/drv/drvGpib.c delete mode 100644 src/drv/drvGpib.h delete mode 100644 src/drv/drvHp1404a.c delete mode 100644 src/drv/drvHp1404a.h delete mode 100644 src/drv/drvHpe1368a.c delete mode 100644 src/drv/drvHpe1368a.h delete mode 100644 src/drv/drvHpe1445a.c delete mode 100644 src/drv/drvJgvtr1.c delete mode 100644 src/drv/drvJgvtr1.h delete mode 100644 src/drv/drvKscV215.c delete mode 100644 src/drv/drvKscV215.h delete mode 100644 src/drv/drvMsg.c delete mode 100644 src/drv/drvMvme162.c delete mode 100644 src/drv/drvMz8310.c delete mode 100644 src/drv/drvMz8310.h delete mode 100644 src/drv/drvOms.c delete mode 100644 src/drv/drvOms.h delete mode 100644 src/drv/drvPEPBitBus.c delete mode 100644 src/drv/drvPEPBitBus.h delete mode 100644 src/drv/drvRs232.c delete mode 100644 src/drv/drvStc.c delete mode 100644 src/drv/drvStc.h delete mode 100644 src/drv/drvTime.c delete mode 100644 src/drv/drvVmi4100.c delete mode 100644 src/drv/drvXy010.c delete mode 100644 src/drv/drvXy210.c delete mode 100644 src/drv/drvXy220.c delete mode 100644 src/drv/drvXy240.c delete mode 100644 src/drv/drvXy566.c delete mode 100644 src/drv/module_types.c delete mode 100644 src/drv/old/VXI_SETUP_README delete mode 100644 src/drv/old/drvAt5Vxi.c delete mode 100644 src/drv/old/drvAt5Vxi.h delete mode 100644 src/drv/old/drvCaenV265.c delete mode 100644 src/drv/old/drvEpvxi.c delete mode 100644 src/drv/old/drvEpvxiMsg.c delete mode 100644 src/drv/old/drvHp1404a.c delete mode 100644 src/drv/old/drvHp1404a.h delete mode 100644 src/drv/old/drvHpe1368a.c delete mode 100644 src/drv/old/drvHpe1368a.h delete mode 100644 src/drv/old/drvHpe1445a.c delete mode 100644 src/drv/old/drvKscV215.c delete mode 100644 src/drv/old/drvKscV215.h delete mode 100644 src/drv/old/drvMz8310.c delete mode 100644 src/drv/old/drvMz8310.h delete mode 100644 src/drv/old/drvStc.c delete mode 100644 src/drv/old/drvStc.h delete mode 100644 src/drv/old/drvTime.c delete mode 100644 src/drv/steppermotor.h delete mode 100644 src/include/asDbLib.h delete mode 100644 src/include/asLib.h delete mode 100644 src/include/cadef.h delete mode 100644 src/include/caerr.h delete mode 100644 src/include/caeventmask.h delete mode 100644 src/include/devSup.h delete mode 100644 src/include/drvSup.h delete mode 100644 src/include/drvTS.h delete mode 100644 src/include/fast_lock.h delete mode 100644 src/libCom/Makefile.Unix delete mode 100644 src/libCom/ansidecl.h delete mode 100644 src/libCom/arAccessLib.c delete mode 100644 src/libCom/arCSCheck.c delete mode 100644 src/libCom/arChanIO.c delete mode 100644 src/libCom/bdt.c delete mode 100644 src/libCom/bfSubr.c delete mode 100644 src/libCom/bucketLib/bucketLib.c delete mode 100644 src/libCom/bucketLib/bucketLib.h delete mode 100644 src/libCom/calc/calcPerform.c delete mode 100644 src/libCom/calc/postfix.c delete mode 100644 src/libCom/calc/postfix.h delete mode 100644 src/libCom/calc/postfixPvt.h delete mode 100644 src/libCom/calc/sCalcPerform.c delete mode 100644 src/libCom/calc/sCalcPostfix.c delete mode 100644 src/libCom/calc/sCalcPostfix.h delete mode 100644 src/libCom/calc/sCalcPostfixPvt.h delete mode 100644 src/libCom/cmdSubr.c delete mode 100644 src/libCom/createSoftLinks.sh delete mode 100644 src/libCom/cvtFast/cvtFast.c delete mode 100644 src/libCom/cvtFast/cvtFast.h delete mode 100644 src/libCom/cvtNumbers.c delete mode 100644 src/libCom/cxxTemplates/README delete mode 100644 src/libCom/cxxTemplates/resourceLib.h delete mode 100644 src/libCom/cxxTemplates/test/Makefile delete mode 100644 src/libCom/cxxTemplates/test/minmaxTest.cc delete mode 100644 src/libCom/cxxTemplates/test/resourceLibTest.cc delete mode 100644 src/libCom/cxxTemplates/test/tsBTreeBench.cc delete mode 100644 src/libCom/cxxTemplates/test/tsBTreeTest.cc delete mode 100644 src/libCom/cxxTemplates/test/tsDLListBench.cc delete mode 100644 src/libCom/cxxTemplates/test/tsDLListTest.cc delete mode 100644 src/libCom/cxxTemplates/test/tsSLListBench.cc delete mode 100644 src/libCom/cxxTemplates/test/tsSLListTest.cc delete mode 100644 src/libCom/cxxTemplates/tsBTree.h delete mode 100644 src/libCom/cxxTemplates/tsDLList.h delete mode 100644 src/libCom/cxxTemplates/tsMinMax.h delete mode 100644 src/libCom/cxxTemplates/tsSLList.h delete mode 100644 src/libCom/dbmf/dbmf.c delete mode 100644 src/libCom/dbmf/dbmf.h delete mode 100644 src/libCom/ellLib/ellLib.c delete mode 100644 src/libCom/ellLib/ellLib.h delete mode 100644 src/libCom/env/bldEnvData.pl delete mode 100644 src/libCom/env/envDefs.h delete mode 100644 src/libCom/env/envSubr.c delete mode 100644 src/libCom/epicsEnvParams.h delete mode 100644 src/libCom/error/epicsPrint.h delete mode 100644 src/libCom/error/errMdef.h delete mode 100644 src/libCom/error/errSymLib.c delete mode 100644 src/libCom/error/errSymTbl.h delete mode 100644 src/libCom/error/errlog.c delete mode 100644 src/libCom/error/errlog.h delete mode 100644 src/libCom/error/error.h delete mode 100644 src/libCom/error/makeStatTbl.pl delete mode 100644 src/libCom/ezsSockSubr.c delete mode 100644 src/libCom/fdmgr/fdManager.cpp delete mode 100644 src/libCom/fdmgr/fdManager.h delete mode 100644 src/libCom/fdmgr/fdmgr.h delete mode 100644 src/libCom/freeList/freeList.h delete mode 100644 src/libCom/freeList/freeListLib.c delete mode 100644 src/libCom/genSubr.c delete mode 100644 src/libCom/genTaskSubr.c delete mode 100644 src/libCom/gpHash/gpHash.h delete mode 100644 src/libCom/gpHash/gpHashLib.c delete mode 100644 src/libCom/helpSubr.c delete mode 100644 src/libCom/macLib/macCore.c delete mode 100644 src/libCom/macLib/macLib.h delete mode 100644 src/libCom/macLib/macLibNOTES delete mode 100644 src/libCom/macLib/macLibREADME delete mode 100644 src/libCom/macLib/macUtil.c delete mode 100644 src/libCom/misc/aToIPAddr.c delete mode 100644 src/libCom/misc/adjustment.c delete mode 100644 src/libCom/misc/adjustment.h delete mode 100644 src/libCom/misc/createSoftLinks.sh delete mode 100644 src/libCom/misc/dbDefs.h delete mode 100644 src/libCom/misc/epicsString.c delete mode 100644 src/libCom/misc/epicsString.h delete mode 100644 src/libCom/misc/epicsTypes.h delete mode 100644 src/libCom/misc/gsd_sync_defs.h delete mode 100644 src/libCom/misc/makeEpicsVersion.pl delete mode 100644 src/libCom/misc/shareLib.h delete mode 100644 src/libCom/misc/truncateFile.c delete mode 100644 src/libCom/misc/truncateFile.h delete mode 100644 src/libCom/misc/unixFileName.h delete mode 100644 src/libCom/mprintf.c delete mode 100644 src/libCom/osi/epicsAssert.h delete mode 100644 src/libCom/osi/os/Linux/osdSock.h delete mode 100644 src/libCom/osi/os/Linux/osiFileName.h delete mode 100644 src/libCom/osi/os/VMS/osiFileName.h delete mode 100644 src/libCom/osi/os/VMS/osiSock.h delete mode 100644 src/libCom/osi/os/VMS/ucx.h delete mode 100644 src/libCom/osi/os/WIN32/dllmain.cpp delete mode 100644 src/libCom/osi/os/WIN32/getopt.c delete mode 100644 src/libCom/osi/os/WIN32/getopt.h delete mode 100644 src/libCom/osi/os/WIN32/osdSock.h delete mode 100644 src/libCom/osi/os/WIN32/osdTime.cpp delete mode 100644 src/libCom/osi/os/WIN32/osiFileName.h delete mode 100644 src/libCom/osi/os/alpha/osdSock.h delete mode 100644 src/libCom/osi/os/alpha/osiFileName.h delete mode 100644 src/libCom/osi/os/cygwin32/osdSock.h delete mode 100644 src/libCom/osi/os/cygwin32/osiFileName.h delete mode 100644 src/libCom/osi/os/hpux/osdSock.h delete mode 100644 src/libCom/osi/os/hpux/osiFileName.h delete mode 100644 src/libCom/osi/os/sgi/osdSock.h delete mode 100644 src/libCom/osi/os/sgi/osiFileName.h delete mode 100644 src/libCom/osi/os/solaris/osdSock.h delete mode 100644 src/libCom/osi/os/solaris/osiFileName.h delete mode 100644 src/libCom/osi/os/sun4/osdSock.h delete mode 100644 src/libCom/osi/os/sun4/osiFileName.h delete mode 100644 src/libCom/osi/os/vxWorks/osdSock.h delete mode 100644 src/libCom/osi/os/vxWorks/osiFileName.h delete mode 100644 src/libCom/sydSubr.c delete mode 100644 src/libCom/sydSubrCA.c delete mode 100644 src/libCom/sydSubrCF.c delete mode 100644 src/libCom/sydSubrPFO.c delete mode 100644 src/libCom/sydSubrSSF.c delete mode 100644 src/libCom/timer/osiTimer.cpp delete mode 100644 src/libCom/timer/osiTimer.h delete mode 100644 src/misc/epicsEnvParams.c delete mode 100644 src/misc/epicsEnvParams.h delete mode 100644 src/rec/caMonitor.c delete mode 100644 src/rec/caMonitor.h delete mode 100644 src/util/apCreateShadow.c delete mode 100644 src/util/apStatusSync.c delete mode 100644 src/util/bfRing.c delete mode 100644 src/util/calcTest.c delete mode 100644 src/util/checkDvlNode.c delete mode 100644 src/util/cmdClient.c delete mode 100644 src/util/cmdProto.c delete mode 100644 src/util/extrDoc.c delete mode 100644 src/util/guiSubr.c delete mode 100644 src/util/guiTest.icon delete mode 100644 src/util/in.calcTest delete mode 100644 src/util/lopi.c delete mode 100644 src/util/lopi_def.h delete mode 100644 src/util/pprPlot.c delete mode 100644 src/util/pprPlot.man delete mode 100644 src/util/racPrint.c delete mode 100644 src/util/recListProg.c delete mode 100644 src/util/recordTest.c delete mode 100644 src/util/sydPlot.c delete mode 100644 src/vxWorks/db/devLib.c delete mode 100644 src/vxWorks/db/devLib.h delete mode 100644 src/vxWorks/db/devLibVxWorks.c delete mode 100644 src/vxWorks/db/drvTS.c delete mode 100644 src/vxWorks/db/drvTS.h delete mode 100644 src/vxWorks/dev/apsDev/devApsEg.c delete mode 100644 src/vxWorks/dev/apsDev/devApsEr.c delete mode 100644 src/vxWorks/dev/apsDev/devApsEr.h delete mode 100644 src/vxWorks/dev/atDev/devAt5Vxi.c delete mode 100644 src/vxWorks/dev/atDev/devAt8Fp.c delete mode 100644 src/vxWorks/dev/compumotorDev/devSmCompumotor1830.c delete mode 100644 src/vxWorks/dev/gpibDev/devCommonGpib.c delete mode 100644 src/vxWorks/dev/gpibDev/devCommonGpib.h delete mode 100644 src/vxWorks/dev/joergerDev/devWfJoergerVtr1.c delete mode 100644 src/vxWorks/devOpt/devAnalytekGpib.c delete mode 100644 src/vxWorks/devOpt/devGpibInteract.c delete mode 100644 src/vxWorks/devOpt/devK486Gpib.c delete mode 100644 src/vxWorks/devOpt/devXxBugRac.c delete mode 100644 src/vxWorks/devOpt/devXxDc5009Gpib.c delete mode 100644 src/vxWorks/devOpt/devXxDg535Gpib.c delete mode 100644 src/vxWorks/devOpt/devXxHvpsGpib.c delete mode 100644 src/vxWorks/devOpt/devXxK196Gpib.c delete mode 100644 src/vxWorks/devOpt/devXxK263Gpib.c delete mode 100644 src/vxWorks/devOpt/devXxSkeletonGpib.c delete mode 100644 src/vxWorks/devOpt/devXxSoftMsg.c delete mode 100644 src/vxWorks/devOpt/devXxSr620Gpib.c delete mode 100644 src/vxWorks/drv/ansi/drvAt5Vxi.c delete mode 100644 src/vxWorks/drv/ansi/drvAt5Vxi.h delete mode 100644 src/vxWorks/drv/ansi/drvHp1404a.c delete mode 100644 src/vxWorks/drv/ansi/drvHp1404a.h delete mode 100644 src/vxWorks/drv/ansi/drvHpe1368a.c delete mode 100644 src/vxWorks/drv/ansi/drvHpe1368a.h delete mode 100644 src/vxWorks/drv/ansi/drvHpe1445a.c delete mode 100644 src/vxWorks/drv/ansi/drvStc.c delete mode 100644 src/vxWorks/drv/ansi/drvStc.h delete mode 100644 src/vxWorks/drv/old/drvComet.c delete mode 100644 src/vxWorks/drv/old/drvCompuSm.c delete mode 100644 src/vxWorks/drv/old/drvFp.c delete mode 100644 src/vxWorks/drv/old/drvFpm.c delete mode 100644 src/vxWorks/drv/old/drvJgvtr1.c delete mode 100644 src/vxWorks/drv/old/drvJgvtr1.h delete mode 100644 src/vxWorks/drv/old/module_types.c delete mode 100644 src/vxWorks/include/camacLib.h delete mode 100644 src/vxWorks/include/fast_lock.h delete mode 100644 src/vxWorks/include/module_types.h delete mode 100644 src/vxWorks/include/task_params.h delete mode 100644 src/vxWorks/libvxWorks/epicsDynLink.c delete mode 100644 src/vxWorks/libvxWorks/epicsDynLink.h delete mode 100644 src/vxWorks/libvxWorks/veclist.c diff --git a/config.hkv2f.mk b/config.hkv2f.mk deleted file mode 100644 index 2c04cc878..000000000 --- a/config.hkv2f.mk +++ /dev/null @@ -1,5 +0,0 @@ -BUILD_TYPE = Vx - -DIRS = src/as src/ca src/db src/dev src/devOpt src/drv \ - src/libCom src/libvxWorks src/rec src/rsrv \ - src/sequencer src/util src/dbtools src/misc . diff --git a/config.mk b/config.mk deleted file mode 100644 index 6d54ddafe..000000000 --- a/config.mk +++ /dev/null @@ -1 +0,0 @@ -BUILD_ARCHS=sun4 mv167 mv147 diff --git a/config.mv147.mk b/config.mv147.mk deleted file mode 100644 index 2c04cc878..000000000 --- a/config.mv147.mk +++ /dev/null @@ -1,5 +0,0 @@ -BUILD_TYPE = Vx - -DIRS = src/as src/ca src/db src/dev src/devOpt src/drv \ - src/libCom src/libvxWorks src/rec src/rsrv \ - src/sequencer src/util src/dbtools src/misc . diff --git a/config.mv167.mk b/config.mv167.mk deleted file mode 100644 index 2c04cc878..000000000 --- a/config.mv167.mk +++ /dev/null @@ -1,5 +0,0 @@ -BUILD_TYPE = Vx - -DIRS = src/as src/ca src/db src/dev src/devOpt src/drv \ - src/libCom src/libvxWorks src/rec src/rsrv \ - src/sequencer src/util src/dbtools src/misc . diff --git a/config.sun4.mk b/config.sun4.mk deleted file mode 100644 index ad02adf57..000000000 --- a/config.sun4.mk +++ /dev/null @@ -1,13 +0,0 @@ -BUILD_TYPE = Unix -DIRS = src/libCom \ - src/db \ - src/ca \ - src/toolsComm/antelope \ - src/toolsComm/flex \ - src/as \ - src/bld \ - src/dct \ - src/util \ - src/sequencer \ - src/dbtools \ - rec diff --git a/config/CONFIG.LynxOS b/config/CONFIG.LynxOS new file mode 100644 index 000000000..f18c11ae6 --- /dev/null +++ b/config/CONFIG.LynxOS @@ -0,0 +1,136 @@ +# $Id$ +# +# This file contains definitions for Vx builds + +#-------------------------------------------------- +# operating system class (include/os/) +OS_CLASS = LynxOS + +lynx_pc486 =YES + +CC = gcc +CXX = g++ + +#-------------------------------------------------- +# vxWorks directory definitions + +# The definitions VX_DIR, VX_GNU, GNU_DIR and GNU_LIB +# can be overridden for specific host architectures +# by creating a CONFIG_SITE.Vx. file with +# the override definitions. + +# Tornado directory definitions +VX_CONFIG_DIR_YES = +VX_INCLUDE_YES = +VX_GNU_YES = +VX_GNU_BIN_YES = +VX_GNU_LIB_YES = + + +# pre Torando directory definitions +VX_CONFIG_DIR_NO = +VX_INCLUDE_NO = +VX_GNU_NO = +VX_GNU_BIN_NO = + +# directory definitions +VX_DIR = +VX_CONFIG_DIR = +VX_INCLUDE = +VX_GNU = + +GNU_BIN = /usr/local/bin +GNU_LIB = /usr/local/lib + +#-------------------------------------------------- +# VxWorks command definitions + +#GCC = $(GNU_BIN)/cc$(CMPLR_SUFFIX) -B$(GNU_LIB)/gcc-lib/ -nostdinc +#AR = $(GNU_BIN)/ar$(CMPLR_SUFFIX) +#CPP = $(GNU_BIN)/cpp$(CMPLR_SUFFIX) -nostdinc +#RANLIB = $(GNU_BIN)/ranlib$(CMPLR_SUFFIX) +#LD = $(GNU_BIN)/ld$(CMPLR_SUFFIX) -r + +AR = ar -rc +ARCMD = $(AR) $@ +RANLIB = ranlib -t +GCC = gcc +CPP = cpp +LD = ld -r + + +#-------------------------------------------------- +# Tornado C++ crosscompiler definitions + +#CPLUSPLUS_YES = G++ +#G++ = $(GNU_BIN)/cc$(CMPLR_SUFFIX) -B$(GNU_LIB)/gcc-lib/ -nostdinc +#LD_G++ = $(GNU_BIN)/ld$(CMPLR_SUFFIX) -r +#NM = $(GNU_BIN)/nm$(CMPLR_SUFFIX) +#MUNCH = $(GNU_BIN)/munch + +CPLUSPLUS_YES = g++ -DLynxOS -DLynxOS_pc486 -mposix -D_X86_ -DEXPL_TEMP +G++ = g++ -DLynxOS -DLynxOS_pc486 -mposix -D_X86_ -DEXPL_TEMP +LD_G++ = ld -r +NM = nm + +#-------------------------------------------------- +# Pre Tornado C++ crosscompiler definitions +# These are pre tornado definitions for Hideos builds (defined for 68k only) + +#CPLUSPLUS_NO = CCC +#CCC = $(GNU_DIR)/bin/sun3-g++ -B$(GNU_DIR)/lib/gcc-lib/ -nostdinc -DEXPL_TEMPL +#LD_CCC = $(GNU_DIR)/bin/sun3-ld $(OLD_ARCH_DEP_LDFLAGS) -r + +CPLUSPLUS_NO = g++ -DLynxOS -DLynxOS_pc486 -mposix -D_X86_ -DEXPL_TEMP +CCC = g++ -DLynxOS -DLynxOS_pc486 -mposix -D_X86_ -DEXPL_TEMP +LD_CCC = ld -r + +CCC_NORMAL = $(CCC) $(OLD_ARCH_DEP_CFLAGS) +CCC_STRICT = $(CCC) -ansi -pedantic -Wall -traditional $(OLD_ARCH_DEP_CFLAGS) +CCC_TRAD = $(CCC) -traditional $(OLD_ARCH_DEP_CFLAGS) +CCC_TEMPL_INST_FLAG = -DEXPL_TEMP +CCC_WARN_YES = -Wall +CCC_WARN_NO = -w +CCC_OPT_YES = -O +CCC_OPT_NO = -g +CCC_DEPENDS_FLAG = -pedantic -DLynxOS -DLynxOS_pc486 -mposix -D_X86_ +CPU = i486 +OS = lynxos +OLD_ARCH_DEP_CFLAGS = -DLynxOS -DLynxOS_pc486 -mposix -D_X86_ +# --no-builtin -Wa,"-m68040" -DOS_EQ_$(OS) \ +# -DBOARD_EQ_$(BOARD) -DCPU_EQ_$(CPU) -DBOARD=$(BOARD) +OLD_ARCH_DEP_LDFLAGS = -mposix -lc -lbsd -lnsl -lm -lposix4d9 -llynx +# -Ur -N -T$(EPICS_BASE_BIN)/vxldscript.MRI + +#-------------------------------------------------- +# C compiler definitions +ANSI = gcc -ansi + +#-------------------------------------------------- +# Command definitions +CPLUSPLUS = g++ +# $(CPLUSPLUS_$(TORNADO)) +LD_CXX = ld -r +# $(LD_$(CPLUSPLUS)) + +#-------------------------------------------------- +# Operating system flags +OP_SYS_INCLUDES = +# -I$(VX_INCLUDE) +OP_SYS_CFLAGS = -DLynxOS -DLynxOS_pc486 -mposix -D_X86_ +# -DvxWorks -DV5_vxWorks -fno-builtin +OP_SYS_LDFLAGS = -DLynxOS -DLynxOS_pc486 -mposix -D_X86_ +OP_SYS_LDLIBS = -lc -lbsd -lnsl -lm -lposix4d9 -llynx + +#-------------------------------------------------- +# Optimization flag overrides +GCC_OPT_YES = -O +# 2 -fstrength-reduce +G++_OPT_YES = -O +# 2 -fstrength-reduce + +#-------------------------------------------------- +# Link definitions +LINK.c = $(LD) $(LDFLAGS) -o +LINK.cc = $(LD_CXX) $(LDFLAGS) -o + diff --git a/src/ca/ca_printf.c b/src/ca/ca_printf.c deleted file mode 100644 index ffbc6ccf9..000000000 --- a/src/ca/ca_printf.c +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************/ -/* */ -/* L O S A L A M O S */ -/* Los Alamos National Laboratory */ -/* Los Alamos, New Mexico 87545 */ -/* */ -/* Copyright, 1986, The Regents of the University of California. */ -/* */ -/* Author */ -/* ------ */ -/* Jeff Hill */ -/* */ -/* History */ -/* ------- */ -/* */ -/*_begin */ -/************************************************************************/ -/* */ -/* Title: channel access TCPIP interface include file */ -/* File: ca_printf.c */ -/* Environment: VMS, UNIX, VRTX */ -/* */ -/* */ -/* Purpose */ -/* ------- */ -/* */ -/* */ -/* */ -/* Special comments */ -/* ------- -------- */ -/* */ -/************************************************************************/ -/*_end */ - -static char *sccsId = "@(#) $Id$"; - -#include -#include - -#ifdef vxWorks -# include -# include -#endif /*vxWorks*/ - - - -/* - * - * - * ca_printf() - * - * Dump error messages to the appropriate place - * - */ -int ca_printf(char *pformat, ...) -{ - va_list args; - int status; - - va_start(args, pformat); - -#if defined(vxWorks) - status = mprintf(pformat, args); -#else - status = vfprintf(stderr, pformat, args); -#endif - - va_end(args); - - return status; -} diff --git a/src/db/setMasterTimeToSelf.c b/src/db/setMasterTimeToSelf.c deleted file mode 100644 index 8a263e40a..000000000 --- a/src/db/setMasterTimeToSelf.c +++ /dev/null @@ -1,99 +0,0 @@ -/* setMasterTimeToSelf.c ioc initialization */ -/* base/src/db $Id$ */ -/* - * Author: Bob Zieman - * Date: 09-11-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 09-11-92 rcz moved here from iocInit.c - * - */ - -/* - * SETMASTERTIMETOSELF - * - * This routine should only be called from function initHooks - * at case INITHOOKafterSetEnvParams or later but before - * INITHOOKafterTS_init - * - */ - - - - -#include -#include -#include -#include -#include -#include -#include -#include /* for N_TEXT */ -#include - - - - -void setMasterTimeToSelf() -{ - BOOT_PARAMS bp; - char *pnext; - char name[] = "_EPICS_IOCMCLK_INET"; - char message[100]; - UINT8 type; - long rtnval = 0; - char *pSymAddr; - int len = 0; - int i = 0; - char *ptr = 0; - - pnext = bootStringToStruct(sysBootLine, &bp); - if (*pnext != EOS) { - sprintf(message, - "setMasterTimeToSelf: unable to parse boot params\n"); - errMessage(-1L, message); - return; - } - rtnval = symFindByName(sysSymTbl, name, &pSymAddr, &type); - if (rtnval != OK || (type & N_TEXT == 0)) { - sprintf(message, - "setMasterTimeToSelf: symBol EPICS_IOCMCLK_INET not found"); - errMessage(-1L, message); - return; - } - ptr = (char*)&bp.ead; - len=strlen((char*)&bp.ead); - /* strip off mask */ - for (i=0; i -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Create the dsets*/ -static long init_1771Ife(); -static long read_1771Ife(); -static long linconv_1771Ife(); -static long init_1771Ife0to5V(); -static long read_1771Ife0to5V(); -static long linconv_1771Ife0to5V(); -static long init_1771IfeMa(); -static long read_1771IfeMa(); -static long linconv_1771IfeMa(); -static long init_1771IfeSe(); -static long read_1771IfeSe(); -static long linconv_1771IfeSe(); -static long init_1771Il(); -static long read_1771Il(); -static long linconv_1771Il(); -static long init_1771Ixe(); -static long read_1771Ixe(); -static long linconv_1771Ixe(); -static long init_1771IrPlatinum(); -static long read_1771IrPlatinum(); -static long init_1771IrCopper(); -static long read_1771IrCopper(); -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, NULL, NULL, init_1771Ife, NULL, - read_1771Ife, linconv_1771Ife}; -ABAIDSET devAiAb1771Ife0to5V= {6, NULL, NULL, init_1771Ife0to5V,NULL, - read_1771Ife0to5V, linconv_1771Ife0to5V}; -ABAIDSET devAiAb1771IfeMa= {6, NULL, NULL, init_1771IfeMa,NULL, - read_1771IfeMa, linconv_1771IfeMa}; -ABAIDSET devAiAb1771IfeSe= {6, NULL, NULL, init_1771IfeSe, NULL, - read_1771IfeSe, linconv_1771IfeSe}; -ABAIDSET devAiAb1771Il= {6, NULL, NULL, init_1771Il, NULL, - read_1771Il, linconv_1771Il}; -ABAIDSET devAiAb1771Ixe= {6, NULL, NULL, init_1771Ixe, NULL, - read_1771Ixe, linconv_1771Ixe}; -ABAIDSET devAiAb1771IrPlatinum= {6, NULL, NULL, init_1771IrPlatinum, NULL, - read_1771IrPlatinum, NULL}; -ABAIDSET devAiAb1771IrCopper= {6, NULL, NULL, init_1771IrCopper, NULL, - read_1771IrCopper, NULL}; - -static long init_1771Ofe(); -static int read_1771Ofe(); -static long write_1771Ofe(); -static long linconv_1771Ofe(); -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_ao; - DEVSUPFUN special_linconv;} ABAODSET; -ABAIDSET devAoAb1771Ofe={ 6, NULL, NULL, init_1771Ofe, NULL, - write_1771Ofe, linconv_1771Ofe}; - -static long init_bi(); -static long ioinfo_bi(); -static long read_bi(); -static long init_bi16(); -static long ioinfo_bi16(); -static long read_bi16(); -static long init_mbbi(); -static long init_mbbiDirect(); -static long ioinfo_mbbi(); -static long ioinfo_mbbiDirect(); -static long read_mbbi(); -static long read_mbbiDirect(); -static long init_mbbi16(); -static long init_mbbiDirect16(); -static long ioinfo_mbbi16(); -static long ioinfo_mbbiDirect16(); -static long read_mbbi16(); -static long read_mbbiDirect16(); -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi;} ABBIDSET; - -ABBIDSET devBiAb={ 5, NULL, NULL, init_bi, ioinfo_bi, read_bi}; -ABBIDSET devBiAb16={ 5, NULL, NULL, init_bi16, ioinfo_bi16, read_bi16}; -ABBIDSET devMbbiAb={ 5, NULL, NULL, init_mbbi, ioinfo_mbbi, read_mbbi}; -ABBIDSET devMbbiDirectAb={ 5, NULL, NULL, init_mbbiDirect, ioinfo_mbbiDirect, read_mbbiDirect}; -ABBIDSET devMbbiAb16={ 5, NULL, NULL, init_mbbi16, ioinfo_mbbi16, read_mbbi16}; -ABBIDSET devMbbiDirectAb16={ 5, NULL, NULL, init_mbbiDirect16, ioinfo_mbbiDirect16, read_mbbiDirect16}; - -static long init_bo(); -static long write_bo(); -static long init_bo16(); -static long write_bo16(); -static long init_mbbo(); -static long init_mbboDirect(); -static long write_mbbo(); -static long write_mbboDirect(); -static long init_mbbo16(); -static long init_mbboDirect16(); -static long write_mbbo16(); -static long write_mbboDirect16(); -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_bo;} ABBODSET; - -ABBODSET devBoAb={ 5, NULL, NULL, init_bo, NULL, write_bo}; -ABBODSET devBoAb16={ 5, NULL, NULL, init_bo16, NULL, write_bo16}; -ABBODSET devMbboAb={ 5, NULL, NULL, init_mbbo, NULL, write_mbbo}; -ABBODSET devMbboDirectAb={ 5, NULL, NULL, init_mbboDirect, NULL, write_mbboDirect}; -ABBODSET devMbboAb16={ 5, NULL, NULL, init_mbbo16, NULL, write_mbbo16}; -ABBODSET devMbboDirectAb16={ 5, NULL, NULL, init_mbboDirect16, NULL, write_mbboDirect16}; - - -static long init_1771Ife(struct aiRecord *pai) -{ - unsigned short value; - struct abio *pabio; - - /* ai.inp must be an AB_IO */ - switch (pai->inp.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiAb1771Ife (init_record) Illegal INP field"); - return(S_db_badField); - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - - /* call driver so that it configures card */ - /* The driver returns error for first call for a card. Ignore it. */ - pabio = (struct abio *)&(pai->inp.value); - ab_aidriver(AB1771IFE,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - return(0); -} - -static long read_1771Ife(struct aiRecord *pai) -{ - struct abio *pabio; - int status; - unsigned short value; - - - pabio = (struct abio *)&(pai->inp.value); - status = ab_aidriver(AB1771IFE,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - if(status==0 || status==-2) pai->rval = value; - if(status==-1) { - if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose - && (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pai,"ab_aidriver Error"); - status=2; /*dont convert*/ - }else if(status==-2) { - status=0; - recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM); - } - return(status); -} - - -static long linconv_1771Ife(struct aiRecord *pai, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - return(0); -} - -static long init_1771Ife0to5V(struct aiRecord *pai) -{ - unsigned short value; - struct abio *pabio; - - /* ai.inp must be an AB_IO */ - switch (pai->inp.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiAb1771Ife0to5V (init_record) Illegal INP field"); - return(S_db_badField); - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - - /* call driver so that it configures card */ - /* The driver returns error for first call for a card. Ignore it. */ - pabio = (struct abio *)&(pai->inp.value); - ab_aidriver(AB1771IFE_0to5V,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - return(0); -} - -static long read_1771Ife0to5V(struct aiRecord *pai) -{ - struct abio *pabio; - int status; - unsigned short value; - - - pabio = (struct abio *)&(pai->inp.value); - status=ab_aidriver(AB1771IFE_0to5V,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - if(status==0 || status==-2) pai->rval = value; - if(status==-1) { - if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose - && (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pai,"ab_aidriver Error"); - status=2; /*dont convert*/ - }else if(status==-2) { - status=0; - recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM); - } - return(status); -} - - -static long linconv_1771Ife0to5V(struct aiRecord *pai, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - return(0); -} - -static long init_1771IfeMa(struct aiRecord *pai) -{ - unsigned short value; - struct abio *pabio; - - /* ai.inp must be an AB_IO */ - switch (pai->inp.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiAb1771IfeMa (init_record) Illegal INP field"); - return(S_db_badField); - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - - /* call driver so that it configures card */ - /* The driver returns error for first call for a card. Ignore it. */ - pabio = (struct abio *)&(pai->inp.value); - ab_aidriver(AB1771IFE_4to20MA,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - return(0); -} - -static long read_1771IfeMa(struct aiRecord *pai) -{ - struct abio *pabio; - int status; - unsigned short value; - - - pabio = (struct abio *)&(pai->inp.value); - status=ab_aidriver(AB1771IFE_4to20MA,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - if(status==0 || status==-2) pai->rval = value; - if(status==-1) { - if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose - && (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pai,"ab_aidriver Error"); - status=2; /*dont convert*/ - }else if(status==-2) { - status=0; - recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM); - } - return(status); -} - - -static long linconv_1771IfeMa(struct aiRecord *pai, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - return(0); -} - -static long init_1771IfeSe(struct aiRecord *pai) -{ - unsigned short value; - struct abio *pabio; - - /* ai.inp must be an AB_IO */ - switch (pai->inp.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiAb1771IfeSe (init_record) Illegal INP field"); - return(S_db_badField); - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - - /* call driver so that it configures card */ - /* The driver returns error for first call for a card. Ignore it. */ - pabio = (struct abio *)&(pai->inp.value); - ab_aidriver(AB1771IFE_SE,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - return(0); -} - -static long read_1771IfeSe(struct aiRecord *pai) -{ - struct abio *pabio; - int status; - unsigned short value; - - - pabio = (struct abio *)&(pai->inp.value); - status = ab_aidriver(AB1771IFE_SE,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - if(status==0 || status==-2) pai->rval = value; - if(status==-1) { - if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose - && (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pai,"ab_aidriver Error"); - status = 2; /*don`t convert*/ - }else if(status==-2) { - status=0; - recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM); - } - return(status); -} - - -static long linconv_1771IfeSe(struct aiRecord *pai, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - return(0); -} - -static long init_1771Il(struct aiRecord *pai) -{ - unsigned short value; - struct abio *pabio; - - /* ai.inp must be an AB_IO */ - switch (pai->inp.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiAb1771Il (init_record) Illegal INP field"); - return(S_db_badField); - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - - /* call driver so that it configures card */ - /* The driver returns error for first call for a card. Ignore it. */ - pabio = (struct abio *)&(pai->inp.value); - ab_aidriver(AB1771IL,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - return(0); -} - -static long read_1771Il(struct aiRecord *pai) -{ - struct abio *pabio; - int status; - unsigned short value; - - - pabio = (struct abio *)&(pai->inp.value); - status = ab_aidriver(AB1771IL,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,pai->linr); - if(status==0 || status==-2) pai->rval = value; - if(status==-1) { - if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose - && (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pai,"ab_aidriver Error"); - status = 2; /*don't convert*/ - }else if(status==-2) { - status=0; - recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM); - } - return(status); -} - -static long linconv_1771Il(struct aiRecord *pai, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/4095.0; - return(0); -} - -static long init_1771Ixe(struct aiRecord *pai) -{ - short value; - struct abio *pabio; - short linr; - - /* ai.inp must be an AB_IO */ - switch (pai->inp.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiAb1771Ixe (init_record) Illegal INP field"); - return(S_db_badField); - } - - - /* If conversion type is 2,...,13 the Ixe performs the conversion*/ - /* In this case lets set linr = no conversion and use lbrk to tell*/ - /* allen bradley driver the correct conversion. */ - /* THIS SHOULD BE CHANGED */ - linr=pai->linr; - if(linr==0 || linr>13 ) { - pai->eslo=0.0; - pai->lbrk=0; - } - else if (linr==1) { - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/20000.0; - } - else if( linr>=2 && linr<=13 ) { - pai->linr=0; /* make sure record processing routine does not convert*/ - pai->lbrk=linr; - } - - /* call driver so that it configures card */ - /* The driver returns error for first call for a card. Ignore it. */ - pabio = (struct abio *)&(pai->inp.value); - linr=pai->linr; - if(linr==0) linr=pai->lbrk; - ab_aidriver(AB1771IXE,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,linr); - return(0); -} - -static long read_1771Ixe(struct aiRecord *pai) -{ - short linr; - struct abio *pabio; - long status; - short value; - - - linr=pai->linr; - if(linr==0) linr=pai->lbrk; - else if(linr>13) linr = 0; /*use breakpoint table*/ - pabio = (struct abio *)&(pai->inp.value); - status=ab_aidriver(AB1771IXE,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,linr); - if(status==-2) { - recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM); - status = 0; - } - if(status==0) { - if(linr<=1)pai->rval = value + 10000; - else { - pai->val = value; - pai->udf = FALSE; - status=2; /*don't convert*/ - } - } else if(status==-1) { - if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose - && (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pai,"ab_aidriver Error"); - status = 2; /*don't convert*/ - } - return(status); -} - -static long linconv_1771Ixe(struct aiRecord *pai, int after) -{ - short lbrk = pai->lbrk; - - if(lbrk>=2 && lbrk<=13) { - recGblRecordError(S_db_badField,(void *)pai,"DSET: special_linconv"); - return(S_db_badField); - } - if(!after) return(0); - /* set linear conversion slope*/ - pai->eslo = (pai->eguf -pai->egul)/20000.0; - return(0); -} - -static long init_1771IrPlatinum(struct aiRecord *pai) -{ - short value; - struct abio *pabio; - short conversion; - - /* ai.inp must be an AB_IO */ - switch (pai->inp.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiAb1771IrPlatinum (init_record) Illegal INP field"); - return(S_db_badField); - } - pabio = (struct abio *)&(pai->inp.value); - if(pabio->parm[0]=='C') { - conversion=IR_degC; - strcpy(pai->egu,"degC"); - } else if(pabio->parm[0]=='O') { - conversion = IR_Ohms; - strcpy(pai->egu,"ohms"); - } else { - conversion = 0; - strcpy(pai->egu,"degF"); - } - pai->linr = 0; - /* call driver so that it configures card */ - /* The driver returns error for first call for a card. Ignore it. */ - ab_aidriver(AB1771IrPlatinum,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,conversion); - return(0); -} - -static long read_1771IrPlatinum(struct aiRecord *pai) -{ - struct abio *pabio; - long status; - short value; - short conversion; - - - pabio = (struct abio *)&(pai->inp.value); - if(pabio->parm[0]=='C') conversion=IR_degC; - else if(pabio->parm[0]=='O') conversion = IR_Ohms; - else conversion = 0; - status=ab_aidriver(AB1771IrPlatinum,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,conversion); - if(status==-2) { - recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM); - status = 0; - } - if(status==0) { - if(conversion==IR_Ohms) pai->val = ((double)value)/100.0; - else pai->val = ((double)value)/10.0; - pai->udf = FALSE; - status=2; /*don't convert*/ - } else if(status==-1) { - if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose - && (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pai,"ab_aidriver Error"); - status = 2; /*don't convert*/ - } - return(status); -} - -static long init_1771IrCopper(struct aiRecord *pai) -{ - short value; - struct abio *pabio; - short conversion; - - /* ai.inp must be an AB_IO */ - switch (pai->inp.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiAb1771IrCopper (init_record) Illegal INP field"); - return(S_db_badField); - } - pabio = (struct abio *)&(pai->inp.value); - if(pabio->parm[0]=='C') { - conversion=IR_degC; - strcpy(pai->egu,"degC"); - } else if(pabio->parm[0]=='O') { - conversion = IR_Ohms; - strcpy(pai->egu,"ohms"); - } else { - conversion = 0; - strcpy(pai->egu,"degF"); - } - pai->linr = 0; - /* call driver so that it configures card */ - /* The driver returns error for first call for a card. Ignore it. */ - ab_aidriver(AB1771IrCopper,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,conversion); - return(0); -} - -static long read_1771IrCopper(struct aiRecord *pai) -{ - struct abio *pabio; - long status; - short value; - short conversion; - - - pabio = (struct abio *)&(pai->inp.value); - if(pabio->parm[0]=='C') conversion=IR_degC; - else if(pabio->parm[0]=='O') conversion = IR_Ohms; - else conversion = 0; - status=ab_aidriver(AB1771IrCopper,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value,conversion); - if(status==-2) { - recGblSetSevr(pai,HW_LIMIT_ALARM,INVALID_ALARM); - status = 0; - } - if(status==0) { - if(conversion==IR_Ohms) pai->val = ((double)value)/100.0; - else pai->val = ((double)value)/10.0; - pai->udf = FALSE; - status=2; /*don't convert*/ - } else if(status==-1) { - if(recGblSetSevr(pai,READ_ALARM,INVALID_ALARM) && errVerbose - && (pai->stat!=READ_ALARM || pai->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pai,"ab_aidriver Error"); - status = 2; /*don't convert*/ - } - return(status); -} - -static long init_1771Ofe(struct aoRecord *pao) -{ - - /* ao.out must be an AB_IO */ - switch (pao->out.type) { - case (AB_IO) : - break; - default : - recGblRecordError(S_db_badField,(void *)pao, - "devAoAb1771Ofe (init_record) Illegal OUT field"); - return(S_db_badField); - } - - /* set linear conversion slope*/ - pao->eslo = (pao->eguf -pao->egul)/4095.0; - - /* call driver so that it configures card */ - if (read_1771Ofe(pao)==0) return(0); - else return(2); - return(0); -} - -static long write_1771Ofe(struct aoRecord *pao) -{ - struct abio *pabio; - int status; - int value; - - pabio = (struct abio *)&(pao->out.value); - value = pao->rval; - status = ab_aodriver(AB1771OFE,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,value); - if(status==-1) { - if(recGblSetSevr(pao,WRITE_ALARM,INVALID_ALARM) && errVerbose - && (pao->stat!=WRITE_ALARM || pao->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pao,"ab_aodriver Error"); - }else if(status==-2) { - status=0; - recGblSetSevr(pao,HW_LIMIT_ALARM,INVALID_ALARM); - } - return(0); -} - - -static long linconv_1771Ofe(struct aoRecord *pao, int after) -{ - - if(!after) return(0); - /* set linear conversion slope*/ - pao->eslo = (pao->eguf -pao->egul)/4095.0; - return(0); -} - -static int read_1771Ofe(pao) -struct aoRecord *pao; -{ - unsigned short value; - struct abio *pabio = &pao->out.value.abio; - short failed; - - /* get the value from the ao driver */ - /* if this is the first channel on the card being read, */ - /* the block transfer from the ever so wonderful, Allen */ - /* Bradley IO, will not be ready. So we wait. The read */ - /* should only fail when the first channel on the card */ - /* is accessed. It typically fails only once. */ - failed = 0; - while ((ab_aoread(AB1771OFE,pabio->link,pabio->adapter, - pabio->card,pabio->signal,pabio->plc_flag,&value) < 0) - && (failed < 3)){ - failed++; - taskDelay(10); - } - if (failed >= 3) { - recGblSetSevr(pao,READ_ALARM,INVALID_ALARM); - return(-1); - } - pao->rval = value; - return(0); -} - -static long init_bi(struct biRecord *pbi) -{ - struct abio *pabio; - - /* bi.inp must be an AB_IO */ - switch (pbi->inp.type) { - case (AB_IO) : - pabio = (struct abio *)&(pbi->inp.value); - pbi->mask=1; - pbi->mask <<= pabio->signal; - break; - default : - recGblRecordError(S_db_badField,(void *)pbi, - "devBiAb (init_record) Illegal INP field"); - return(S_db_badField); - } - return(0); -} - -static long ioinfo_bi( - int cmd, - struct biRecord *pbi, - IOSCANPVT *ppvt) -{ - struct abio *pabio; - long value; - - pabio = (struct abio *)&(pbi->inp.value); - ab_bi_getioscanpvt(pabio->link,pabio->adapter,pabio->card,ppvt); - /*call ab_bidriver so that it knows it has a binary input*/ - if(cmd==0) { - (void) ab_bidriver(ABBI_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pbi->mask,&value); - } - return(0); -} - -static long read_bi(struct biRecord *pbi) -{ - struct abio *pabio; - int status; - long value; - - - pabio = (struct abio *)&(pbi->inp.value); - status = ab_bidriver(ABBI_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pbi->mask,&value); - if(status==0) { - pbi->rval = value; - return(0); - } else { - if(recGblSetSevr(pbi,READ_ALARM,INVALID_ALARM) && errVerbose - && (pbi->stat!=READ_ALARM || pbi->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pbi,"ab_bidriver Error"); - return(2); - } -} - -static long init_bi16(struct biRecord *pbi) -{ - struct abio *pabio; - - /* bi.inp must be an AB_IO */ - switch (pbi->inp.type) { - case (AB_IO) : - pabio = (struct abio *)&(pbi->inp.value); - pbi->mask=1; - pbi->mask <<= pabio->signal; - break; - default : - recGblRecordError(S_db_badField,(void *)pbi, - "devBiAb16 (init_record) Illegal INP field"); - return(S_db_badField); - } - return(0); -} - -static long ioinfo_bi16( - int cmd, - struct biRecord *pbi, - IOSCANPVT *ppvt) -{ - struct abio *pabio; - long value; - - pabio = (struct abio *)&(pbi->inp.value); - ab_bi_getioscanpvt(pabio->link,pabio->adapter,pabio->card,ppvt); - /*call ab_bidriver so that it knows it has a binary input*/ - if(cmd==0) { - (void) ab_bidriver(ABBI_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pbi->mask,&value); - } - return(0); -} - -static long read_bi16(struct biRecord *pbi) -{ - struct abio *pabio; - int status; - long value; - - - pabio = (struct abio *)&(pbi->inp.value); - status = ab_bidriver(ABBI_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pbi->mask,&value); - if(status==0) { - pbi->rval = value; - return(0); - } else { - if(recGblSetSevr(pbi,READ_ALARM,INVALID_ALARM) && errVerbose - && (pbi->stat!=READ_ALARM || pbi->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pbi,"ab_bidriver Error"); - return(2); - } -} - -static long init_mbbi(struct mbbiRecord *pmbbi) -{ - - /* mbbi.inp must be an AB_IO */ - switch (pmbbi->inp.type) { - case (AB_IO) : - pmbbi->shft = pmbbi->inp.value.abio.signal; - pmbbi->mask <<= pmbbi->shft; - break; - default : - recGblRecordError(S_db_badField,(void *)pmbbi, - "devMbbiAb (init_record) Illegal INP field"); - return(S_db_badField); - } - return(0); -} - -static long ioinfo_mbbi( - int cmd, - struct mbbiRecord *pmbbi, - IOSCANPVT *ppvt) -{ - struct abio *pabio; - unsigned long value; - - pabio = (struct abio *)&(pmbbi->inp.value); - ab_bi_getioscanpvt(pabio->link,pabio->adapter,pabio->card,ppvt); - /*call ab_bidriver so that it knows it has a binary input*/ - if(cmd==0) { - (void) ab_bidriver(ABBI_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbi->mask,&value); - } - return(0); -} - -static long read_mbbi(struct mbbiRecord *pmbbi) -{ - struct abio *pabio; - int status; - unsigned long value; - - - pabio = (struct abio *)&(pmbbi->inp.value); - status = ab_bidriver(ABBI_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbi->mask,&value); - if(status==0) { - pmbbi->rval = value; - return(0); - } else { - if(recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM) && errVerbose - && (pmbbi->stat!=READ_ALARM || pmbbi->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pmbbi,"ab_bidriver Error"); - return(2); - } -} - -static long init_mbbiDirect(struct mbbiDirectRecord *pmbbi) -{ - - /* mbbi.inp must be an AB_IO */ - switch (pmbbi->inp.type) { - case (AB_IO) : - pmbbi->shft = pmbbi->inp.value.abio.signal; - pmbbi->mask <<= pmbbi->shft; - break; - default : - recGblRecordError(S_db_badField,(void *)pmbbi, - "devMbbiDirectAb (init_record) Illegal INP field"); - return(S_db_badField); - } - return(0); -} - -static long ioinfo_mbbiDirect( - int cmd, - struct mbbiDirectRecord *pmbbi, - IOSCANPVT *ppvt) -{ - struct abio *pabio; - unsigned long value; - - pabio = (struct abio *)&(pmbbi->inp.value); - ab_bi_getioscanpvt(pabio->link,pabio->adapter,pabio->card,ppvt); - /*call ab_bidriver so that it knows it has a binary input*/ - if(cmd==0) { - (void) ab_bidriver(ABBI_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbi->mask,&value); - } - return(0); -} - -static long read_mbbiDirect(struct mbbiDirectRecord *pmbbi) -{ - struct abio *pabio; - int status; - unsigned long value; - - - pabio = (struct abio *)&(pmbbi->inp.value); - status = ab_bidriver(ABBI_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbi->mask,&value); - if(status==0) { - pmbbi->rval = value; - return(0); - } else { - if(recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM) && errVerbose - && (pmbbi->stat!=READ_ALARM || pmbbi->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pmbbi,"ab_bidriver Error"); - return(2); - } -} - -static long init_mbbi16(struct mbbiRecord *pmbbi) -{ - - /* mbbi.inp must be an AB_IO */ - switch (pmbbi->inp.type) { - case (AB_IO) : - pmbbi->shft = pmbbi->inp.value.abio.signal; - pmbbi->mask <<= pmbbi->shft; - break; - default : - recGblRecordError(S_db_badField,(void *)pmbbi, - "devMbbiAb16 (init_record) Illegal INP field"); - return(S_db_badField); - } - return(0); -} - -static long ioinfo_mbbi16( - int cmd, - struct mbbiRecord *pmbbi, - IOSCANPVT *ppvt) -{ - struct abio *pabio; - unsigned long value; - - pabio = (struct abio *)&(pmbbi->inp.value); - ab_bi_getioscanpvt(pabio->link,pabio->adapter,pabio->card,ppvt); - /*call ab_bidriver so that it knows it has a binary input*/ - if(cmd==0) { - (void) ab_bidriver(ABBI_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbi->mask,&value); - } - return(0); -} - -static long read_mbbi16(struct mbbiRecord *pmbbi) -{ - struct abio *pabio; - int status; - unsigned long value; - - pabio = (struct abio *)&(pmbbi->inp.value); - status = ab_bidriver(ABBI_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbi->mask,&value); - if(status==0) { - pmbbi->rval = value; - return(0); - } else { - if(recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM) && errVerbose - && (pmbbi->stat!=READ_ALARM || pmbbi->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pmbbi,"ab_bidriver Error"); - return(2); - } -} - -static long init_mbbiDirect16(struct mbbiDirectRecord *pmbbi) -{ - - /* mbbi.inp must be an AB_IO */ - switch (pmbbi->inp.type) { - case (AB_IO) : - pmbbi->shft = pmbbi->inp.value.abio.signal; - pmbbi->mask <<= pmbbi->shft; - break; - default : - recGblRecordError(S_db_badField,(void *)pmbbi, - "devMbbiDirectAb16 (init_record) Illegal INP field"); - return(S_db_badField); - } - return(0); -} - -static long ioinfo_mbbiDirect16( - int cmd, - struct mbbiDirectRecord *pmbbi, - IOSCANPVT *ppvt) -{ - struct abio *pabio; - unsigned long value; - - pabio = (struct abio *)&(pmbbi->inp.value); - ab_bi_getioscanpvt(pabio->link,pabio->adapter,pabio->card,ppvt); - /*call ab_bidriver so that it knows it has a binary input*/ - if(cmd==0) { - (void) ab_bidriver(ABBI_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbi->mask,&value); - } - return(0); -} - -static long read_mbbiDirect16(struct mbbiDirectRecord *pmbbi) -{ - struct abio *pabio; - int status; - unsigned long value; - - pabio = (struct abio *)&(pmbbi->inp.value); - status = ab_bidriver(ABBI_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbi->mask,&value); - if(status==0) { - pmbbi->rval = value; - return(0); - } else { - if(recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM) && errVerbose - && (pmbbi->stat!=READ_ALARM || pmbbi->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pmbbi,"ab_bidriver Error"); - return(2); - } -} - -static long init_bo(struct boRecord *pbo) -{ - unsigned long value; - struct abio *pabio; - int status=0; - - /* bo.out must be an AB_IO */ - switch (pbo->out.type) { - case (AB_IO) : - pabio = (struct abio *)&(pbo->out.value); - /* read the value via the ab driver */ - pbo->mask = 1; - pbo->mask <<= pabio->signal; - status = ab_boread(ABBO_08_BIT,pabio->link,pabio->adapter, - pabio->card,&value,pbo->mask); - if(status == 0) pbo->rval = value; - else status=2; - break; - default : - status=S_db_badField; - recGblRecordError(status,(void *)pbo,"devBoAb (init_record) Illegal OUT field"); - } - return(status); -} - -static long write_bo(struct boRecord *pbo) -{ - struct abio *pabio; - int status; - - - pabio = (struct abio *)&(pbo->out.value); - status = ab_bodriver(ABBO_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pbo->rval,pbo->mask); - if(status!=0) { - if(recGblSetSevr(pbo,WRITE_ALARM,INVALID_ALARM) && errVerbose - && (pbo->stat!=WRITE_ALARM || pbo->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pbo,"ab_bodriver Error"); - } - return(0); -} - -static long init_bo16(struct boRecord *pbo) -{ - unsigned long value; - struct abio *pabio; - int status=0; - - /* bo.out must be an AB_IO */ - switch (pbo->out.type) { - case (AB_IO) : - pabio = (struct abio *)&(pbo->out.value); - /* read the value via the ab driver */ - pbo->mask = 1; - pbo->mask <<= pabio->signal; - status = ab_boread(ABBO_16_BIT,pabio->link,pabio->adapter, - pabio->card,&value,pbo->mask); - if(status == 0) pbo->rval = value; - else status = 2; - break; - default : - status = S_db_badField; - recGblRecordError(status,(void *)pbo, - "devBoAb16 (init_record) Illegal OUT field"); - } - return(status); -} - -static long write_bo16(struct boRecord *pbo) -{ - struct abio *pabio; - int status; - - - pabio = (struct abio *)&(pbo->out.value); - status = ab_bodriver(ABBO_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pbo->rval,pbo->mask); - if(status!=0) { - if(recGblSetSevr(pbo,WRITE_ALARM,INVALID_ALARM) && errVerbose - && (pbo->stat!=WRITE_ALARM || pbo->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pbo,"ab_bodriver Error"); - } - return(0); -} - -static long init_mbbo(struct mbboRecord *pmbbo) -{ - unsigned long value; - struct abio *pabio; - int status=0; - - /* mbbo.out must be an AB_IO */ - switch (pmbbo->out.type) { - case (AB_IO) : - pabio = &(pmbbo->out.value.abio); - pmbbo->shft = pabio->signal; - pmbbo->mask <<= pmbbo->shft; - status = ab_boread(ABBO_08_BIT,pabio->link,pabio->adapter,pabio->card,&value,pmbbo->mask); - if(status==0) pmbbo->rval = value; - else status = 2; - break; - default : - status = S_db_badField; - recGblRecordError(status,(void *)pmbbo, - "devMbboAb (init_record) Illegal OUT field"); - } - return(status); -} - -static long write_mbbo(struct mbboRecord *pmbbo) -{ - struct abio *pabio; - int status; - unsigned long value; - - - pabio = &(pmbbo->out.value.abio); - status = ab_bodriver(ABBO_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbo->rval,pmbbo->mask); - if(status!=0) { - if(recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM) && errVerbose - && (pmbbo->stat!=WRITE_ALARM || pmbbo->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pmbbo,"ab_bodriver Error"); - } - return(0); -} - -static long init_mbboDirect(struct mbboDirectRecord *pmbbo) -{ - unsigned long value; - struct abio *pabio; - int status=0; - - /* mbbo.out must be an AB_IO */ - switch (pmbbo->out.type) { - case (AB_IO) : - pabio = &(pmbbo->out.value.abio); - pmbbo->shft = pabio->signal; - pmbbo->mask <<= pmbbo->shft; - status = ab_boread(ABBO_08_BIT,pabio->link,pabio->adapter,pabio->card,&value,pmbbo->mask); - if(status==0) pmbbo->rval = value; - else status = 2; - break; - default : - status = S_db_badField; - recGblRecordError(status,(void *)pmbbo, - "devMbboDirectAb (init_record) Illegal OUT field"); - } - return(status); -} - -static long write_mbboDirect(struct mbboDirectRecord *pmbbo) -{ - struct abio *pabio; - int status; - unsigned long value; - - - pabio = &(pmbbo->out.value.abio); - status = ab_bodriver(ABBO_08_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbo->rval,pmbbo->mask); - if(status!=0) { - if(recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM) && errVerbose - && (pmbbo->stat!=WRITE_ALARM || pmbbo->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pmbbo,"ab_bodriver Error"); - } - return(0); -} - -static long init_mbbo16(struct mbboRecord *pmbbo) -{ - unsigned long value; - struct abio *pabio; - int status=0; - - /* mbbo.out must be an AB_IO */ - switch (pmbbo->out.type) { - case (AB_IO) : - pabio = &(pmbbo->out.value.abio); - pmbbo->shft = pabio->signal; - pmbbo->mask <<= pmbbo->shft; - status = ab_boread(ABBO_16_BIT,pabio->link,pabio->adapter,pabio->card,&value,pmbbo->mask); - if(status==0) pmbbo->rval = value; - else status = 2; - break; - default : - status = S_db_badField; - recGblRecordError(status,(void *)pmbbo, - "devMbboAb16 (init_record) Illegal OUT field"); - } - return(status); -} - -static long write_mbbo16(struct mbboRecord *pmbbo) -{ - struct abio *pabio; - int status; - - - pabio = &(pmbbo->out.value.abio); - status = ab_bodriver(ABBO_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbo->rval,pmbbo->mask); - if(status!=0) { - if(recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM) && errVerbose - && (pmbbo->stat!=WRITE_ALARM || pmbbo->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pmbbo,"ab_bodriver Error"); - } - return(0); -} - -static long init_mbboDirect16(struct mbboDirectRecord *pmbbo) -{ - unsigned long value; - struct abio *pabio; - int status=0; - - /* mbbo.out must be an AB_IO */ - switch (pmbbo->out.type) { - case (AB_IO) : - pabio = &(pmbbo->out.value.abio); - pmbbo->shft = pabio->signal; - pmbbo->mask <<= pmbbo->shft; - status = ab_boread(ABBO_16_BIT,pabio->link,pabio->adapter,pabio->card,&value,pmbbo->mask); - if(status==0) pmbbo->rval = value; - else status = 2; - break; - default : - status = S_db_badField; - recGblRecordError(status,(void *)pmbbo, - "devMbboDirectAb16 (init_record) Illegal OUT field"); - } - return(status); -} - -static long write_mbboDirect16(struct mbboDirectRecord *pmbbo) -{ - struct abio *pabio; - int status; - - - pabio = &(pmbbo->out.value.abio); - status = ab_bodriver(ABBO_16_BIT,pabio->link,pabio->adapter, - pabio->card,pabio->plc_flag,pmbbo->rval,pmbbo->mask); - if(status!=0) { - if(recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM) && errVerbose - && (pmbbo->stat!=WRITE_ALARM || pmbbo->sevr!=INVALID_ALARM)) - recGblRecordError(-1,(void *)pmbbo,"ab_bodriver Error"); - } - return(0); -} - diff --git a/src/dev/devMbbiDirectTestAsyn.c b/src/dev/devMbbiDirectTestAsyn.c deleted file mode 100644 index f094fa76e..000000000 --- a/src/dev/devMbbiDirectTestAsyn.c +++ /dev/null @@ -1,148 +0,0 @@ -/* devMbbiDirectTestAsyn.c */ -/* base/src/dev $Id$ */ - -/* devMbbiDirectTestAsyn.c - Device Support for testing asynch processing */ -/* - * Original Author: Bob Dalesio - * Current Author: Matthew Needes - * Date: 10-08-93 - * - * 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: - * ----------------- - * (modification log of devMbbiDirectTestAsyn.c applies) - * .01 10-08-93 mcn added support for direct mbbi records - */ - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Create the dset for devMbbiDirectTestAsyn */ -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; - DEVSUPFUN special_linconv; -}devMbbiDirectTestAsyn={ - 6, - NULL, - NULL, - init_record, - NULL, - read_mbbi, - NULL}; - -/* control block for callback*/ -struct callback { - CALLBACK callback; - struct dbCommon *precord; - WDOG_ID wd_id; -}; - -static void myCallback(pcallback) - struct callback *pcallback; -{ - struct dbCommon *precord=pcallback->precord; - struct rset *prset=(struct rset *)(precord->rset); - - dbScanLock(precord); - (*prset->process)(precord); - dbScanUnlock(precord); -} - - -static long init_record(pmbbi) - struct mbbiDirectRecord *pmbbi; -{ - struct callback *pcallback; - - /* mbbi.inp must be a CONSTANT*/ - switch (pmbbi->inp.type) { - case (CONSTANT) : - pcallback = (struct callback *)(calloc(1,sizeof(struct callback))); - pmbbi->dpvt = (void *)pcallback; - callbackSetCallback(myCallback,pcallback); - pcallback->precord = (struct dbCommon *)pmbbi; - pcallback->wd_id = wdCreate(); - pmbbi->val = pmbbi->inp.value.value; - pmbbi->udf = FALSE; - break; - default : - recGblRecordError(S_db_badField,(void *)pmbbi, - "devMbbiDirectTestAsyn (init_record) Illegal INP field"); - return(S_db_badField); - } - return(0); -} - -static long read_mbbi(pmbbi) - struct mbbiDirectRecord *pmbbi; -{ - struct callback *pcallback=(struct callback *)(pmbbi->dpvt); - int wait_time; - - /* mbbi.inp must be a CONSTANT*/ - switch (pmbbi->inp.type) { - case (CONSTANT) : - if(pmbbi->pact) { - printf("%s Completed\n",pmbbi->name); - return(2); /* don't convert */ - } else { - wait_time = (int)(pmbbi->disv * vxTicksPerSecond); - if(wait_time<=0) return(0); - callbackSetPriority(pmbbi->prio,pcallback); - printf("%s Starting asynchronous processing\n",pmbbi->name); - wdStart(pcallback->wd_id,wait_time,(FUNCPTR)callbackRequest,(int)pcallback); - pmbbi->pact=TRUE; - return(0); - } - default : - if(recGblSetSevr(pmbbi,SOFT_ALARM,INVALID_ALARM)){ - if(pmbbi->stat!=SOFT_ALARM) { - recGblRecordError(S_db_badField,(void *)pmbbi, - "devMbbiDirectTestAsyn (read_mbbi) Illegal INP field"); - } - } - } - return(0); -} diff --git a/src/dev/devMbboDirectTestAsyn.c b/src/dev/devMbboDirectTestAsyn.c deleted file mode 100644 index d1df032f9..000000000 --- a/src/dev/devMbboDirectTestAsyn.c +++ /dev/null @@ -1,146 +0,0 @@ -/* devMbboDirectTestAsyn.c */ -/* base/src/dev $Id$ */ - -/* devMbboDirectTestAsyn.c - Device Support for testing asynch processing */ -/* - * Original Author: Bob Dalesio - * Current Author: Matthew Needes - * Date: 10-08-93 - * - * 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: - * ----------------- - * (modification log for devMbboTestAsyn applies) - * .01 10-08-93 mcn device support for MbboDirect records - */ - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Create the dset for devMbboDirectTestAsyn */ -static long init_record(); -static long write_mbbo(); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_mbbo; - DEVSUPFUN special_linconv; -}devMbboDirectTestAsyn={ - 6, - NULL, - NULL, - init_record, - NULL, - write_mbbo, - NULL}; - -/* control block for callback*/ -struct callback { - CALLBACK callback; - struct dbCommon *precord; - WDOG_ID wd_id; -}; - -static void myCallback(pcallback) - struct callback *pcallback; -{ - struct dbCommon *precord=pcallback->precord; - struct rset *prset=(struct rset *)(precord->rset); - - dbScanLock(precord); - (*prset->process)(precord); - dbScanUnlock(precord); -} - -static long init_record(pmbbo) - struct mbboDirectRecord *pmbbo; -{ - struct callback *pcallback; - - /* mbbo.out must be a CONSTANT*/ - switch (pmbbo->out.type) { - case (CONSTANT) : - pcallback = (struct callback *)(calloc(1,sizeof(struct callback))); - pmbbo->dpvt = (void *)pcallback; - callbackSetCallback(myCallback,pcallback); - pcallback->precord = (struct dbCommon *)pmbbo; - pcallback->wd_id = wdCreate(); - break; - default : - recGblRecordError(S_db_badField,(void *)pmbbo, - "devMbboDirectTestAsyn (init_record) Illegal OUT field"); - return(S_db_badField); - } - return(2); -} - -static long write_mbbo(pmbbo) - struct mbboDirectRecord *pmbbo; -{ - struct callback *pcallback=(struct callback *)(pmbbo->dpvt); - int wait_time; - - /* mbbo.out must be a CONSTANT*/ - switch (pmbbo->out.type) { - case (CONSTANT) : - if(pmbbo->pact) { - printf("%s Completed\n",pmbbo->name); - return(0); - } else { - wait_time = (int)(pmbbo->disv * vxTicksPerSecond); - if(wait_time<=0) return(0); - callbackSetPriority(pmbbo->prio,pcallback); - printf("%s Starting asynchronous processing\n",pmbbo->name); - wdStart(pcallback->wd_id,wait_time,(FUNCPTR)callbackRequest,(int)pcallback); - pmbbo->pact=TRUE; - return(0); - } - default : - if(recGblSetSevr(pmbbo,SOFT_ALARM,INVALID_ALARM)){ - if(pmbbo->stat!=SOFT_ALARM) { - recGblRecordError(S_db_badField,(void *)pmbbo, - "devMbboDirectTestAsyn (read_mbbo) Illegal OUT field"); - } - } - } - return(0); -} diff --git a/src/drv/Makefile.Vx b/src/drv/Makefile.Vx deleted file mode 100644 index 1b90ab7f3..000000000 --- a/src/drv/Makefile.Vx +++ /dev/null @@ -1,85 +0,0 @@ -EPICS = ../../../.. -include Target.include -include $(EPICS)/config/CONFIG_BASE - -USR_CFLAGS = -fshared-data -fvolatile -mnobitfield -traditional - -SRCS.c += ../module_types.c -SRCS.c += ../drvAb.c -SRCS.c += ../drvAt5Vxi.c -SRCS.c += ../drvBB232.c -SRCS.c += ../drvBb902.c -SRCS.c += ../drvBb910.c -SRCS.c += ../drvBitBus.c -# SRCS.c += ../drvCaenV265.c -SRCS.c += ../drvComet.c -SRCS.c += ../drvCompuSm.c -SRCS.c += ../drvDvx.c -SRCS.c += ../drvEpvxi.c -SRCS.c += ../drvEpvxiMsg.c -SRCS.c += ../drvFp.c -SRCS.c += ../drvFpm.c -SRCS.c += ../drvGpib.c -SRCS.c += ../drvHp1404a.c -SRCS.c += ../drvHpe1368a.c -SRCS.c += ../drvHpe1445a.c -SRCS.c += ../drvJgvtr1.c -SRCS.c += ../drvKscV215.c -SRCS.c += ../drvMsg.c -SRCS.c += ../drvMz8310.c -SRCS.c += ../drvOms.c -SRCS.c += ../drvStc.c -SRCS.c += ../drvTime.c -# SRCS.c += ../drvTranServ.c -SRCS.c += ../drvVmi4100.c -SRCS.c += ../drvXy010.c -SRCS.c += ../drvXy210.c -SRCS.c += ../drvXy220.c -SRCS.c += ../drvXy240.c -SRCS.c += ../drvXy566.c - -OBJS += module_types.o -OBJS += drvAb.o -OBJS += drvAt5Vxi.o -OBJS += drvBB232.o -OBJS += drvBb902.o -OBJS += drvBb910.o -OBJS += drvBitBus.o -# OBJS += drvCaenV265.o -OBJS += drvComet.o -OBJS += drvCompuSm.o -OBJS += drvDvx.o -OBJS += drvEpvxi.o -OBJS += drvEpvxiMsg.o -OBJS += drvFp.o -OBJS += drvFpm.o -OBJS += drvGpib.o -OBJS += drvHp1404a.o -OBJS += drvHpe1368a.o -OBJS += drvHpe1445a.o -OBJS += drvJgvtr1.o -OBJS += drvKscV215.o -OBJS += drvMsg.o -OBJS += drvMz8310.o -OBJS += drvOms.o -OBJS += drvStc.o -OBJS += drvTime.o -# OBJS += drvTranServ.o -OBJS += drvVmi4100.o -OBJS += drvXy010.o -OBJS += drvXy210.o -OBJS += drvXy220.o -OBJS += drvXy240.o -OBJS += drvXy566.o - - -PROD = drvSup - -include $(EPICS)/config/RULES.Vx - -$(PROD): $(OBJS) - $(RM) $@ - $(LINK.c) $@ $(OBJS) $(LDLIBS) - - - diff --git a/src/drv/TODO b/src/drv/TODO deleted file mode 100644 index ee07dda9a..000000000 --- a/src/drv/TODO +++ /dev/null @@ -1,8 +0,0 @@ -date person task ----- ------ ---- - Is suspect that AB driver will not reconfigure the - number of scanners and their offset at runtime. - - - The EPICS driver entry point structures in each - driver need to be extended diff --git a/src/drv/VXI_SETUP_README b/src/drv/VXI_SETUP_README deleted file mode 100644 index 42c6507a2..000000000 --- a/src/drv/VXI_SETUP_README +++ /dev/null @@ -1,30 +0,0 @@ - -The CPU030 may need to have the nivxi path set correctly: - From the vxWorks shell type "vxitedit" - take option 2 - take option 3 - type list - type modify 0 - type in the correct path when promped - (the path should end in nivxi - and should traverse the niCpu030 - directories shipped with the 030 - ie somethin of the form "???/config/niCPU030/nivxi" - type save - type exit - . - . - . - - -You may may need to setup front panel to backplane trigger -routing: - -To take a TTL input and map it to VXI backplane ECL trigger 0 -type in (to the vxWorks shell): - -epvxiRouteTriggerECL(, 1, 0) - -where specifies the card with the -front panel trigger connection. - diff --git a/src/drv/drvAb.c b/src/drv/drvAb.c deleted file mode 100644 index 84b417df5..000000000 --- a/src/drv/drvAb.c +++ /dev/null @@ -1,2505 +0,0 @@ -/* drvAb.c - Driver Support Routines for Allen Bradley */ -/* base/src/drv $Id$ */ -/* - * routines that are used, below the ai, ao, bi and bo drivers to interface - * to the Allen-Bradley Remote Serial IO - * - * Author: Bob Dalesio - * Date: 6-21-88 - * - * 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 - * - * Notes: - * 1. This driver uses Asynchronous Communications to the AB scanner - * The manual description for this type of interface is - * misleading in the area of interrupt handling. - * 2. We are using double slot addressing as the ab1771il card only works - * in this addressing mode. This dictates that analog io cards alternate - * between input and output. Therefore there are 6 input slots and - * 6 output slots per adapter. The binaries may be placed in either slot. - * Slots 1,3,5,7,9,11 are analog input slots - * Slots 2,4,6,8,10,12 are analog output slots - * The database uses card numbers 0-11 to address slots 1-12 - * 3. The binary io is memory mapped and the analog io is handled through - * block transfers of whole cards of data. - * 4. The timing rates for the analog inputs should not be made lower as - * the cards will not respond to the AB scanner any faster. - * - * Modification Log: - * ----------------- - * .01 09-15-88 lrd only spawn tasks if Allen-Bradley IO is present - * .02 09-15-88 lrd use the ##open(name,flags,mode)## circuit detect - * from the 6008 for read failure indication - * .03 09-15-88 lrd documentation for data and command flow - * .04 12-18-88 lrd fix the conversions - * .05 02-01-89 lrd changed vxTas to sysBusTas!!!!!!!!!!!! - * delete tasks before spawning again - * add 1771IFE card support - * .06 02-10-89 lrd read OFE at initialization - * .07 02-24-89 lrd modify for vxWorks 4.0 - * change spawn to taskSpawn and rearranged args - * change sysSetBCL to sysIntEnable - * move task data to task_params.h - * .08 03-10-89 lrd keep the scan list at initialization - * .09 03-14-89 lrd move interrupt enable to ioc_init - * .10 03-17-89 lrd modify link_init for restart - * provide read routines for outputs - * .11 03-23-89 lrd fixed ab_bidriver address not even numbers only - * and the mask and pvalue args were switched - * .12 03-25-89 lrd routines for the database to read the outputs - * at initialization - * .13 04-22-89 lrd implement binary IO to ignore addressing mode - * implement more than one serial link - * .14 04-24-89 lrd have one outstanding attempt for initialization - * .15 04-26-89 lrd removed card type checking for binary IO - * as the binaries are memory mapped into a - * seperate area - * .16 04-27-89 lrd recover from IO failures and pass the failure - * status back to the database - * .17 04-28-89 lrd fleshed out timeout counters and added check - * for conversion errors on IL and IFE modules - * .18 05-15-89 lrd took out scaling error check and made thre - * consecutive timeouts before a change of status - * .19 08-01-89 lrd changed mr_wait and bt_queue to always set - * length to 0 for compatibility with PLC-5 - * communication - * .20 09-29-89 ba/lrd changed the interrupt routine to remove response - * data from the dual port memory and queueing the - * entire response - * .21 09-29-89 lrd add scan_list command and support to build the - * scan list according to the database thus polling - * racks that may not have been powered at - * initialization - * .22 09-29-89 lrd add more error checking - * .23 10-17-89 cbf modified the way interrupts are dispatched in - * ab_intr - * .24 10-17-89 cbf added logic to avoid queueing requests to cards - * which already had a request pending to avoid - * overflowing scanner's queue when I/O card is missing - * .25 10-17-89 cbf added code to grab the operating status word - * in the interrupt routine to determine when the - * status of any scanned adapter has changed - * .26 10-17-89 cbf added logic to see if the scanner was using the - * dual port when we had it locked. it is! - * **************************************************************************** - * * Many of the above were needed to work around problems in the * - * * 6008-SV firmware. These problems have been reported to Allen- * - * * Bradley and fixes are promised. The PROMs we are presently using * - * * are both labeled "91332-501". U63 chksum = A7A1. U64 chksum = 912B * - * * (Series A, Revision C.) * - * **************************************************************************** - * .27 12-11-89 cbf new PROMs implemented which allow output image table - * to be preserved during SYSTEM RESET. This driver - * is still compatible with the old firmware also. - * A piece of code was added to store the firmware - * revision level in array ab_firmware_info. - * .28 12-11-89 cbf With the new firmware, the scanner no longer uses - * the dual port when we have it locked so the tests - * for this condition have been removed. - * .29 01-23-90 cbf In the previous rev of this driver we made an attempt - * to build a scan list automatically by waiting until - * the periodic scan task had asked for data from each - * needed adapter. This scheme caused problems with the - * the initialization of BOs and AOs, because they were - * not initially in the scan list and so could not be read - * at initialization. In this rev, that code has been - * removed and the scan list is always built to include all - * eight possible adapters. This has some performance - * implications because each non-existant adapter which - * appears in the scan list adds an extra 5 ms to each - * I/O scan time for the 6008SV. The decreased performance - * does not appear to be very significant, however. The - * 6008SV front panel "SER" LED blinks if not all adapters - * in the scan list are responding. With this rev of the - * driver, the light will therefore be blinking. - * .30 01-30-90 lrd add plc/adapter distinction - * .31 05-24-90 mk added 4-20Ma IFE support - * .32 05-25-90 jcr added PLC readback support - * .33 07-03-90 lrd fixed PLC readback verification - * .34 07-19-90 mk/lrd fixed the overrange indications (<< -> <<=) - * .35 11-02-90 lrd initialize the adapter buffers whether or not - * the link is there for detection by the bi and - * bo driver interface to the database library - * .36 11-27-90 lrd add support for the 16 BI and BO cards - * .37 12-19-90 lrd added 0-5V IFE support - ***************************************************************************************** - ** Allen-Bradley has given us a new firmware revision. This revision allows the reset * - ** of the scanner without using the sysReset on the VME backplane. It also maintains * - ** the output image table for the binary outputs. This reset is used to recover from * - ** a scanner fault, where the 6008 firmware deadends - ab_reset provides this function. * - ************************************************************************************************ - * .38 03-07-91 lrd modify ab_driver_init to not reinitialize semaphores and interrupts - * if this is not the first invocation - * .39 03-07-91 lrd modify the ab_aodriver to only set the update bit if the new value - * is different than the old value - * .40 03-08-91 lrd fix ab_boread to verify card is present - * .41 05-16-91 lrd have the ab_scan_task driver analog outputs - * periodically as well as on change - * .42 08-06-91 rac remove include for alarm.h--it's not used - * .43 09-11-91 joh updated for v5 vxWorks - * .44 11-16-91 bg moved io_report for Allen Bradley to this - * module. Broke io_report up into subroutines. - * Added sysBusToLocalAdrs and SysIntEnable - * .45 1-13-92 bg added level to io_report and added the - * ability to print raw - * values if the level is > 0 . - * .46 05-22-92 lrd added the task that monitors the binary - * inputs and simulates a change - * of state interrupt - wakes up the io event - * scanner - * .47 06-10-92 bg combined drvAb.c and ab_driver.c - * .48 06-26-92 bg added level to the ab_io_report in - * the drvSup structure - * .49 06-29-92 joh removed FILE pointer argument to io report - * .50 06-29-92 joh moved ab reset here - * .51 07-10-92 lrd mode interrupt on change of state to scan once on initialization - * .52 08-11-92 joh io report format cleanup - * .53 08-25-92 mrk made masks a macro - * .54 08-25-92 mrk added support for Type E,T,R,S Tcs - * .55 08-25-92 mrk support epics I/O event scan - * .56 06-30-93 mrk After 3 attempts to queue request Ask to initialize - * .57 07-22-93 mrk For BI call scanIoRequest when adapter status changes - * .58 07-22-93 mrk For AB1771IL sign_bit>>= becomes sign_bit<<= - * .59 07-27-93 mrk Included changes made by Jeff Hill to stop warning messages - * .60 07-27-93 mrk Made changes for vxWorks 5.x semLib - * .61 08-02-93 mrk Added call to taskwdInsert - * .62 08-04-93 mgb Removed V5/V4 and EPICS_V2 conditionals - * .62 09-04-93 mrk for bo and ao change value even if down - * .63 09-15-93 mrk make report shorter. - * .64 09-16-93 mrk ab_reset: all links; only reset scanner. - * .65 05-05-94 kornke IL Differential Fix - */ - -/* - * Binary Input Code Portions: - * - * process_bi - * | - * | - * | - * V - * ab_bidriver - * | ^ - * | mark card | data - * | as BI | - * V | - * ab_config AB dual ported memory - * ^ - * | - * | - * | - * AB 6008 scanner card - */ - - - -/* - * Binary Output Code Portions: - * - * process_bo - * | - * | - * | - * V - * ab_bodriver - * | | - * | mark card | data - * | as BO | - * V V - * ab_config AB dual ported memory - * | - * | - * | - * V - * AB 6008 scanner card - */ - -/* - * Analog Input Code Portions: - * - * process_ai - * | - * V - * ab_aidriver - * | ^ - * | mark card | - * | as AI | data - * V | - * ab_config ab_btdata - * | ^ - * | cards | data - * | present | returned - * V | - * abScanTask abDoneTask - * | ^ - * | commands | data - * V | - * bt_queue bt_done - * | ^ - * | commands | data - * V | - * AB dual ported memory - * | ^ - * | commands | data - * V | - * AB 6008 scanner card - */ - -/* - * Analog Output Code Portions: - * - * process_ao - * | - * V - * ab_aidriver - * | | - * | mark card | - * | as AI | data - * V V - * ab_config ab_btdata - * | | - * | cards | data - * | present | returned - * V V - * abScanTask - * | - * | command/data - * V - * bt_queue bt_done - * | ^ - * | command/data | acknowledge - * V | - * AB dual ported memory - * | ^ - * | command/data | acknowledge - * V | - * AB 6008 scanner card - */ - -#include -#include /* library for task support */ -#include /* library for semaphore support */ -#include -#include -#include /* library for watchdog timer support */ -#include /* library for ring buffer support */ -#include -#include - -#include -#include -#include -#include -#include - - - /* AllenBradley serial link and ai,ao,bi and bo cards */ -#define LOCK -2 - /* AllenBradley serial link and ai,ao,bi and bo cards */ - -/* If any of the following does not exist replace it with #define <> NULL */ -static long report(); -static long init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvAb={ - 2, - report, - init}; - - -static long report(level) -int level; -{ - return(ab_io_report(level)); -} - -/* forward reference for ab_reboot_hook */ -int ab_reboot_hook(); - -static long init() -{ - return(ab_driver_init()); -} - - -short ab_disable=0; - -/*jcr */ -/* response queue */ -struct ab_response{ -unsigned short status; -unsigned short link; -unsigned short adapter; -unsigned short card; -unsigned short command; -unsigned short data[64]; -}; - -/* internal timeout variables */ -short ab_tout[AB_MAX_LINKS]; /* time out flag */ -WDOG_ID wd_id[AB_MAX_LINKS]; /* watchdog task ID */ -int ab_timeout(); /* internal timeout handler */ - -/* message complete variables */ -SEM_ID ab_data_sem; /* transfer complete semaphore */ -SEM_ID ab_cmd_sem; /* transfer complete semaphore */ - /* following flag indicates to interrupt handler that we're - requesting a block xfer (and expect immediate confirmation) */ -short ab_requesting_bt[AB_MAX_LINKS]; -LOCAL RING_ID ab_cmd_q; /* links ready to be read */ -int ab_intr (); /* interrupt service routine */ -#define AB_Q_SZ 32*sizeof(struct ab_response) /* AB command Q size */ - -/* - * The configuration table contains a word to describe each card - * in each adapter. The word contains the following data: - * 0x0000 - not initialized - * 0xffff - no card present - * 0x8000 - initialized - * 0x4000 - updated data flag (used for sending analog outputs) - * 0x2000 - real time scan initialized - * 0x1000 - adapter/plc flag - * 0 - adapter - * 1 - PLC - * 0x0f00 - conversion - * For IXE - * 0 - no conversion (use millivolt range) - * 1 - linear (use millivolt range) - * 2 - K_DGF - * 3 - K_DGC - * 4 - J_DGF - * 5 - J_DGC - * 6 - E_DGF - * 7 - E_DGC - * 8 - T_DGF - * 9 - T_DGC - * 10- R_DGF - * 11- R_DGC - * 12- S_DGF - * 13- S_DGC - * For Ir - * 0- degF - * 1- degC - * 0x00e0 - interface type - * 0 - Not Assigned - * 1 - Binary Input - * 2 - Binary Output - * 3 - Analog Input - * 4 - Analog Output - * 0x001f - the Allen-Bradley card type (from ~gta/h/module_types.h) - * unique only per interface type - */ -unsigned short ab_config[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; - -/* - * Allen-Bradley Raw Data read through the abScanTask. This table - * will contain the analog inputs read using block transfers. It - * is also where analog outputs are placed to affect a change in an - * analog output signal Binary cards read and write directly into the - * Allen-Bradley dual ported memory - */ -short ab_btdata[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS][AB_CHAN_CARD]; - -/* array of pointers to the Allen-Bradley 6008 serial interface cards present */ -struct ab_region *p6008s[AB_MAX_LINKS]; - -/* Allen-Bradley Block Transfer Task */ -int abDoneId; /* id of the Allen-Bradley io complete task */ -int abCOSId; /* id of the Allen-Bradley binary input change of state scan wakeup */ -int abScanId; /* id of the Allen-Bradley scan task */ - -/* Timeout counters for outstanding data requests */ -/* The driver has to be smart about when the data requests are made because */ -/* the Allen-Bradley IO will hold up all requests if an IO card isn't ready */ -/* to talk. The thermocouple input card has a max scan rate of .5 second and */ -/* if it isn't ready when a request is made, all proceeding block transfers */ -/* will be held up. This table is used so that requests are only made at */ -/* a rate that the card can accept. */ -/* Some of the unpleasant side affects of making this number too small are: */ -/* 1. the interrupt for command done comes when the dual port memory is */ -/* unlocked - so you have to wait for the lock flag in a loop */ -/* 2. timeouts from the scanner occur rendering the data useless */ -/* Note that this problem increases exponentially */ -/* scan task rate is .1 second */ -short ab_timers[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; -#define AB_IXE_RATE 5 /* .5 seconds */ -#define AB_IL_RATE 4 /* .4 seconds */ -#define AB_IR_RATE 5 /* .5 seconds */ -#define AB_IFE_RATE 1 /* .1 seconds */ -#define AB_OFE_RATE 10 /* 1 seconds - written immediately */ -#define AB_INT_LEVEL 5 - -/* status on the Allen-Bradley driver interface */ - /* got back read/write info instead of cmd response */ -short ab_bad_response[AB_MAX_LINKS]; - /* got back cmd info instead of read/write response */ -short ab_rw_resp_err[AB_MAX_LINKS]; - /* watchdog timeouts through our internal timer */ -short ab_comm_to[AB_MAX_LINKS]; - /* data transfer timed out */ -short ab_data_to[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; - /* data xfer timeout detected through the AB scanner */ -short ab_cmd_to[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; - /* link status and scan list command timeouts */ -short ab_link_to[AB_MAX_LINKS]; - /* under range scaling error returned through block xfer */ -short ab_scaling_error[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; - /* over range scaling error returned through block xfer */ -short ab_or_scaling_error[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; - /* awakened but dual ported memory was unlocked */ -short ab_post_no_lock[AB_MAX_LINKS]; - /* no. time dpm locked when we wanted to talk */ -short ab_not_ready[AB_MAX_LINKS]; - /* card status 0 - good -1 - bad */ -char ab_btsts[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS][AB_CHAN_CARD]; - /* scanner operational status word */ -short ab_op_stat[AB_MAX_LINKS]; - /* Keeps track of how many times we've asked for data - before we actually receive it for a given card. Keeps - us from asking for data faster than card can supply it */ -unsigned short ab_btq_cnt[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; -#include -static IOSCANPVT ioscanpvt[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; - -/* - * flags a communication error on a link status - * which in turn flags all channels on the adapter as hardware errors - */ -short ab_adapter_status[AB_MAX_LINKS][AB_MAX_ADAPTERS]; -short ab_adapter_status_change[AB_MAX_LINKS][AB_MAX_ADAPTERS]; - -/* disables the scanner during a restart - required for */ -/* successful restart of the IOC */ - -/* scan list management variables */ -/* these are used to build and reset the scan list according to the */ -/* database */ - /* scan list built from the adapters_present array */ -char ab_scan_list[AB_MAX_LINKS][AB_MAX_ADAPTERS]; - /* scan attempts while waiting for initialization */ -char ab_init_cnt[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; - -/* debug variable (must be >1 to see all messages) */ -int ab_debug = 0; - -/* location to store scanner firmware revision info which is avail only temporarily */ -char ab_firmware_info[AB_MAX_LINKS][96]; - -static char *ab_stdaddr; - -/* - * - * support for ab reset - * - * - */ -unsigned short ab_reset_wait; -unsigned short reset_code[100]; -unsigned short reset_cnt = 0; - -/* forward references */ -static void wtrans(); -int abScanTask(); -void ab_reset_task(); -int ab_reset(); - -typedef enum{abbtSuccess,abbtCardUsed,abbtBusy, - abbtTimeout,abbtLinkDown,abbtError} abbtStatus; -/*definitions for BT_READ and BT_WRITE */ -typedef struct { - void (*callback)(); - unsigned short *pbuffer; - abbtStatus status; - unsigned short nwords; - void *userPvt; -} ABBTREQUEST; - -ABBTREQUEST *pabbtrequest[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; - -static void abBtCallback(link,adapter,card) -unsigned short link; -unsigned short adapter; -unsigned short card; -{ - ABBTREQUEST *preq=pabbtrequest[link][adapter][card]; - unsigned short *pcard = &ab_config[link][adapter][card]; - - if(!preq ) { - printf("Allen Bradley: abBtCallback Logic Error"); - return; - } - pabbtrequest[link][adapter][card] = NULL; - pcard = &ab_config[link][adapter][card]; - *pcard &= ~(AB_INTERFACE_TYPE|AB_INIT_BIT|AB_SENT_INIT); - (preq->callback)(preq); -} - -int ab_bt_read(link,adapter,card,preq) -unsigned short link; -unsigned short adapter; -unsigned short card; -ABBTREQUEST *preq; -{ - /* pointer to the Allen-Bradley configuration table */ - unsigned short *pcard = &ab_config[link][adapter][card]; - abbtStatus status; - - /* If card is initialized then error */ - if (*pcard & AB_INTERFACE_TYPE) { - if(((*pcard & AB_INTERFACE_TYPE)==AB_BT_READ) - || ((*pcard & AB_INTERFACE_TYPE)==AB_BT_WRITE)) { - status = abbtBusy; - } else { - status = abbtCardUsed; - } - return(status); - } - if(ab_adapter_status[link][adapter]) return(abbtLinkDown); - pabbtrequest[link][adapter][card] = preq; - ab_btq_cnt[link][adapter][card] = 0; - *pcard |= AB_BT_READ | AB_INIT_BIT; - return(abbtSuccess); -} - -int ab_bt_write(link,adapter,card,preq) -unsigned short link; -unsigned short adapter; -unsigned short card; -ABBTREQUEST *preq; -{ - /* pointer to the Allen-Bradley configuration table */ - unsigned short *pcard = &ab_config[link][adapter][card]; - abbtStatus status; - - /* If card is initialized then error */ - if (*pcard & AB_INTERFACE_TYPE) { - if(((*pcard & AB_INTERFACE_TYPE)==AB_BT_READ) - || ((*pcard & AB_INTERFACE_TYPE)==AB_BT_WRITE)) { - status = abbtBusy; - } else { - status = abbtCardUsed; - } - return(status); - } - if(ab_adapter_status[link][adapter]) return(abbtLinkDown); - ab_btq_cnt[link][adapter][card] = 0; - pabbtrequest[link][adapter][card] = preq; - *pcard |= AB_BT_WRITE | AB_INIT_BIT; - return(abbtSuccess); -} - -/* - * READ_AB_ADAPTER - * - * read an adapter of AB IO - */ -void read_ab_adapter(link,adapter,pass) -register unsigned short link; -register unsigned short adapter; -register short pass; -{ - register unsigned short card; - register unsigned short *pcard; - short btq_err; - short msg[64]; - - /* each card */ - for (card = 0, pcard = &ab_config[link][adapter][0]; - card < AB_MAX_CARDS; - card++, pcard++){ - - if (*pcard & AB_INTERFACE_TYPE){ - if((*pcard & AB_INTERFACE_TYPE)==AB_BT_READ) { - ABBTREQUEST *preq = pabbtrequest[link][adapter][card]; - abbtStatus status = abbtSuccess; - unsigned short count; - - - count = ab_btq_cnt[link][adapter][card]++ ; - if(count>1 && count<50) continue; - if(count>=50) status = abbtTimeout; - else if(bt_queue(AB_READ,link,adapter,card, - preq->nwords,preq->pbuffer)!=OK) status = abbtError; - preq->status = status; - if(status) abBtCallback(link,adapter,card); - continue; - } - if((*pcard & AB_INTERFACE_TYPE)==AB_BT_WRITE) { - ABBTREQUEST *preq = pabbtrequest[link][adapter][card]; - abbtStatus status = abbtSuccess; - unsigned short count; - - ab_btq_cnt[link][adapter][card]++; - count = ab_btq_cnt[link][adapter][card]++ ; - if(count>1 && count<50) continue; - if(count>=50) status = abbtTimeout; - else if(bt_queue(AB_WRITE,link,adapter,card, - preq->nwords,preq->pbuffer)!=OK) status = abbtError; - preq->status = status; - if(status) abBtCallback(link,adapter,card); - continue; - } - - /* need intialization */ /* jcr */ - if ((*pcard & AB_INIT_BIT) == 0){ - if ((*pcard & AB_SENT_INIT) == 0){ - if (*pcard & AB_PLC) { - *pcard |= AB_INIT_BIT; - *pcard |= AB_SENT_INIT; - } - else if (ab_card_init(pcard,adapter,card,link) == 0){ - *pcard |= AB_SENT_INIT; - ab_init_cnt[link][adapter][card] = 0; - } - /* did the init message get lost - try each second */ - }else if (ab_init_cnt[link][adapter][card]++ > 10){ - if (ab_card_init(pcard,adapter,card,link) == 0){ - ab_init_cnt[link][adapter][card] = 0; - } - } - continue; - } - /* need block transfer */ - btq_err = OK; /* assume success */ - - /* don't make another block transfer request if one's outstanding... */ - if((ab_btq_cnt[link][adapter][card] % 10) != 0) { - /* ...but try again periodically in case a request got lost. */ - ab_btq_cnt[link][adapter][card]++; - continue; - } - /*If 3 queue attempts fail then reinitialize*/ - if(ab_btq_cnt[link][adapter][card] >= 30) { - *pcard &= ~(AB_INIT_BIT | AB_SENT_INIT); - ab_btq_cnt[link][adapter][card] = 0; - continue; - } - - if ((*pcard & AB_INTERFACE_TYPE) == AB_AI_INTERFACE){ - switch (*pcard&AB_CARD_TYPE){ - case (AB1771IrPlatinum) : - case (AB1771IrCopper) : - if ((pass % AB_IR_RATE) == 0) { - btq_err = bt_queue(AB_READ,link,adapter,card,8,&msg[0]); - } - break; - case (AB1771IL): - if ((pass % AB_IL_RATE) == 0) { - btq_err = bt_queue(AB_READ,link,adapter,card,12,&msg[0]); - } - break; - case (AB1771IXE ): - if ((pass % AB_IXE_RATE) == 0) { - btq_err = bt_queue(AB_READ,link,adapter,card,12,&msg[0]); - } - break; - case (AB1771IFE): - case (AB1771IFE_4to20MA): - case (AB1771IFE_0to5V): - btq_err = bt_queue(AB_READ,link,adapter,card,12,&msg[0]); - break; - case (AB1771IFE_SE): - btq_err = bt_queue(AB_READ,link,adapter,card,20,&msg[0]); - break; - } - if(btq_err != OK){ - if(ab_debug) - logMsg("Error on AI BT request for L%x A%x C%x\n", - link,adapter,card); - } - - }else if ((*pcard&AB_INTERFACE_TYPE)==AB_AO_INTERFACE){ - if (((pass % AB_OFE_RATE) == 0) || (*pcard & AB_UPDATE)){ - ab_btwrite(pcard,adapter,card,link); - - } - } - } - } -} - -/* - * ab_card_init - * - * Allen-Bradley card initialization routines - */ -ab_card_init(pcard,adapter,card,link) -register unsigned short *pcard; /* AB configuration word */ -register unsigned short adapter; -register unsigned short card; -short link; -{ - short msg[64]; - register short *pmsg = &msg[0]; - register short length; - register short i; - register short *pab_table; - - bfill(pmsg,64*2,0); - *pmsg = 0; - switch (*pcard & AB_INTERFACE_TYPE){ - case (AB_AI_INTERFACE): - switch (*pcard & AB_CARD_TYPE){ - case (AB1771IrCopper) : - *pmsg = IR_COPPER; - case (AB1771IrPlatinum) : - i = (*pcard & AB_CONVERSION) >> 8; - if(i==IR_degF) *pmsg |= IR_UNITS_DEGF; - if(i==IR_Ohms) *pmsg |= IR_UNITS_OHMS; - *pmsg |= IR_SIGNED; - length = 1; - break; - case (AB1771IXE): /* millivolt module */ - /* need to base this on conversion */ - switch ((*pcard & AB_CONVERSION) >> 8){ - case (K_DGF): - *pmsg = IXE_K | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC; - break; - case (K_DGC): - *pmsg = IXE_K | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC; - break; - case (J_DGF): - *pmsg = IXE_J | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC; - break; - case (J_DGC): - *pmsg = IXE_J | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC; - break; - case (E_DGF): - *pmsg = IXE_E | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC; - break; - case (E_DGC): - *pmsg = IXE_E | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC; - break; - case (T_DGF): - *pmsg = IXE_T | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC; - break; - case (T_DGC): - *pmsg = IXE_T | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC; - break; - case (R_DGF): - *pmsg = IXE_R | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC; - break; - case (R_DGC): - *pmsg = IXE_R | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC; - break; - case (S_DGF): - *pmsg = IXE_S | IXE_DEGF | IXE_SIGNED | IXE_HALFSEC; - break; - case (S_DGC): - *pmsg = IXE_S | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC; - break; - default: - *pmsg = IXE_MILLI | IXE_DEGC | IXE_SIGNED | IXE_HALFSEC; - break; - } - length = 27; - break; - case (AB1771IL): - *pmsg = IL_RANGE; /* -10 to +10 volts */ - *(pmsg+1) = IL_DATA_FORMAT; /* signed magnitude */ - *(pmsg+2) = 0x0ff; - for (i = 4; i <= 18; i+=2) *(pmsg+i) = 0x4095; - length = 19; - break; - case (AB1771IFE): - *pmsg = 0xffff;/*IFE_RANGE; -10 to +10 volts */ - *(pmsg+1) = 0xffff;/*IFE_RANGE; -10 to +10 volts */ - *(pmsg+2) = 0x0700;/*IFE_DATA_FORMAT; signed magnitude, differential */ - *(pmsg+3) = 0x0ffff; - for (i = 6; i <= 36; i+=2) *(pmsg+i) = 0x4095; - length = 37; - break; - case (AB1771IFE_SE): - *pmsg = 0xffff;/*IFE_RANGE; -10 to +10 volts */ - *(pmsg+1) = 0xffff;/*IFE_RANGE; -10 to +10 volts */ - *(pmsg+2) = 0x0600;/*IFE_SE_DATA_FORMAT; signed magnitude, single-ended */ - *(pmsg+3) = 0x0ffff; - for (i = 6; i <= 36; i+=2) *(pmsg+i) = 0x4095; - length = 37; - break; - case (AB1771IFE_4to20MA): - *pmsg = 0x0000;/*IFE_RANGE; 4to20 MilliAmps */ - *(pmsg+1) = 0x0000;/*IFE_RANGE; 4to20 MilliApms */ - *(pmsg+2) = 0x0700;/*IFE_DATA_FORMAT; signed magnitude, double */ - for (i = 6; i <= 36; i+=2) *(pmsg+i) = 0x4095; - length = 37; - break; - case (AB1771IFE_0to5V): - *pmsg = 0x5555;/*IFE_RANGE; 0 to 5 Volts */ - *(pmsg+1) = 0x5555;/*IFE_RANGE; 0 to 5 Volts */ - *(pmsg+2) = 0x0700;/*IFE_DATA_FORMAT; signed magnitude, double */ - for (i = 6; i <= 36; i+=2) *(pmsg+i) = 0x4095; - length = 37; - break; - default: - return(-1); - } - break; - - case (AB_AO_INTERFACE): - /* initializing an analog output card includes writing the values */ - /* see also ab_aoread below */ - /* analog output reads the current outputs at initialization */ - if ((*pcard & AB_CARD_TYPE) == AB1771OFE){ - /* configuration data */ - *(pmsg+4) = OFE_BINARY | OFE_SCALING; - for (i = 6; i <= 12; i+=2) *(pmsg+i) = 0x4095; - length = 5; - return(bt_queue(AB_READ,link,adapter,card,length,pmsg)); - }else - return(-1); - break; - default: - return(-1); - } - - /* initate block tranfer */ - return(bt_queue(AB_WRITE,link,adapter,card,length,pmsg)); -} - -/* - * ab_btwrite - * - * block transfer - to write data - */ -ab_btwrite(pcard,adapter,card,link) -unsigned short *pcard; -register unsigned short adapter; -register unsigned short card; -register unsigned short link; -{ - short msg[64]; - register short *pmsg = &msg[0]; - register i; - register short *pab_table = &ab_btdata[link][adapter][card][0]; - short btq_err; - - /* clear out the dual ported memory */ - bfill(&msg[0],64*2,0); - - if ((*pcard & AB_CARD_TYPE) == AB1771OFE){ - /* take the data from the Allen-Bradley data table */ - for (i = 0; i < 4; i++, pab_table++) - *(pmsg+i) = *pab_table; - /* configuration data */ - *(pmsg+4) = OFE_BINARY | OFE_SCALING; - for (i = 6; i <= 12; i+=2) *(pmsg+i) = 0x4095; - - /* initate block tranfer */ - if(btq_err = bt_queue(AB_WRITE,link,adapter,card,5,pmsg)){ - if(ab_debug) - logMsg("link %x, ab_btwrite error %x\n",link,btq_err); - return (btq_err); - } - }else{ - return(-1); - } - return(0); -} - -/* - * bt_queue - * - * queue a block transfer request - */ -bt_queue(command,link,adapter,card,length,pmsg) -register unsigned short command; -register unsigned short link; -register unsigned short adapter; -unsigned short card; -unsigned short length; -unsigned short *pmsg; -{ - unsigned short *pcard = &ab_config[link][adapter][card]; - register struct ab_region *p6008 = p6008s[link]; - register struct dp_mbox *pmb = (struct dp_mbox *)(&p6008->mail); - register unsigned short *pmb_msg = (unsigned short *)&pmb->da; - register unsigned short lock_stat,i; - int status; - register unsigned short command_back; - - /* try to get access to (lock) the dual port memory */ - /* This prevents the Allen-Bradley scanner from accessing the dual */ - /* ported memory while a request is being made. */ - for(i=0; i<100; i++) { - if ((lock_stat = sysBusTas (&pmb->fl_lock)) == TRUE) break; - taskDelay(1); - } - if(lock_stat == FALSE) { - if(ab_debug != 0) - logMsg("link %x BTQ-dpm locked on %x cmd\n", - link,command); - ab_not_ready[link] += 1; - return (LOCK); - } - - /* As the scanner will not be sending us data during this command */ - /* request, we direct the interrupts here and wait for command */ - /* accepted. */ - ab_requesting_bt[link] = TRUE; - - /* clear the timeout flag */ - ab_tout[link] = OK; - - /* copy the message into the dual-ported memory */ - - /* clear the semaphore to make sure we stay in sync */ - if((semTake(ab_cmd_sem,NO_WAIT) == OK) && ab_debug) - logMsg("link %x, semaphore set before bt_queue cmd %x,%x,%x\n", - link,command,pmb->command,pmb->conf_stat); - - pmb->command = command; - /* jcr */ - if ((*pcard & AB_PLC)==0) { - pmb->address = (adapter << 4) + card; - pmb->data_len = length; - }else{ - pmb->address = (adapter << 4); /* always writes to card 0 */ - pmb->data_len = 0; /* PLCs govern the length */ - /* used by the PLC to determine where the data comes from */ - /* the PLC programmers have to use this knowledge fopr the */ - /* interface */ - pmsg[62] = card; - } - wtrans(pmsg,pmb_msg); - - /* initiate the timeout clock */ - wdStart(wd_id[link],vxTicksPerSecond,ab_timeout,link); - /* alert the scanner to the new request */ - p6008->sc_intr = 1; - - /* wait for the command to be accepted */ - semTake(ab_cmd_sem, WAIT_FOREVER); - /* determine if the command was accepted */ - if (ab_tout[link] == ERROR){ - if(ab_debug) - logMsg("link %x, BTQ cmd %x...timeout\n",link,command); - ab_cmd_to[link][adapter][card]++; - ab_requesting_bt[link] = FALSE; - /* unlock the dual ported memory */ - pmb->fl_lock = 0; - return(ERROR); - } - - /* get the status & command from the dual-ported memory */ - status = pmb->conf_stat; - command_back = pmb->command; - if(command_back != command){ - if (ab_debug) - logMsg("link %x, BTQ cmd %x, resp=%x\n" - ,link,command,command_back); - ab_bad_response[link]++; - status = ERROR; - } - if (status != BT_ACCEPTED){ - if (status == 0x14){ - taskDelay(vxTicksPerSecond/10); - if(ab_debug >1) - logMsg("link %x BTQ full, delaying...\n",link); - }else{ - if(ab_debug != 0) - logMsg("link %x BTQ failure %x\n",link,status); - } - }else - status = OK; - /* return the interrupts to the data received state */ - ab_requesting_bt[link] = FALSE; - - /* unlock the dual ported memory */ - pmb->fl_lock = 0; - - /* indicate that a response is queued for this card */ - if(command == AB_READ) ab_btq_cnt[link][adapter][card]++; - - return(0); -} - -/* - * abDoneTask - * - * This task handles block transfer data returned from the Allen-Bradley - * scan task through the dual ported memory. - * It needs to acknowledge that a block tranfer card (analog io) has been - * successfully configured or place the read data into the block transfer - * memory. - */ -abDoneTask(){ - register short i,sign_bit,card,plc_card; - unsigned short adapter,link; - register unsigned short *pcard; /* ptr to configuration word */ - register short *pab_table; - char *pab_sts; - struct ab_response response; - struct ab_response *presponse = &response; - while(TRUE){ - /* wait for block transfer completion */ - semTake(ab_data_sem, WAIT_FOREVER); - while (rngBufGet(ab_cmd_q,&response,sizeof(struct ab_response)) - == sizeof(struct ab_response)){ - link = presponse->link; - - /* make sure we got a response to a read or write command */ - if ((presponse->command != AB_READ) - && (presponse->command != AB_WRITE)){ - ab_rw_resp_err[link]++; - continue; - } - - /* find whose data this is */ - /* unpacks the card pack out of the message */ - /* this codes determines if it is a PLC or */ - /* adapter response */ - adapter = presponse->adapter; - card = presponse->card; - plc_card = presponse->data[62]; - - /* let's determine if this is a PLC - verify with config table */ - if ((plc_card <= 16) && (plc_card >= 0) - && (ab_config[link][adapter][plc_card] & AB_PLC)) - card = plc_card; - - pcard = &ab_config[link][adapter][card]; - - /* zero counter to indicate that a requested BT was received */ - ab_btq_cnt[link][adapter][card] = 0; - if(((*pcard & AB_INTERFACE_TYPE)==AB_BT_READ) - || ((*pcard & AB_INTERFACE_TYPE)==AB_BT_WRITE)) { - ABBTREQUEST *preq = pabbtrequest[link][adapter][card]; - - /* block transfer timeout */ - if (presponse->status == 0x23) { - preq->status = abbtTimeout; - } else { - preq->status = abbtSuccess; - } - if((*pcard & AB_INTERFACE_TYPE)==AB_BT_READ) { - for(i=0; inwords; i++) - preq->pbuffer[i] = presponse->data[i]; - } - abBtCallback(link,adapter,card); - continue; - } - - /* block transfer timeout */ - if (presponse->status == 0x23){ - if (ab_debug >1) - logMsg("link %x adapter %x card %x timeout %x\n" - ,link,adapter,card,presponse->status); - ab_data_to[link][adapter][card]++; - /* mark the channels on this card as harware error */ - pab_sts = &ab_btsts[link][adapter][card][0]; - for (i=0; istatus != 0){ - if (ab_debug != 0) - logMsg("L%x A%x C%x, Bad Done Status=%x\n" - ,link,adapter,card,presponse->status); - continue; - } - - /* was it a response to configuration */ - if ((*pcard & AB_INIT_BIT) == 0){ - *pcard |= AB_INIT_BIT; - ab_init_cnt[link][adapter][card] = 0; - - /* analog outputs return values on init */ - if ((*pcard & AB_INTERFACE_TYPE)==AB_AO_INTERFACE) - { - register struct ab1771ofe_write *pmsg - = (struct ab1771ofe_write *)presponse->data; - pab_table = &ab_btdata[link][adapter][card][0]; - for (i = 0; i < 4; i++,pab_table++) - *pab_table = pmsg->data[i]; - } - - /* it was a response to a command */ - /* analog input response */ - }else if ((*pcard & AB_INTERFACE_TYPE) == AB_AI_INTERFACE){ - if((*pcard & AB_CARD_TYPE) == AB1771IrPlatinum - || (*pcard & AB_CARD_TYPE) == AB1771IrCopper) - { - struct ab1771ir_read *pmsg = (struct ab1771ir_read *) presponse->data; - short under,over,overflow,polarity; - - pab_table = &ab_btdata[link][adapter][card][0]; - pab_sts = &ab_btsts[link][adapter][card][0]; - for(i=0, under = 0x1, over=0x100, overflow=0x1, polarity=0x100; - idata[i]; - if(pmsg->pol_over&polarity) *pab_table = -*pab_table; - if((pmsg->status&under) || (pmsg->status&over) - || (pmsg->pol_over&overflow)) { - *pab_sts = -3; - ab_scaling_error[link][adapter][card]++; - }else{ - *pab_sts = 0; - } - pab_sts++; - pab_table++; - } - } - else if ((*pcard & AB_CARD_TYPE) == AB1771IL) - { - register struct ab1771il_read *pmsg - = (struct ab1771il_read *)presponse->data; - pab_table = &ab_btdata[link][adapter][card][0]; - pab_sts = &ab_btsts[link][adapter][card][0]; - for (i=0, sign_bit=1; i < ai_num_channels[AB1771IL]; i++, sign_bit<<= 1){ - /* status */ - if((pmsg->urange & sign_bit) || (pmsg->orange & sign_bit)){ - *pab_sts = -3; - ab_scaling_error[link][adapter][card]++; - }else{ - *pab_sts = 0; - /* data */ - *pab_table = pmsg->data[i]; - } - pab_sts++; - pab_table++; - } - } - else if ((*pcard & AB_CARD_TYPE) == AB1771IXE) - { - register struct ab1771ixe_read *pmsg - = (struct ab1771ixe_read *)presponse->data; - pab_table = &ab_btdata[link][adapter][card][0]; - pab_sts = &ab_btsts[link][adapter][card][0]; - for (i=0, sign_bit=0x1; iout_of_range & sign_bit) - || (pmsg->out_of_range & (sign_bit << 8))){ - *pab_sts = -3; - ab_scaling_error[link][adapter][card]++; - }else{ - *pab_sts = 0; - /* data */ - *pab_table = pmsg->data[i]; - if(pmsg->pol_stat & (sign_bit << 8)) *pab_table = -*pab_table; - } - pab_sts++; - pab_table++; - } - } - else if ((*pcard & AB_CARD_TYPE) == AB1771IFE) - { - register struct ab1771ife_read *pmsg - = (struct ab1771ife_read *)presponse->data; - pab_table = &ab_btdata[link][adapter][card][0]; - pab_sts = &ab_btsts[link][adapter][card][0]; - /* check each channel as overrange */ - for (i=0, sign_bit=0x1; iurange & sign_bit){ - *pab_sts = -3; - ab_scaling_error[link][adapter][card]++; - }else if(pmsg->orange & sign_bit){ - *pab_sts = -3; - ab_or_scaling_error[link][adapter][card]++; - }else if ((pmsg->data[i] & 0xf000) > 0){ - ab_or_scaling_error[link][adapter][card]++; - }else{ - *pab_sts = 0; - *pab_table = pmsg->data[i]; /* put data in table */ - } - pab_sts++; - pab_table++; - } - } - else if ((*pcard & AB_CARD_TYPE) == AB1771IFE_SE) - { - register struct ab1771ife_read *pmsg - = (struct ab1771ife_read *)presponse->data; - pab_table = &ab_btdata[link][adapter][card][0]; - pab_sts = &ab_btsts[link][adapter][card][0]; - /* check each channel as overrange */ - for (i=0, sign_bit=0x1; iurange & sign_bit){ - *pab_sts = -3; - ab_scaling_error[link][adapter][card]++; - }else if(pmsg->orange & sign_bit){ - *pab_sts = -3; - ab_or_scaling_error[link][adapter][card]++; - }else if ((pmsg->data[i] & 0xf000) > 0){ - ab_or_scaling_error[link][adapter][card]++; - }else{ - *pab_sts = 0; - *pab_table = pmsg->data[i]; /* put data in table */ - } - pab_sts++; - pab_table++; - } - } - else if ( ((*pcard & AB_CARD_TYPE) == AB1771IFE_4to20MA) - || ((*pcard & AB_CARD_TYPE) == AB1771IFE_0to5V ) ) - { - register struct ab1771ife_read *pmsg - = (struct ab1771ife_read *)presponse->data; - pab_table = &ab_btdata[link][adapter][card][0]; - pab_sts = &ab_btsts[link][adapter][card][0]; - /* check each channel as overrange */ - for (i=0, sign_bit=0x1; - iurange & sign_bit){ - *pab_sts = -3; - ab_scaling_error[link][adapter][card]++; - }else if(pmsg->orange & sign_bit){ - *pab_sts = -3; - ab_or_scaling_error[link][adapter][card]++; - }else if ((pmsg->data[i] & 0xf000) > 0){ - ab_or_scaling_error[link][adapter][card]++; - }else{ - *pab_sts = 0; - *pab_table = pmsg->data[i]; /* put data in table */ - } - pab_sts++; - pab_table++; - } - } - /* analog output response */ - }else if ((*pcard & AB_CARD_TYPE) == AB1771OFE){ - *pcard = *pcard & (~AB_UPDATE); /* mark as updated */ - } - } - } -} - - -/* - * AB_BI_COS_SIMULATOR - * - * simulate a change of state interrupt from the Allen-Bradley - */ -unsigned short ab_old_binary_ins[AB_MAX_LINKS][AB_MAX_ADAPTERS][AB_MAX_CARDS]; -ab_bi_cos_simulator() -{ - register struct ab_region *p6008; - register unsigned short link; - register unsigned short *pcard; - unsigned short new; - unsigned short *pold; - short adapter,card,inpinx; - short first_scan,first_scan_complete; - short adapter_status_change; - - /* dont do anything until interruptAccept */ - for(;;){ - if(interruptAccept) break; - taskDelay(vxTicksPerSecond/15); - } - first_scan_complete = FALSE; - first_scan = TRUE; - for(;;){ - for (link = 0; link < AB_MAX_LINKS; link++){ - if ((p6008 = p6008s[link]) == 0) continue; - for (adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - adapter_status_change = ab_adapter_status_change[link][adapter]; - ab_adapter_status_change[link][adapter] = 0; - - /* check each card that is configured to be a binary input card */ - for (card = 0; card < AB_MAX_CARDS; card++){ - pcard = &ab_config[link][adapter][card]; - inpinx = (adapter * AB_CARD_ADAPTER) + card; - pold = &ab_old_binary_ins[link][adapter][card]; - if ((*pcard & AB_INTERFACE_TYPE) != AB_BI_INTERFACE) continue; - if ((*pcard & AB_CARD_TYPE) == ABBI_16_BIT){ - /* sixteen bit byte ordering in dual ported memory */ - /* byte 0011 2233 4455 6677 8899 AABB */ - /* card 0000 2222 4444 6666 8888 AAAA */ - if (inpinx & 0x1) continue; - new = *(unsigned short *)&(p6008->iit[inpinx]); - }else{ - /* eight bit byte ordering in dual ported memory */ - /* 1100 3322 5544 7766 9988 BBAA */ - if (inpinx & 0x1) inpinx--; /* shuffle those bytes */ - else inpinx++; - new = (unsigned short)(p6008->iit[inpinx]); - } - if((new!=*pold) || first_scan || adapter_status_change){ - scanIoRequest(ioscanpvt[link][adapter][card]); - *pold = new; - } - } - } - } - - /* turn off first scan */ - if (first_scan){ - first_scan_complete = TRUE; - first_scan = FALSE; - } - - /* check for changes at about 15 Hertz */ - taskDelay(vxTicksPerSecond/15); - } -} - -int ab_bi_getioscanpvt(link,adapter,card,scanpvt) -unsigned short link; -unsigned short adapter; -unsigned short card; -IOSCANPVT *scanpvt; -{ - *scanpvt = ioscanpvt[link][adapter][card]; - return(0); -} - -/* - * ALLEN-BRADLEY DRIVER INITIALIZATION CODE - */ -ab_driver_init() -{ - unsigned short cok,got_one; - register unsigned short err_cnt; - register unsigned short not_init; - register unsigned short link; - struct ab_region *p6008; - int status; - - /* initialize the Allen-Bradley 'done' semaphore */ - if (abScanId == 0){ - if(!(ab_cmd_sem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))) - errMessage(0,"semBcreate failed in initEvent"); - if(!(ab_data_sem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))) - errMessage(0,"semBcreate failed in initEvent"); - if ((ab_cmd_q = rngCreate(AB_Q_SZ)) == (RING_ID)NULL) - panic ("ab_init: ab_cmd_q\n"); - } - got_one = FALSE; - if ((status = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA,AB_BASE_ADDR,&ab_stdaddr)) != OK){ - logMsg("Addressing error in ab driver\n"); - return ERROR; - } - p6008 =(struct ab_region *)ab_stdaddr; - for (link=0;link < AB_MAX_LINKS; link++,p6008++){ - /* initialize the AB config buffer for this link */ - bfill(&ab_config[link][0][0], - AB_MAX_ADAPTERS*AB_MAX_CARDS*sizeof(short), - 0); - bfill(&ab_btdata[link][0][0][0], - AB_MAX_ADAPTERS*AB_MAX_CARDS*AB_CHAN_CARD*sizeof(short), - 0); - bfill(&pabbtrequest[link][0][0], - AB_MAX_ADAPTERS*AB_MAX_CARDS*sizeof(ABBTREQUEST *), - 0); - - /* initialize each 6008 that exists */ - if (vxMemProbe(p6008,READ,1,&cok) != ERROR){ - p6008s[link] = p6008; - err_cnt = 0; - not_init = TRUE; - /* create the internal watchdog timer */ - if (wd_id[link] == 0) - wd_id[link] = wdCreate(); - - /*connect intr service routine to intr vector */ - intConnect((AB_VEC_BASE+link)*4,ab_intr,link); - sysIntEnable(AB_INT_LEVEL); - - while ((err_cnt < 5) && (not_init)){ - if (link_init(link) >=0) not_init = FALSE; - else { - err_cnt++; - logMsg("link %x, link_init error\n",link); - } - } - if (err_cnt >= 5){ - p6008s[link] = 0; - }else{ - got_one = TRUE; - } - }else{ - p6008s[link] = 0; - } - if(p6008s[link]) { - int adapter,card; - for(adapter=0; adaptermail); - char *pfirmware_info = &ab_firmware_info[link][0]; - - ab_bad_response[link]=0; - ab_rw_resp_err[link]=0; - - /* the scanner comes up with the dual ported memory locked */ - pmb->fl_lock = 0; /* so unlock it */ - - /* initialize the scanner on power up */ - if (pmb->conf_stat == SCANNER_POWERUP){ - logMsg("link %x, powerup...\n",link); - /* on initialization the scanner puts its firmware revision info */ - /* into the general data are of the dual-port. We save it here. */ - /* (The most current revision is Series A, Revision D.) */ - strcpy(pfirmware_info,(char *)&pmb->da); - if(ab_debug != 0) - logMsg("link %x f/w = :\n\t%s\n",link,ab_firmware_info[link]); - /*scanner comes up in program_mode */ - ab_op_stat[link] = PROGRAM_MODE; - /*interrupt the scanner to wake it up */ - p6008->sc_intr = 1; - } - - logMsg("Link %x, initial operating status word = %x\n",link,ab_op_stat[link]); - - if((ab_op_stat[link] & PROGRAM_MODE) != PROGRAM_MODE){ - /* This link must already be initialized. We're done */ - logMsg("Link %x already initialized\n",link); - return(0); - } - - /* setup scanner */ - bfill(pbuffer,80,0); - *(pbuffer) = DEF_RATE; /* baud rate */ - *(pbuffer+2) = DEBUG; /* always in debug mode - don't know why */ - *(pbuffer+3) = AB_IL; /* interrupt level */ - *(pbuffer+4) = AB_VEC_BASE+link; /* interrupt vector */ - *(pbuffer+5) = AB_INT_ENABLE; /* enable interrupt */ - *(pbuffer+6) = AB_SYSFAIL_DISABLE; /* disable VMEbus SYSFAIL sig */ - length = 7; - if((mr_w_err = mr_wait(SET_UP,length,pbuffer,link)) != OK){ - if (ab_debug != 0) - logMsg("link %x link_init set_up cmd - mr_wait error %x\n" - ,link,mr_w_err); - return(-1); - } - - /* Once scanner has been placed in RUN_MODE, putting it back into * - * PROGRAM_MODE will disable binary outputs until it is placed back in * - * RUN_MODE. Some scanner commands, such as SCAN_LIST, can only be * - * performed in PROGRAM_MODE. These commands should only be issued * - * immediately after initialization. Re-booting an IOC (without powering - * it down) is the presently the only way of getting it into PROGRAM_MODE - * without disabling binary outputs */ - - /* initialize scan list for each link present */ - if(scan_list(link) != OK){ - logMsg(" scan_list error on link %x\n",link); - return(-1); - } - - return(0); -} - -/* - * MR_WAIT - * - * scanner management command send - */ -mr_wait(command,length,pmsg,link) -unsigned short command; -short length; -short *pmsg; -unsigned short link; -{ - register struct ab_region *p6008 = p6008s[link]; - register struct dp_mbox *pmb = (struct dp_mbox *)&p6008->mail; - register short *pmb_msg, i, lock_stat; - short rtn_val; - - /* pointer to the message portion of the mailbox */ - pmb_msg = (short *)&pmb->da; - - /* try to get access to (lock) the dual port memory */ - for(i=0; i<100; i++) { - if ((lock_stat = sysBusTas (&pmb->fl_lock)) == TRUE) break; - taskDelay(1); - } - if(lock_stat == FALSE) { - if(ab_debug != 0) - logMsg("link %x mr_wait-dpm locked on %x cmd\n", - link,command); - return (LOCK); - } - /* reset timeout */ - ab_tout[link] = OK; - - - /* clear the semaphore to make sure we stay in sync */ - if((semTake(ab_cmd_sem,NO_WAIT) == OK) && ab_debug) - logMsg("link %x, semaphore set before mr_wait cmd %x,%x,%x\n", - link,command,pmb->command,pmb->conf_stat); - - /* process commands */ - pmb->command = command; - pmb->data_len = length; - rtn_val = OK; /* assume success */ - switch (command) { - - /* commands with response */ - case AUTO_CONF: - case LINK_STATUS: - wdStart(wd_id[link],vxTicksPerSecond*10,ab_timeout,link); - p6008->sc_intr = 1; /* wakeup scanner tsk */ - semTake(ab_cmd_sem, WAIT_FOREVER); - /* was this a timeout? */ - if(ab_tout[link] == ERROR){ - if(ab_debug != 0) - logMsg("link %x mr_wait - timeout on %x cmd\n" - ,link,command); - rtn_val = ERROR; - break; - } - if ((pmb->conf_stat != 0) && (ab_debug != 0)){ - logMsg("link %x mr_wait cmd %x failed, status=%x\n" - ,link,pmb->command,pmb->conf_stat); - rtn_val = ERROR; - break; - } - if (pmb->command == command){ - wtrans(pmb_msg,pmsg); /* xfer data to local mailbox */ - }else{ - ab_bad_response[link]++; - if(ab_debug != 0) - logMsg("link %x mr_wait - bad resp on %x cmd\n" - ,link,command); - rtn_val = ERROR; - } - break; - - /* commands which send data */ - case SCAN_LIST: - case SET_MODE: - case SET_UP: - wtrans(pmsg,pmb_msg); /* xfer data to local mailbox */ - wdStart(wd_id[link],vxTicksPerSecond*5,ab_timeout,link); - p6008->sc_intr = 1; /* wakeup scanner */ - semTake(ab_cmd_sem, WAIT_FOREVER); - /* was this a timeout? */ - if(ab_tout[link] == ERROR){ - if(ab_debug != 0) - logMsg("link %x mr_wait - timeout on %x cmd\n" - ,link,command); - rtn_val = ERROR; - break; - } - if ((pmb->conf_stat != 0) && (ab_debug != 0)){ - logMsg("link %x mr_wait cmd %x failed status %x\n" - ,link,pmb->command,pmb->conf_stat); - rtn_val = ERROR; - } - break; - } - /* unlock the dual port memory */ - pmb->fl_lock = 0; - return (rtn_val); -} - -int ab_intr_cnt[AB_MAX_LINKS]; -/* - * AB_INTR - * - * interrupt service routine - * - * The Allen-Bradley protocol requires that an interrupt be received when - * a block transfer request is given to the scanner board through the dual - * ported memory and then another when the command is complete. As the command - * accept interrupt occurs while the Allen-Bradley scanner is locked out, - * there is no danger of getting a data interrupt back. The documentation is - * very misleading in this area: It gives no indication of how the interrupts - * are used to accomplish asynchronous communication and implies that the - * dual-ported memory lock is controlled in a much different fashion than it is. - */ -ab_intr(link) -short link; -{ - struct ab_response response; - register struct ab_response *presponse; - register unsigned short *presp_data; - register unsigned short *pdata; - register struct dp_mbox *pmb; - register unsigned short i; - - register short tmp_op_stat; - register struct ab_region *p6008 = p6008s[link]; - - pmb = &p6008s[link]->mail; - - /* Test the operating status word of link to see if adapter * - * status has changed since the last time the scanner interrupted us. */ - tmp_op_stat = (p6008->osw & OSW_MASK); - if (tmp_op_stat != ab_op_stat[link]){ -/* logMsg("old stat %x, new stat %x\n",ab_op_stat[link], tmp_op_stat); */ - ab_op_stat[link] = tmp_op_stat; - } - - ab_intr_cnt[link]++; - if (((pmb->command != AB_WRITE) && (pmb->command != AB_READ)) || - (ab_requesting_bt[link])){ - semGive(ab_cmd_sem); - wdCancel(wd_id[link]); - }else{ - presponse = &response; - - /* wait for the genius, who posted us, to lock the data area */ - ab_post_no_lock[link] = 0; - while(TRUE) { - unsigned char fl_lock; - - fl_lock = pmb->fl_lock; - if(fl_lock&0x80) break; - ab_post_no_lock[link] += 1; - if(ab_post_no_lock[link]>=1000) { - logMsg("link %x exceeded stop count\n",link); - return; - } - } - /* put the response on the queue for abDoneTask */ - presponse->link = link; - presponse->card = pmb->address & 0x0f; - presponse->adapter = (pmb->address & 0x70) >> 4; - presponse->command = pmb->command; - presponse->status = pmb->conf_stat; - presp_data = &presponse->data[0]; - pdata = &pmb->da.wd[0]; - for (i = 0; i < 64; i++,pdata++,presp_data++) - *presp_data = *pdata; - if (rngBufPut(ab_cmd_q,&response,sizeof(struct ab_response)) - != sizeof(struct ab_response)) - logMsg("ab_cmd_q - Full\n"); - - /* wake up abDoneTask */ - semGive(ab_data_sem); - pmb->fl_lock = 0; - } -} - -/* - * AB_TIMEOUT - * - * internal watchdog timer - */ -ab_timeout(link) -int link; -{ - /* mark a timeout error */ - ab_tout[link] = ERROR; - - /* only the command receive gives a damn */ - semGive(ab_cmd_sem); - - /* keep track in case someone wants to snoop */ - ab_comm_to[link]++; -} -static void wtrans (from, to) -register short *from, *to; -{ - register i; - for (i=0;i<64;i++) - *to++ = *from++; -} - -/* - * AB_AIDRIVER - * - * data request from the Analog Input driver - */ -ab_aidriver(card_type,link,adapter,card,signal,adapter_plc,pvalue,conversion) -unsigned short card_type; -register unsigned short link; -register unsigned short adapter; -register unsigned short card; -unsigned short signal; -unsigned short *pvalue; -unsigned short conversion; -unsigned short adapter_plc; -{ - /* pointer to the Allen-Bradley configuration table */ - register unsigned short *pcard = &ab_config[link][adapter][card]; - - /* verify that the card is initialized */ - if ((*pcard & AB_INIT_BIT) == 0){ - if ((*pcard & AB_SENT_INIT) == 0){ - /* configuration data - the scan task takes over from here */ - *pcard = AB_AI_INTERFACE | card_type - | ((conversion << 8) & AB_CONVERSION); - if (adapter_plc) *pcard |= AB_PLC; - } - /* sorry, but the initalization is not immediate */ - return(-1); - } - - /* verify that link is ok and card type is correct */ - if (ab_adapter_status[link][adapter] == ERROR) return(-1); - if ((*pcard & AB_INTERFACE_TYPE) != AB_AI_INTERFACE) return(-1); - if ((*pcard & AB_CARD_TYPE) != card_type) return(-1); - - /* get the value from the table */ - *pvalue = ab_btdata[link][adapter][card][signal]; - if (ab_btsts[link][adapter][card][signal] < -2) return(-1); - return(0); -} - -/* - * AB_AODRIVER - * - * data send from the Analog Output driver - */ -ab_aodriver(card_type,link,adapter,card,signal,adapter_plc,value) -unsigned short card_type; -register unsigned short link; -register unsigned short adapter; -register unsigned short card; -unsigned short signal; -unsigned short adapter_plc; -unsigned short value; -{ - register unsigned short *pcard = &ab_config[link][adapter][card]; - - /* verify that the card is initialized */ - if ((*pcard & AB_INIT_BIT) == 0){ - if ((*pcard & AB_SENT_INIT) == 0){ - /* configuration data - the scan task takes over from here */ - /* we assume the write will work and return 0 */ - *pcard = AB_AO_INTERFACE | card_type | AB_UPDATE; - if (adapter_plc) *pcard |= AB_PLC; - - /* put the value into the table */ - ab_btdata[link][adapter][card][signal] = value; - } - return(-1); - } - - /* put the value into the table */ - if ((unsigned short)ab_btdata[link][adapter][card][signal] == value) return(0); - ab_btdata[link][adapter][card][signal] = value; - *pcard |= AB_UPDATE; - - /* verify that link is ok and card type is correct */ - if (ab_adapter_status[link][adapter] == ERROR) return(-1); - if ((*pcard & AB_INTERFACE_TYPE) != AB_AO_INTERFACE) return(-1); - if ((*pcard & AB_CARD_TYPE) != card_type) return(-1); - - return(0); -} - -/* - * AB_AOREAD - * - * read the analog output value - * called from read_ao in ../../dblib/src/iocao.c - * used to initialize AOs - */ -ab_aoread(card_type,link,adapter,card,signal,adapter_plc,pvalue) -register unsigned short card_type; -unsigned short link; -register unsigned short adapter; -register unsigned short card; -unsigned short signal; -unsigned short adapter_plc; -unsigned short *pvalue; -{ - register unsigned short *pcard = &ab_config[link][adapter][card]; - - if ((*pcard & AB_INIT_BIT) == 0){ - /* add adapter to the scan list if neccessary */ - if ((*pcard & AB_SENT_INIT) == 0){ - if (*pcard == 0){ - /* configuration data-scan task takes over from here */ - *pcard = AB_AO_INTERFACE | card_type; - if (adapter_plc) *pcard |= AB_PLC; - } - } - return(-1); - } - *pvalue = ab_btdata[link][adapter][card][signal]; - return(0); -} - -/* - * AB_BIDRIVER - * - * data read from the Binary Input driver - */ -ab_bidriver(card_type,link,adapter,card,adapter_plc,mask,pvalue) -unsigned short card_type; -register unsigned short link; -register unsigned short adapter; -register unsigned short card; -unsigned short adapter_plc; -unsigned long *pvalue; -unsigned long mask; -{ - register struct ab_region *p6008 = p6008s[link]; - register unsigned short *pcard = &ab_config[link][adapter][card]; - register unsigned short inpinx; - register unsigned short *pshort; - /* verify there is a scanner */ - if (p6008 == 0) return(-1); - - /* claim the card as a binary input */ - if (((*pcard & AB_INIT_BIT) == 0) && ((*pcard & AB_SENT_INIT) == 0)){ - *pcard = AB_BI_INTERFACE | card_type | AB_INIT_BIT; - if (adapter_plc) *pcard |= AB_PLC; - } - - /* verify link communication is OK */ - /* This doesn't work in a box with no analog IO */ - if (ab_adapter_status[link][adapter] == ERROR) return(-1); - - /* eight bit byte ordering in dual ported memory */ - /* 1100 3322 5544 7766 9988 BBAA */ - if (card_type == ABBI_08_BIT){ - /* eight bit byte ordering in dual ported memory */ - /* byte 1100 3322 5544 7766 9988 BBAA */ - inpinx = (adapter * AB_CARD_ADAPTER) + card; - if (card & 0x1) inpinx--; /* shuffle those bytes */ - else inpinx++; - *pvalue = p6008->iit[inpinx] & mask; - }else{ - /* sixteen bit byte ordering in dual ported memory */ - /* byte 0011 2233 4455 6677 8899 AABB */ - /* card 0000 2222 4444 6666 8888 AAAA */ - inpinx = (adapter * AB_CARD_ADAPTER) + card; - if (card & 0x1) return(-1); - pshort = (unsigned short *)&(p6008->iit[inpinx]); - *pvalue = *pshort & mask; - } - return(0); -} - -/* - * AB_BODRIVER - * - * data send from the Binary Output driver - */ -ab_bodriver(card_type,link,adapter,card,adapter_plc,value,mask) -unsigned short card_type; -register unsigned short link; -unsigned short adapter; -register unsigned short card; -unsigned short adapter_plc; -unsigned long value; -unsigned long mask; -{ - register struct ab_region *p6008 = p6008s[link]; - register unsigned short *pcard = &ab_config[link][adapter][card]; - register unsigned short outinx; - register unsigned short *pshort; - - /* verify there is a scanner */ - if (p6008 == 0) return(-1); - - /* claim the card as a binary output */ - if (((*pcard & AB_INIT_BIT) == 0) && ((*pcard & AB_SENT_INIT) == 0)){ - *pcard = AB_BO_INTERFACE | card_type | AB_INIT_BIT; - if (adapter_plc) *pcard |= AB_PLC; - } - - /* eight bit byte ordering in dual ported memory */ - /* 1100 3322 5544 7766 9988 BBAA */ - if (card_type == ABBO_08_BIT){ - /* eight bit byte ordering in dual ported memory */ - /* byte 1100 3322 5544 7766 9988 BBAA */ - outinx = (adapter * AB_CARD_ADAPTER) + card; - if (card & 0x1) outinx--; /* shuffle those bytes */ - else outinx++; - p6008->oit[outinx] = (p6008->oit[outinx] & ~mask) | value; - }else{ - /* sixteen bit byte ordering in dual ported memory */ - /* byte 0011 2233 4455 6677 8899 AABB */ - /* card 1111 3333 5555 7777 9999 BBBB */ - outinx = (adapter * AB_CARD_ADAPTER) + card; - if (card & 0x1) outinx--; /* shuffle those bytes */ - else return(-1); - pshort = (unsigned short *)&(p6008->oit[outinx]); - *pshort = (*pshort & ~mask) | value; - } - /* verify link communication is OK */ - /* This doesn't work in a box with no analog IO */ - if (ab_adapter_status[link][adapter] == ERROR) return(-1); - return(0); -} -/* - * AB_BOREAD - * - * read the binary output channel - */ -ab_boread(card_type,link,adapter,card,pvalue,mask) -unsigned short card_type; -unsigned short link; -register unsigned short adapter; -register unsigned short card; -register unsigned long *pvalue; -unsigned long mask; -{ - register struct ab_region *p6008 = p6008s[link]; - register unsigned short outinx; - register unsigned short *pshort; - - /* verify there is a scanner */ - if (p6008 == 0) return(-1); - - /* verify link communication is OK */ - /* This doesn't work in a box with no analog IO */ - if (ab_adapter_status[link][adapter] == ERROR) return(-1); - - /* eight bit byte ordering in dual ported memory */ - /* 1100 3322 5544 7766 9988 BBAA */ - if (card_type == ABBO_08_BIT){ - /* eight bit byte ordering in dual ported memory */ - /* byte 1100 3322 5544 7766 9988 BBAA */ - outinx = (adapter * AB_CARD_ADAPTER) + card; - if (card & 0x1) outinx--; /* shuffle those bytes */ - else outinx++; - *pvalue = p6008->oit[outinx] & mask; - }else{ - /* sixteen bit byte ordering in dual ported memory */ - /* byte 0011 2233 4455 6677 8899 AABB */ - /* card 1111 3333 5555 7777 9999 BBBB */ - outinx = (adapter * AB_CARD_ADAPTER) + card; - if (card & 0x1) outinx--; /* shuffle those bytes */ - else return(-1); - pshort = (unsigned short *)(&p6008->oit[outinx]); - *pvalue = *pshort & mask; - } - return(0); -} - -/* - * LINK_STATUS - * - * Fetches the status of the adapters on the specified link - * The ab_adapter_status table is used to determine hardware communication - * errors and convey them to the database - */ -link_status(link) -unsigned short link; -{ - short buffer[200]; - register short *pbuffer = &buffer[0]; - register short i, mr_w_err; - - /* for no card present - mark all adapters as offline */ - if (p6008s[link] == 0){ - for (i = 0; i < AB_MAX_ADAPTERS; i++){ - ab_adapter_status[link][i] = -1; - } - return(0); - } - - /* get the link status */ - if((mr_w_err = mr_wait(LINK_STATUS,0,pbuffer,link)) != OK){ - if (ab_debug != 0) - logMsg(" link_status cmd error\n"); - ab_link_to[link]++; - return(-1); - }else{ - /* check each adapter on this link */ - for (i = 0; i< AB_MAX_ADAPTERS; i++){ - /* good status */ - if (*(pbuffer+(i*4)) & 0x70){ - if (ab_adapter_status[link][i] == -1) { - printf("link %d adapter %d change bad to good\n" - ,link,i); - ab_adapter_status_change[link][i]=1; - } - ab_adapter_status[link][i] = 0; - /* bad status */ - }else { - if (ab_adapter_status[link][i] == 0){ - printf("link %d adapter %d change good to bad\n" - ,link,i); - ab_adapter_status_change[link][i]=1; - } - ab_adapter_status[link][i] = -1; - } - } - } - return(0); -} - -/* - * SCAN_LIST - * - * sets the scan list for the Allen-Bradley scanner - */ -scan_list(link) -unsigned short link; -{ - register short i,sl_inx,fail,mr_w_err; - char buffer[80]; - register char *pbuffer = &buffer[0]; - - /* for no card present - mark all adapters as offline */ - if (p6008s[link] == 0) return(0); - - - /* A promised firmware change will allow us to RESET - the scanner over the vmeBus. For now, the only way - to get the scanner into prog-mode without having - the BO's glitch is with the vmeBus SYSRESET signal, - which occurs when the RESET switch on the VME chassis - is used. Until the f/w change is made, changing the - scanner from run mode to program mode (to modify the - scan list, for instance) will cause the BO's to turn - off until the scanner is returned to run mode. It's - not nice, but for now we'll have to assume that all - adapters are needed and put them all in the scan list. */ - - /* build the scan list */ - bfill(&ab_scan_list[link][0],AB_MAX_ADAPTERS,0); - for (sl_inx = 0, i = 0; i < AB_MAX_ADAPTERS; i++){ - ab_scan_list[link][sl_inx] = (i << 2); - sl_inx++; - } - - /* set new scan list - assume we're in program mode */ - if((mr_w_err = mr_wait(SCAN_LIST,sl_inx,&ab_scan_list[link][0],link)) != OK){ - if (ab_debug != 0) - logMsg(" scan_list SCAN_LIST cmd error\n"); - return(-1); - } - - - /* place the scanner into run mode */ - bfill(pbuffer,80,0); - *pbuffer = RUN_MODE; - if((mr_w_err = mr_wait(SET_MODE,0,pbuffer,link)) != OK){ - if (ab_debug != 0) - logMsg(" scan_list SET_MODE cmd error\n"); - return(-1); - } - return(0); -} - -#define MAX_8BIT 8 -ab_io_report(level) - short int level; - { - short i,j,k,l,m,card,adapter,plc_card,x,type; - unsigned short jrval,krval,lrval,mrval; - unsigned long val,jval,kval,lval,mval; - - /* report all of the Allen-Bradley Serial Links present */ - for (i = 0; i < AB_MAX_LINKS; i++){ - if(!p6008s[i]) continue; - printf("AB-6008SV:\tcard %d ",i); - for(adapter=0; adapter0) printf("%s\n",ab_firmware_info[i]); - /* report all cards to which the database has interfaced */ - /* as there is no way to poll the Allen-Bradley IO to */ - /* determine which card is there we assume that any interface */ - /* which is successful implies the card type is correct */ - /* since all binaries succeed and some analog inputs will */ - /* succeed for either type this is a shakey basis */ - for (adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - for (card = 0; card < AB_MAX_CARDS; card++){ - - /* Determine whether the card is in a plc or not. */ - - if(ab_config[i][adapter][card] & AB_PLC){ - plc_card = 1; - /* printf("This card is a plc card.\n"); */ - } else { - plc_card = 0; - /* printf("This card is not a plc card.\n"); */ - } - - switch (ab_config[i][adapter][card] & AB_INTERFACE_TYPE){ - - case (AB_BI_INTERFACE): - printf("\tBI: AB\tadapter %d card %d",adapter,card); - ab_bi_report(i,adapter,card,plc_card); - break; - case (AB_BO_INTERFACE): - printf("\tBO: AB\tadapter %d card %d",adapter,card); - ab_bo_report(i,adapter,card,plc_card); - break; - case (AB_AI_INTERFACE): - type = ab_config[i][adapter][card]&AB_CARD_TYPE; - if ((ab_config[i][adapter][card]&AB_CARD_TYPE)==AB1771IXE){ - printf("\tAI: AB1771IXE\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card], - ab_scaling_error[i][adapter][card], - ab_or_scaling_error[i][adapter][card]); - if (level > 0){ - ab_ai_report(type,i,adapter,card,plc_card); - } - } else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IL){ - printf("\tAI: AB1771IL\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card], - ab_scaling_error[i][adapter][card], - ab_or_scaling_error[i][adapter][card]); - if (level > 0){ - ab_ai_report(type,i,adapter,card,plc_card); - } - } else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IrPlatinum){ - printf("\tAI: AB1771IrPlatinum\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card], - ab_scaling_error[i][adapter][card], - ab_or_scaling_error[i][adapter][card]); - if (level > 0){ - ab_ai_report(type,i,adapter,card,plc_card); - } - } else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IrCopper){ - printf("\tAI: AB1771IrPlatinum\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card], - ab_scaling_error[i][adapter][card], - ab_or_scaling_error[i][adapter][card]); - if (level > 0){ - ab_ai_report(type,i,adapter,card,plc_card); - } - } else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IFE_SE){ - printf("\tAI: AB1771IFE_SE\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card], - ab_scaling_error[i][adapter][card], - ab_or_scaling_error[i][adapter][card]); - if (level > 0){ - ab_ai_report(type,i,adapter,card,plc_card); - } - } else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IFE_4to20MA){ - printf("\tAI: AB1771IFE_4to20MA\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card], - ab_scaling_error[i][adapter][card], - ab_or_scaling_error[i][adapter][card]); - if (level > 0){ - ab_ai_report(type,i,adapter,card,plc_card); - } - } else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IFE){ - printf("\tAI: AB1771IFE\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card], - ab_scaling_error[i][adapter][card], - ab_or_scaling_error[i][adapter][card]); - if (level > 0){ - ab_ai_report(type,i,adapter,card,plc_card); - } - } else if ((ab_config[i][adapter][card] & AB_CARD_TYPE) == AB1771IFE_0to5V){ - printf("\tAI: AB1771IFE_0to5V\tadapter %d card %d:\tcto: %d dto: %d sclerr: %d %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card], - ab_scaling_error[i][adapter][card], - ab_or_scaling_error[i][adapter][card]); - if (level > 0){ - ab_ai_report(type,i,adapter,card,plc_card); - } - } - break; - case (AB_AO_INTERFACE): - printf("\tAO: AB1771OFE\tadapter %d card %d:\tcto: %d dto: %d", - adapter,card,ab_cmd_to[i][adapter][card], - ab_data_to[i][adapter][card]); - if (level > 0 ){ - ab_ao_report(AB1771OFE,i,adapter,card,plc_card,&jrval,0); - } - break; - default: - continue; - } - if ((ab_config[i][adapter][card] & AB_INIT_BIT) == 0) - printf(" NOT INITIALIZED\n"); - else { - printf("\n"); - } - } - } - } - - } - -ab_bi_report(link,adapter,card,plc_card) - short link,adapter,card,plc_card; - { - unsigned short type; - unsigned long value; - - type = ab_config[link][adapter][card] & AB_CARD_TYPE; - ab_bidriver(type,link,adapter,card,plc_card,0xffffffff,&value); - printf(" value=%08.8x",value); - } - -ab_bo_report(link,adapter,card) - short link,adapter,card; - { - unsigned short type; - unsigned long value; - - - type = ab_config[link][adapter][card] & AB_CARD_TYPE; - ab_boread(type,link,adapter,card,&value,0xffffffff); - } - -ab_ai_report(type,link,adapter,card,plc_card) - - unsigned short type; - short link,adapter,card,plc_card; - { - short i,num_chans; - unsigned short value; - - num_chans = ai_num_channels[type]; - for(i=0; iosw = 0; /* scanner depends on us to clear some bits */ - } - - - /* check each adapter */ - for (adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - if (ab_adapter_status[link][adapter] >= 0) - read_ab_adapter(link,adapter,pass); - } - - /* Every second perform a link check to see if any adapters */ - /* have changed state. (Don't want to queue up requests if*/ - /* they're off) */ - if((pass % 10) == 0){ - if (link_status(link) != 0){ - if(ab_debug) - logMsg("%x link_stat error %x\n",link); - } - } - - } - - /* run every 1/10 second */ - taskDelay(vxTicksPerSecond/10); - } -} - -/* ab_reboot_hook - routine to call when IOC is rebooted with a control-x */ - -int ab_reboot_hook(boot_type) -int boot_type; -{ - short i; - static char wait_msg[] = {"I Hate to WAIT"}; - register char *pmsg = &wait_msg[0]; - - /* Stop communication to the Allen-Bradley Scanner Cards */ - if (abScanId != 0){ - /* flag the analog output and binary IO routines to stop */ - ab_disable = 1; - - /* delete the scan task stops analog input communication */ - taskDelete(abScanId); - - /* this seems to be necessary for the AB card to stop talking */ - printf("\nReboot: delay "); - for(i = 0; i <= 14; i++){ - printf("%c",*(pmsg+i)); - taskDelay(20); - } - } -} - -/* - * - * ab_reset_task() - * - * - * - */ -void -ab_reset_task() -{ - short link,adapter,card; - struct ab_region *pab_region=0; - - /* keep track of the status and frequency */ - if (reset_cnt < 100){ - reset_code[reset_cnt] = pab_region->mail.conf_stat; - reset_cnt++; - } - - /* disable scanning during reset */ - ab_disable = 1; - printf("Disabled AB Scanner Task\n"); - taskDelay(vxTicksPerSecond*2); - /* Signal the Scanner to Reset */ - for(link=0; linksys_fail_set2 = 0xa0a0; - pab_region->sys_fail_set1 = 0x0080; - printf("Card %d Reset\n",0); - } - - ab_reset_wait = 0; - for(link=0; linkmail.conf_stat != SCANNER_POWERUP){ - taskDelay(1); - ab_reset_wait++; - } - } - printf("Link Power Up After %d Ticks\n",ab_reset_wait); - /* Reinitialize the Link */ - for(link=0; link -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char SccsId[] = "@(#)drvAt5Vxi.c 1.19\t8/27/93"; - -typedef long at5VxiStatus; - -LOCAL void at5vxi_int_service( - int addr -); - -LOCAL void at5vxi_init_card( - unsigned addr -); - -LOCAL int at5vxi_shutdown(void); - -LOCAL void at5vxi_shutdown_card( - unsigned la -); - -LOCAL at5VxiStatus at5vxi_report_timing( - unsigned card, - unsigned channel -); - -LOCAL void at5vxi_stat( - unsigned card, - int level -); - -/* - * these should be in a header file - */ -LOCAL at5VxiStatus at5vxi_init( - void -); - -at5VxiStatus at5vxi_one_shot( - int preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int int_source, /* (FALSE)External/(TRUE)Internal source */ - void *event_rtn, /* subroutine to run on events */ - int event_rtn_param /* parameter to pass to above routine */ -); - -at5VxiStatus at5vxi_one_shot_read( - int *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -); - -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -); - -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -); - -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -); - -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -); - -at5VxiStatus at5vxi_getioscanpvt( - unsigned card, - IOSCANPVT *scanpvt -); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvAt5Vxi={ - 2, - NULL, /* VXI io report takes care of this */ - at5vxi_init}; - -#define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */ - -/* - * Set this flag if you wish for the driver to - * to disable the busy period and operate - * without periodic interrupts - * -#define CONTINUOUS_OPERATION - * - */ - -/* - * all AT5VXI cards will use this VME interrupt level - */ -#ifdef CONTINUOUS_OPERATION -# define AT5VXI_INT_LEVEL 0 -# define AT5VXI_INT_ENABLE FALSE -# define AT5VXI_BUSY_ENABLE FALSE -#else -# define AT5VXI_INT_LEVEL 5 -# define AT5VXI_INT_ENABLE TRUE -# define AT5VXI_BUSY_ENABLE TRUE -#endif - -#define abort(A) taskSuspend(0) - -/* - * bit fields allocated starting with the ms bit - */ -struct at5vxi_status{ - unsigned pad0:1; - unsigned modid_cmpl:1; - unsigned dev255:1; - unsigned busy:1; - unsigned pad1:2; - unsigned timer_bank:1; - unsigned ipend:1; - unsigned ienable:1; - unsigned ilevel:3; - unsigned ready:1; - unsigned passed:1; - unsigned sfinh:1; - unsigned sreset:1; -}; - - -#define PSTATUS(PCSR)\ -(&((struct vxi_csr *)PCSR)->dir.r.status) - -struct at5vxi_control{ - unsigned pad0:3; - unsigned busy_enable:1; - unsigned pad1:2; - unsigned timer_bank:1; - unsigned softint:1; - unsigned ienable:1; - unsigned ilevel:3; - unsigned pad2:2; - unsigned sfinh:1; - unsigned sreset:1; -}; - -/* - * Insert or extract a bit field using the standard - * masks and shifts defined below - */ -#ifdef __STDC__ -# define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S)) -# define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M)) -#else -# define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S)) -# define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M)) -#endif - -/* - * in the constants below _M is a right justified mask - * and _S is a shift required to right justify the field - */ -#define FD_INT_ENABLE_M (0x1) -#define FD_INT_ENABLE_S (7) -#define FD_BUSY_ENABLE_M (0x1) -#define FD_BUSY_ENABLE_S (12) -#define FD_BUSY_STATUS_M (0x1) -#define FD_BUSY_STATUS_S (12) -#define FD_INT_LEVEL_M (0x7) -#define FD_INT_LEVEL_S (4) -#define FD_TIMER_BANK_M (0x1) -#define FD_TIMER_BANK_S (9) - -#define BUSY(PCSR)\ -(((struct vxi_csr *)PCSR)->dir.r.status & INSERT(BUSY_STATUS,1)) - -/* - * Some constants for the CSR. - * - */ -#ifndef CONTINUOUS_OPERATION -# define INTDISABLE\ - ( \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_ENABLE, FALSE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) -#endif - -/* - * Used to initialize the control register. - * (enables interrupts) - */ -#define CSRINIT\ - ( \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_ENABLE, AT5VXI_INT_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) - -/* - * Use bank zero of the timing. - */ -#define BANK0\ - ( \ - INSERT(TIMER_BANK, 0) | \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) -/* - * Use bank one of the timing. - */ -#define BANK1\ - ( \ - INSERT(TIMER_BANK, 1) | \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) - -/* - * Some constants for the CSR. - * set at initialization for better readability - */ -#define PCONTROL(PCSR)\ -(&((struct vxi_csr *)PCSR)->dir.w.control) - - - - -#define AT5VXI_TIMER_BANKS_PER_MODULE 2 -#define AT5VXI_CHANNELS_PER_TIMER_BANK 5 -#define AT5VXI_NTIMER_CHANNELS\ - (AT5VXI_TIMER_BANKS_PER_MODULE*AT5VXI_CHANNELS_PER_TIMER_BANK) - - -struct at5vxi_dd{ - vxi16_t bio[2]; - vxi16_t tdata; - vxi8_t pad; - vxi8_t tcmd; - vxi16_t ai[8]; - vxi16_t ao[16]; -}; - - -struct at5vxi_setup{ -# define UNITY 0 -# define TIMES2 1 - unsigned gainA:1; - unsigned gainB:1; - unsigned gainC:1; - unsigned gainD:1; -# define UNIPOLAR 0 -# define BIPOLAR 1 - unsigned modeA:1; - unsigned modeB:1; - unsigned modeC:1; - unsigned modeD:1; - unsigned ch2enbl:1; - unsigned ch2select:3; - unsigned ch1enbl:1; - unsigned ch1select:3; -}; - - -#define AT5VXI_BUSY_PERIOD 2 - -struct bo_val { - volatile int32_t val; - volatile int32_t mask; -}; - -struct ao_val { - volatile int16_t mdt; - volatile int16_t val; -}; - -struct time_val { - volatile unsigned preset; - volatile int16_t iedge0_delay; - volatile int16_t iedge1_delay; - volatile char mdt; - volatile char valid; -}; - -struct at5vxi_config{ - FAST_LOCK lock; /* mutual exclusion */ - struct bo_val bv; /* binary out values */ - struct ao_val av[16]; /* analog out values */ - struct time_val tv[10]; /* delayed pulse values */ - volatile char mdt; /* modified data tag */ - struct vxi_csr *pcsr; /* vxi device hdr ptr */ - struct at5vxi_dd *pdd; /* at5 device dep ptr */ - IOSCANPVT ioscanpvt; -}; - -LOCAL unsigned long at5vxiDriverID; - -#define AT5VXI_PCONFIG(CARD, PTR) \ -epvxiFetchPConfig(CARD, at5vxiDriverID, PTR) - -#define AT5VXI_CORRECT_MAKE(PCSR) (VXIMAKE(PCSR)==VXI_MAKE_AT5) - -struct at5vxi_model{ - char *name; /* AT5 VXI module name */ - char *drawing; /* AT5 VXI assembly drawing number */ -}; - -#define AT5VXI_INDEX_FROM_MODEL(MODEL) ((unsigned)((MODEL)&0xff)) -#define AT5VXI_MODEL_FROM_INDEX(INDEX) ((unsigned)((INDEX)|0xf00)) - -/* - * NOTE: The macro AT5VXI_INDEX_FROM_MODEL(MODEL) defined above - * should return an index into the correct data given the - * VXI device's model code. - */ -struct at5vxi_model at5vxi_models[] = { - {"INTERFACE SIMULATOR", "112Y-280158"}, - {"I CONTROLLER", "112Y-280176"}, - {"CONTROL PREDISTORTER", "112Y-280172"}, - {"VECTOR DETECTOR", "112Y-280230"}, - {"VECTOR MODULATOR", "112Y-280177"}, - {"425MHz ENVELOPE DETECTOR", "112Y-280169"}, - {"425MHz DOWNCONVERTER", "112Y-280165"}, - {"POLAR DETECTOR", "112Y-280567"}, - {"UPCONVERTER", "112Y-280225"}, - {"MONITOR TRANSMITTER", "112Y-280187"}, - {"TIMING DISTRIBUTION", "112Y-280582"}, - {"LINE CONDITIONER", "112Y-280305"}, - {"BEAM FEEDFORWARD", "112Y-280564"}, - {"TIMING RECEIVER", "112Y-280243"}, - {"FAST PROTECTION", "112Y-280246"}, - {"ADAPTIVE FEEDFORWARD", "112Y-280563"}, - {"CABLE CONTROLLER", "112Y-280307"}, - {"Q CONTROLLER", "112Y-280180"}, - {"ENVELOPE DETECTOR", "112Y-280249"}, - {"DOWNCONVERTER", "112Y-280456"}, - {"COAX MONITOR TRANSMITTER", "112Y-280587"}, - {"CAVITY SIMULATOR", "112Y-280232"}, - {"CABLE CONTROLLER (2 CHANNEL)","112Y-280539"}, - {"BREADBOARD", "112Y-280358"}, - {"I/O INTERFACE", "112Y-280359"}, - {"DIAGNOSTIC - BPM", "112Y-280422-1"}, - {"FAST ENVELOPE DETECTOR", "112Y-280421"}, - {"DIAGNOSTIC - CM", "112Y-280422-2"}, - {"DIAGNOSTIC - MISC", "112Y-280422-3"}, - {"FAST VECTOR DETECTOR", "112Y-280651"}, - {"SINGLE-WIDE VECTOR DETECTOR", "112Y-280672"}, - {"FM / AM", "112Y-280xxx"} -}; - -#define AT5VXI_VALID_MODEL(MODEL) \ -(AT5VXI_INDEX_FROM_MODEL(MODEL)dir.w.control = INTDISABLE; -#endif -} - - - -/* - * AT5VXI_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL -void at5vxi_init_card( - unsigned addr -) -{ - at5VxiStatus r0; - struct at5vxi_config *pc; - struct time_val *ptv; - unsigned chan; - int i; - int model; - - r0 = epvxiOpen( - addr, - at5vxiDriverID, - (unsigned long) sizeof(*pc), - at5vxi_stat); - if(r0){ - errPrintf( - r0, - __FILE__, - __LINE__, - "AT5VXI: device open failed %d\n", addr); - return; - } - - r0 = AT5VXI_PCONFIG(addr, pc); - if(r0){ - errMessage(r0, NULL); - epvxiClose(addr, at5vxiDriverID); - return; - } - - pc->pcsr = VXIBASE(addr); - pc->pdd = (struct at5vxi_dd *) &pc->pcsr->dir.r.dd; - - FASTLOCKINIT(&pc->lock); - - scanIoInit(&pc->ioscanpvt); - - - /* - * revert to power up control - * (temporarily disable the busy period) - */ - pc->pcsr->dir.w.control = 0; - - -#ifndef CONTINUOUS_OPERATION - /* - * wait 5 sec for the end of current busy cycle as required - * (busy period is temporarily disabled - * - */ - for(i=0; i<5 && BUSY(pc->pcsr); i++) - taskDelay(sysClkRateGet()); - if(BUSY(pc->pcsr)){ - epvxiClose(addr, at5vxiDriverID); - return; - } -#endif - -#if defined(INIT_BINARY_OUTS) - /* - * Set AD 664 default - */ - { - struct at5vxi_setup su; - - su.gainA = TIMES2; - su.gainB = TIMES2; - su.gainC = TIMES2; - su.gainD = TIMES2; - - su.modeA = BIPOLAR; - su.modeB = BIPOLAR; - su.modeC = BIPOLAR; - su.modeD = BIPOLAR; - - su.ch2enbl = FALSE; - su.ch1enbl = FALSE; - - (* (struct at5vxi_setup *) &pc->pdd->bio[1]) = su; - } -#endif - - /* - * Init AMD 9513 for - * - * binary division - * data ptr seq enbl - * 16 bit bus - * FOUT on - * FOUT divide by 16 - * FOUT source (F1) - * Time of day disabled - */ -# define MASTER_MODE ((uint16_t)0x2000) - *PCONTROL(pc->pcsr) = BANK0; - r0 = stc_init( &pc->pdd->tcmd, - &pc->pdd->tdata, - MASTER_MODE); - if(r0!=STC_SUCCESS){ - epvxiClose(addr, at5vxiDriverID); - return; - } - - *PCONTROL(pc->pcsr) = BANK1; - r0 = stc_init( - &pc->pdd->tcmd, - &pc->pdd->tdata, - MASTER_MODE); - if(r0!=STC_SUCCESS){ - epvxiClose(addr, at5vxiDriverID); - return; - } - - for(chan=0, ptv = pc->tv; chantv); chan++, ptv++){ - unsigned int_source; - - if(chan/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pc->pcsr) = BANK1; - } - else{ - *PCONTROL(pc->pcsr) = BANK0; - } - - /* - * casting below discards volatile - * (ok in this case) - */ - r0 = stc_one_shot_read( - (unsigned *)&ptv->preset, - (uint16_t *)&ptv->iedge0_delay, - (uint16_t *)&ptv->iedge1_delay, - &pc->pdd->tcmd, - &pc->pdd->tdata, - chan, - &int_source); - if(r0 == STC_SUCCESS && int_source == FALSE) - ptv->valid = TRUE; - else - ptv->valid = FALSE; - } - -# ifndef CONTINUOUS_OPERATION - r0 = intConnect( - INUM_TO_IVEC(addr), - at5vxi_int_service, - addr); - if(r0 == ERROR) - return; - - sysIntEnable(AT5VXI_INT_LEVEL); -# endif - - /* - * init the csr - * (see at5vxi_init() for field definitions) - * interrupts enabled if not compiled for continuous operation - */ - *PCONTROL(pc->pcsr) = CSRINIT; - - model = VXIMODEL(pc->pcsr); - if(AT5VXI_VALID_MODEL(model)){ - r0 = epvxiRegisterModelName( - VXIMAKE(pc->pcsr), - model, - at5vxi_models[AT5VXI_INDEX_FROM_MODEL(model)].name); - if(r0){ - errMessage(r0,NULL); - } - - r0 = epvxiRegisterMakeName(VXI_MAKE_AT5, "LANL AT5"); - if(r0){ - errMessage(r0,NULL); - } - } - - return; -} - - -/* - * - * AT5VXI_INT_SERVICE - * - * update card busy writes and notify the IO interrupt scanner - */ -void at5vxi_int_service( - int addr -) -{ - struct at5vxi_config *pconfig; - at5VxiStatus r0; - - r0 = AT5VXI_PCONFIG(addr, pconfig); - if(r0){ - logMsg( "AT5VXI: int before init\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - return; - } - - /* - * wake up the I/O event scanner - */ - scanIoRequest(pconfig->ioscanpvt); - - /* - * Update outputs while it is safe to do so - */ - if(pconfig->mdt){ - struct at5vxi_dd *pdd; - struct vxi_csr *pcsr; - unsigned chan; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - for(chan=0; chantv); chan++){ - unsigned chip_chan; - - if(!pconfig->tv[chan].mdt) - continue; - - - if(chan/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - } - else{ - *PCONTROL(pcsr) = BANK0; - } - - chip_chan = chan% - AT5VXI_CHANNELS_PER_TIMER_BANK; - - r0 = stc_one_shot( - pconfig->tv[chan].preset, - pconfig->tv[chan].iedge0_delay, - pconfig->tv[chan].iedge1_delay, - &pdd->tcmd, - &pdd->tdata, - chip_chan, - FALSE); - if(r0 != STC_SUCCESS){ - logMsg( "AT5 VXI- AMD9513 load fail\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - } - else{ - pconfig->tv[chan].valid = TRUE; - } - - /* - * reenable interrupts - */ - *PCONTROL(pcsr) = CSRINIT; - - pconfig->tv[chan].mdt = FALSE; - } - - for(chan=0; chanav); chan++){ - if(!pconfig->av[chan].mdt) - continue; - pdd->ao[chan] = pconfig->av[chan].val; - pconfig->av[chan].mdt = FALSE; - } - - if(pconfig->bv.mask){ - uint32_t work; - - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | - pdd->bio[0]); - - /* alter specified bits */ - work = (work & ~pconfig->bv.mask) | - (pconfig->bv.val & pconfig->bv.mask); - - pdd->bio[0] = work; - pdd->bio[1] = work>>(NBBY*sizeof(uint16_t)); - - pconfig->bv.mask = 0; - } - - if(BUSY(pcsr)) - logMsg( "AT5 VXI INT- finished with card busy\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - - pconfig->mdt = FALSE; - } - -} - - - -/* - * - * AT5VXI_ONE_SHOT - * - * setup AMD 9513 STC for a repeated two edge timing signal - */ -at5VxiStatus at5vxi_one_shot( - int preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int int_source, /* (FALSE)External/(TRUE)Internal source */ - void *event_rtn, /* subroutine to run on events */ - int event_rtn_param /* parameter to pass to above routine */ -) -{ - at5VxiStatus status; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - status = AT5VXI_PCONFIG(card, pconfig); - if(status){ - return status; - } - - pcsr = pconfig->pcsr; - -/* AT5VXI does not support internal source for now -*/ if(int_source){ - status = S_dev_badRequest; - errMessage( - status, - "AT5VXI does not support internal trigger source"); - return status; - } - -/* AT5VXI does not support interrupts on timing channels for now -*/ if(event_rtn){ - status = S_dev_badRequest; - errMessage(status, "AT5VXI does not support interrupts on timing channels"); - return status; - } - - if(channel>=AT5VXI_NTIMER_CHANNELS) - return S_dev_badSignalNumber; - -/* dont overflow unsigned short in STC -*/ if(edge0_delay >= devCreateMask(NBBY*sizeof(uint16_t))/EXT_TICKS) - return S_dev_highValue; - if(edge1_delay >= devCreateMask(NBBY*sizeof(uint16_t))/EXT_TICKS) - return S_dev_highValue; - if(edge0_delay < 0.0) - return S_dev_lowValue; - if(edge1_delay < 0.0) - return S_dev_lowValue; - - FASTLOCK(&pconfig->lock); - -# ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - if(channel/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - }else{ - *PCONTROL(pcsr) = BANK0; - } - channel = channel%AT5VXI_CHANNELS_PER_TIMER_BANK; - - status = stc_one_shot( - preset, - (uint16_t) (edge0_delay * EXT_TICKS), - (uint16_t) (edge1_delay * EXT_TICKS), - &pdd->tcmd, - &pdd->tdata, - channel, - FALSE); - - /* - * not required for now but safe - * against future mods - */ - *PCONTROL(pcsr) = CSRINIT; - } -# else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->tv[channel].preset = preset; - pconfig->tv[channel].iedge0_delay = - (edge0_delay * EXT_TICKS); - pconfig->tv[channel].iedge1_delay = - (edge1_delay * EXT_TICKS); - pconfig->tv[channel].mdt = TRUE; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; - - status = STC_SUCCESS; -# endif - - FASTUNLOCK(&pconfig->lock); - - if(status!=STC_SUCCESS){ - return status; - } - - return VXI_SUCCESS; -} - - -/* - * - * AT5VXI_ONE_SHOT_READ - * - * read back two edge timing from an AMD 9513 STC - */ -at5VxiStatus at5vxi_one_shot_read( - int *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int *int_source /* (FALSE)External/(TRUE)Internal src */ -) -{ -#ifdef CONTINUOUS_OPERATION - uint16_t iedge0; - uint16_t iedge1; -#endif - at5VxiStatus status; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - status = AT5VXI_PCONFIG(card, pconfig); - if(status) - return status; - - pcsr = pconfig->pcsr; - - if(channel>=AT5VXI_NTIMER_CHANNELS) - return S_dev_badSignalNumber; - - -# ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - FASTLOCK(&pconfig->lock); - - if(channel/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - }else{ - *PCONTROL(pcsr) = BANK0; - } - channel = channel%AT5VXI_CHANNELS_PER_TIMER_BANK; - status = stc_one_shot_read( - preset, - &iedge0, - &iedge1, - &pdd->tcmd, - &pdd->tdata, - channel, - int_source); - /* - * not required for noe but safe - * against future mods - */ - *PCONTROL(pcsr) = CSRINIT; - FASTUNLOCK(&pconfig->lock); - - if(status==STC_SUCCESS){ - /* - * AT5VXI does not support external - * source for now - */ - if(int_source) - return S_dev_badRequest; - - *edge0_delay = iedge0 / EXT_TICKS; - *edge1_delay = iedge1 / EXT_TICKS; - } - - - return status; - } -# else - if(!pconfig->tv[channel].valid) - return S_dev_badRequest; - - FASTLOCK(&pconfig->lock); - - *preset = pconfig->tv[channel].preset; - *edge0_delay = pconfig->tv[channel].iedge0_delay - /EXT_TICKS; - *edge1_delay = pconfig->tv[channel].iedge1_delay - /EXT_TICKS; - *int_source = FALSE; - - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -# endif -} - - - -/* - * - * AT5VXI_STAT - * - * print status for a single at5 vxi card - * - * - */ -void at5vxi_stat( - unsigned card, - int level -) -{ - struct vxi_csr *pcsr; - register struct at5vxi_dd *pdd; - struct at5vxi_status status; - unsigned channel; - at5VxiStatus r0; - struct at5vxi_config *pconfig; - - static char *busy_status[] = {"","busy"}; - static char *modid_status[] = {"modid-on",""}; - static char *ipend_status[] = {"","int-pending"}; - static char *ienable_status[] = {"int-disabled","int-enabled"}; - static char *ext_st_status[] = {"extended-self-testing",""}; - static char *st_status[] = {"self-testing",""}; - static char *sfinh_status[] = {"","sys-fail-inhibit"}; - static char *sreset_status[] = {"","sys-reset"}; - static char *addr_mode_status[] = {"SC","DC"}; - - if(level==0) - return; - - r0 = AT5VXI_PCONFIG(card, pconfig); - if(r0){ - errMessage(r0,NULL); - return; - } - - pcsr = VXIBASE(card); - pdd = pconfig->pdd; - - r0 = vxMemProbe( (char *)&pcsr->dir.r.status, - READ, - sizeof(status), - (char *)&status); - if(r0 != OK) - return; - - if(VXIMAKE(pcsr) != VXI_MAKE_AT5) - return; - - if(AT5VXI_VALID_MODEL(VXIMODEL(pcsr))){ - printf( "\tDrawing: %s\n", - at5vxi_models[AT5VXI_INDEX_FROM_MODEL(VXIMODEL(pcsr))].drawing); - } - - printf( - "\tcard=%d address-mode=%s %s %s %s %s ilevel=%d %s %s %s %s\n", - card, - addr_mode_status[status.dev255], - busy_status[ status.busy ], - modid_status[ status.modid_cmpl ], - ipend_status[ status.ipend ], - ienable_status[ status.ienable ], - status.ilevel, - ext_st_status[ status.ready ], - st_status[ status.passed ], - sfinh_status[ status.sfinh ], - sreset_status[ status.sreset ]); - - if(pconfig){ - if(pconfig->mdt){ - printf("\toutput update is pending for interrupt\n"); - } - } - - if(level <= 1) - return; - - for(channel=0; channelai); channel++){ - printf( - "\tAI: channel %d value %x\n", - channel, - pdd->ai[channel]); - } - - for(channel=0; channelao); channel++){ - printf( - "\tAO: channel %d value %x\n", - channel, - pdd->ao[channel]); - } - - { - uint32_t work; - - work = ((uint32_t)pdd->bio[1]) << (sizeof(uint16_t)*NBBY); - work |= pdd->bio[0]; - printf("\tBIO: value %x\n", work); - } - - for(channel=0; channeltv); channel++){ - at5vxi_report_timing(card, channel); - } - - return; -} - - -/* - * - * - * AT5VXI_REPORT_TIMING - * - * diagnostic - */ -LOCAL -at5VxiStatus at5vxi_report_timing( - unsigned card, - unsigned channel -) -{ - int preset; - double edge0_delay; - double edge1_delay; - int int_source; - at5VxiStatus status; - char *clk_src[] = {"external-clk", "internal-clk"}; - - status = - at5vxi_one_shot_read( - &preset, - &edge0_delay, - &edge1_delay, - card, - channel, - &int_source); - if(status == VXI_SUCCESS) - printf( - "\tTI: channel %d preset %d delay %f width %f %s\n", - channel, - preset, - edge0_delay, - edge1_delay, - clk_src[int_source?1:0]); - - return status; -} - - -/* - * - * - * AT5VXI_AI_DRIVER - * - * analog input driver - */ -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -) -{ - at5VxiStatus s; - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ai)) - return S_dev_badSignalNumber; - - *prval = pdd->ai[chan]; - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_AO_DRIVER - * - * analog output driver - */ -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -) -{ - struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ao)) - return S_dev_badSignalNumber; - -#ifdef CONTINUOUS_OPERATION - pdd->ao[chan] = *prval; - *prbval = pdd->ao[chan]; -#else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->av[chan].val = *prval; - pconfig->av[chan].mdt = TRUE; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; - - *prbval = *prval; -#endif - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_AO_READ - * - * analog output read back - */ -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -) -{ - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s){ - return s; - } - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ao)) - return S_dev_badSignalNumber; - - *pval = pdd->ao[chan]; - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_BI_DRIVER - * - * binary input driver - */ -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -) -{ - register uint32_t work; - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - FASTLOCK(&pconfig->lock); - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | pdd->bio[0]); - *prval = mask & work; - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_BO_DRIVER - * - * binary output driver - */ -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -) -{ -#ifdef CONTINUOUS_OPERATION - register uint32_t work; -#endif - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - - FASTLOCK(&pconfig->lock); - -#ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | pdd->bio[0]); - - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - pdd->bio[0] = work; - pdd->bio[1] = work>>(NBBY*sizeof(uint16_t)); - } -#else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->bv.val = (pconfig->bv.val & ~mask) | (val & mask); - pconfig->bv.mask |= mask; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; -#endif - - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -} - - -/* - * - * at5vxi_getioscanpvt() - * - * - */ -at5VxiStatus at5vxi_getioscanpvt( -unsigned card, -IOSCANPVT *scanpvt -) -{ - struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s == VXI_SUCCESS){ - *scanpvt = pconfig->ioscanpvt; - } - return s; -} - diff --git a/src/drv/drvAt5Vxi.h b/src/drv/drvAt5Vxi.h deleted file mode 100644 index 97e4a23b3..000000000 --- a/src/drv/drvAt5Vxi.h +++ /dev/null @@ -1,93 +0,0 @@ -/* base/src/drv $Id$ */ - -/* - * - * driver for at5 designed VXI modules - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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: - * ----------------- - */ - -typedef long at5VxiStatus; - -at5VxiStatus at5vxi_one_shot( - int preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int int_source, /* (FALSE)External/(TRUE)Internal source - */ - void *event_rtn, /* subroutine to run on events */ - int event_rtn_param /* parameter to pass to above routine */ -); - -at5VxiStatus at5vxi_one_shot_read( - int *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -); - -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -); - -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -); - -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -); - -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -); - -at5VxiStatus at5vxi_getioscanpvt( - unsigned card, - IOSCANPVT *scanpvt -); - diff --git a/src/drv/drvBB232.c b/src/drv/drvBB232.c deleted file mode 100644 index ef119a955..000000000 --- a/src/drv/drvBB232.c +++ /dev/null @@ -1,598 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 05-21-92 - * EPICS BITBUS -> R/S-232 driver - * - * 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 09-30-91 jrw created - * - */ - -#define DRVBB232_C - -#include -#include -#if 0 /* COMMENTED OUT SOME INCLUDES */ -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* COMMENTED OUT SOME INCLUDES */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int drvBB232Debug = 0; -int softBB232 = 0; - -extern struct drvBitBusEt drvBitBus; - -/****************************************************************************** - * - ******************************************************************************/ -#define BB232LINK_PRI 50 -#define BB232LINK_OPT VX_FP_TASK|VX_STDIO -#define BB232LINK_STACK 5000 - - -/****************************************************************************** - * - ******************************************************************************/ -static long -report() -{ - printf("Report for BITBUS -> RS-232 driver\n"); - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -static long -init(pparms) -msgDrvIniParm *pparms; -{ - if (drvBB232Debug) - printf("Init for BITBUS -> RS-232 driver\n"); - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgXact structure. - * - * It is also responsible for filling in the msgXact.phwpvt pointer. - * - ******************************************************************************/ -static long -genXact(p) -msgDrvGenXParm *p; -{ - long stat = -1; - char message[100]; - drvBB232Link *pdrvBB232Link; - struct dpvtBitBusHead *pdpvtBitBusHead; - - if (p->plink->type != BITBUS_IO) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid device type in devSup.ascii (%d)\n", p->pmsgXact->prec->name, p->plink->type); - errMessage(S_db_badField, message); - return(ERROR); - } - - if (drvBB232Debug) - printf("BB232 genXact entered for link %d, bug %d, port %d, parm %s\n", p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, p->plink->value.bitbusio.port, p->plink->value.bitbusio.parm); - - p->pmsgXact->phwpvt = p->pmsgXact->pparmBlock->pmsgHwpvt; - - /* try to find the hwpvt structure for the required link, bug, and port */ - while ((p->pmsgXact->phwpvt != NULL) && (stat == -1)) - { - pdrvBB232Link = (drvBB232Link *)(p->pmsgXact->phwpvt->pmsgLink->p); - - if ((pdrvBB232Link->link == p->plink->value.bitbusio.link) - && (pdrvBB232Link->node == p->plink->value.bitbusio.node) - && (pdrvBB232Link->port == p->plink->value.bitbusio.port)) - { - if (pdrvBB232Link->pparmBlock != p->pmsgXact->pparmBlock) - { - sprintf(message, "%s: Two different devices on same BB232 port\n", p->pmsgXact->prec->name); - errMessage(S_db_badField, message); - return(ERROR); - } - else - stat = 0; /* Found the correct hwpvt structure */ - } - else - p->pmsgXact->phwpvt = p->pmsgXact->phwpvt->next; - } - if (stat != 0) - { /* Could not find a msgHwpvt for the right link, create a new one */ - if ((p->pmsgXact->phwpvt = drvMsg_genHwpvt(p->pmsgXact->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - /* Set again in case hwpvt was just allocated (and to make compiler happy) */ - pdrvBB232Link = (drvBB232Link *)(p->pmsgXact->phwpvt->pmsgLink->p); - - p->pmsgXact->callback.callback = NULL; - p->pmsgXact->psyncSem = NULL; - - /* Create the skeleton bitbus driver message */ - pdpvtBitBusHead = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead)); - (struct dpvtBitBusHead *)(p->pmsgXact->p) = pdpvtBitBusHead; - - pdpvtBitBusHead->finishProc = NULL; - pdpvtBitBusHead->psyncSem = malloc(sizeof(SEM_ID)); - *(pdpvtBitBusHead->psyncSem) = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pdpvtBitBusHead->link = pdrvBB232Link->link; - - pdpvtBitBusHead->txMsg.route = BB_STANDARD_TX_ROUTE; - pdpvtBitBusHead->txMsg.node = pdrvBB232Link->node; - pdpvtBitBusHead->txMsg.tasks = BB_232_TASK; - pdpvtBitBusHead->txMsg.cmd = 0xff; - - pdpvtBitBusHead->rxMsg.data = (unsigned char *) malloc(BB_MAX_DAT_LEN); - - /* in case I read before write */ - pdpvtBitBusHead->rxMsg.cmd = 0; - pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->status = BB_OK; - - pdpvtBitBusHead->rxMaxLen = 0; - pdpvtBitBusHead->ageLimit = 0; - - if (sscanf(p->plink->value.bitbusio.parm,"%d", &(p->pmsgXact->parm)) != 1) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid parameter string >%s<\n", p->pmsgXact->prec->name, p->plink->value.bitbusio.parm); - errMessage(S_db_badField, message); - return(ERROR); - } - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgHwpvt structure. - * - * It is also responsible for filling in the msgHwpvt.pmsgLink pointer. - * - ******************************************************************************/ -static long -genHwpvt(p) -msgDrvGenHParm *p; -{ - int stat = ERROR; - - if (drvBB232Debug) - printf("BB232 genHwpvt entered\n"); - - p->pmsgHwpvt->pmsgLink = drvBB232Block.pmsgLink; - while ((p->pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR)) - { - if ((((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->link == p->plink->value.bitbusio.link) - && (((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->node == p->plink->value.bitbusio.node) - && (((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->port == p->plink->value.bitbusio.port)) - stat = OK; - else - p->pmsgHwpvt->pmsgLink = p->pmsgHwpvt->pmsgLink->next; - } - if (stat != OK) - { - if ((p->pmsgHwpvt->pmsgLink = drvMsg_genLink(p->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgLink structure. - * - ******************************************************************************/ -static long -genLink(p) -msgDrvGenLParm *p; -{ - char name[20]; - char message[100]; - drvBB232Link *pdrvBB232Link; - - if (drvBB232Debug) - printf("BB232 genLink, link = %d, node = %d\n", p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, p->plink->value.bitbusio.port); - - switch (p->op) { - case MSG_GENLINK_CREATE: - -/* BUG -- verify that the link and node numbers are within range! */ - - if (p->plink->value.bitbusio.port & (~DD_232_PORT)) - { - sprintf(message, "drvBB232: port number %d out of range\n", p->plink->value.bitbusio.port); - errMessage(S_db_badField, message); - return(ERROR); - } - - if ((p->pmsgLink->p = malloc(sizeof(drvBB232Link))) == NULL) - return(ERROR); - - pdrvBB232Link = (drvBB232Link *)(p->pmsgLink->p); - - pdrvBB232Link->link = p->plink->value.bitbusio.link; - pdrvBB232Link->node = p->plink->value.bitbusio.node; - pdrvBB232Link->port = p->plink->value.bitbusio.port; - pdrvBB232Link->pparmBlock = p->pparmBlock; - - - return(OK); - - case MSG_GENLINK_ABORT: - - if (drvBB232Debug) - printf("BB232 genLink: called with abort status\n"); - - pdrvBB232Link = (drvBB232Link *)(p->pmsgLink->p); - /* BUG - free(p->pmsgLink->p); Don't forget to take it out of the list */ - return(OK); - } - return(ERROR); -} - -/****************************************************************************** - * - * This function is called to allow the device to indicate that a device-related - * event has occurred. If an event had occurred, it would have to place the - * address of a valid transaction structure in pxact. This xact structure - * will then be processed by the message link task as indicated by the - * return code of this function. - * - * MSG_EVENT_NONE = no event has occurred, pxact not filled in. - * MSG_EVENT_WRITE = event occurred, process the writeOp assoc'd w/pxact. - * MSG_EVENT_READ = event occurred, process the readOp assoc'd w/pxact. - * - * Note that MSG_EVENT_READ only makes sense when returned with a transaction - * that has deferred readback specified for its readOp function. Because if - * it is NOT a deferred readback, it will be done immediately after the writeOp. - * Even if that writeOp was due to a MSG_EVENT_WRITE from this function. - * - ******************************************************************************/ -static long -checkEvent(p) -msgChkEParm *p; -{ - return(MSG_EVENT_NONE); -} -/****************************************************************************** - * - * This IOCTL function is used to handle non-I/O related operations required - * to operate the RS-232 interface. - * - ******************************************************************************/ -static long -command(p) -ioctlCommand *p; -{ - msgXact *pxact; - struct dpvtBitBusHead *pdpvtBitBusHead; - drvBB232Link *pdrvBB232Link; - - switch (p->cmd) { - case IOCTL232_BREAK: /* send a BREAK signal to the serial port. */ - /* Build a break message to send */ - pxact = (msgXact *) (p->pparm); - pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p); - pdpvtBitBusHead->status = BB_OK; - pdpvtBitBusHead->rxMaxLen = 0; - pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->txMsg.cmd = BB_232_BREAK + pdrvBB232Link->port; - pdpvtBitBusHead->rxMsg.cmd = 0; - - if (drvBB232Debug > 7) - { - printf("drvBB232.control (tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); - - if ((pdpvtBitBusHead->status == BB_OK) && !(pdpvtBitBusHead->rxMsg.cmd & 1)) - return(OK); - else - return(ERROR); - } - - if (drvBB232Debug) - printf("drvBB232.control: bad command 0x%02.2X\n", p->cmd); - return(ERROR); -} - -/****************************************************************************** - * - * This function is used to write a string of characters out to an RS-232 - * device. - * - * Note that the BUGs reply to the write messages with the first 13 bytes - * of the machine's response string (if there is one.) This response string - * will be left in the pdpvtBitBusHead->rxMsg buffer when the drvRead() - * function is called later. - * - ******************************************************************************/ -static long -drvWrite(pxact, pwrParm) -msgXact *pxact; -msgStrParm *pwrParm; -{ - int len; - drvBB232Link *pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p); - struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - unsigned char loopLen; - - /* build a bitbus message and call the bitbus driver */ - - if (pwrParm->len == -1) - len = strlen(pwrParm->buf); - else - len = pwrParm->len; - - pdpvtBitBusHead->txMsg.data = (unsigned char *) pwrParm->buf; - pdpvtBitBusHead->status = BB_OK; - pdpvtBitBusHead->rxMaxLen = BB_MAX_MSG_LENGTH; - - pdpvtBitBusHead->txMsg.cmd = BB_232_CMD + pdrvBB232Link->port; - pdpvtBitBusHead->rxMsg.cmd = 0; - - while (len && (pdpvtBitBusHead->status == BB_OK) && - !(pdpvtBitBusHead->rxMsg.cmd & 1)) - { - if (len > BB_MAX_DAT_LEN) - loopLen = BB_MAX_DAT_LEN; - else - loopLen = len; - - pdpvtBitBusHead->txMsg.length = loopLen + BB_MSG_HEADER_SIZE; - if (softBB232) - { - printf("drvBB232.drvWrite(tx L%d N%d P%d):\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - else - { - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */ - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */ - if (drvBB232Debug > 10) - { - printf("drvBB232.drvWrite (tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - } - - pdpvtBitBusHead->txMsg.data += loopLen; - len -= loopLen; - } - - if ((pdpvtBitBusHead->status != BB_OK) || (pdpvtBitBusHead->rxMsg.cmd & 1)) - { - if (drvBB232Debug) - printf("BB232 write error on link %d, node %d, port %d, driver %02.2X, message %02.2X\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port, pdpvtBitBusHead->status, pdpvtBitBusHead->rxMsg.cmd); - - pxact->status = XACT_IOERR; - } - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to read a string of characters from an RS-232 device. - * - * It is assumed that pdpvtBitBusHead->rxMsg has already got up to 13 - * bytes of the response data already filled in (left there by the prior - * call to drvWrite().) If a call to this function is made when there is - * garbage in the initial pdpvtBitBusHead->rxMsg buffer, set the length field - * to 0 and the status field to BB_OK. - * - ******************************************************************************/ -static long -drvRead(pxact, prdParm) -msgXact *pxact; -msgStrParm *prdParm; -{ - drvBB232Link *pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p); - struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - int len = prdParm->len; - int loopLen = 0; - unsigned char *tmp = pdpvtBitBusHead->rxMsg.data; - - /* check if data already loaded into pdpvtBitBusHead->rxMsg */ - if ((pdpvtBitBusHead->rxMsg.length > BB_MSG_HEADER_SIZE) && (pdpvtBitBusHead->status == BB_OK)) - { - loopLen = pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - - if (prdParm->len < loopLen) - loopLen = prdParm->len; - - if (drvBB232Debug > 9) - { - printf("drvBB232.drvRead (rx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - bcopy(pdpvtBitBusHead->rxMsg.data, prdParm->buf, loopLen); - len -= loopLen; - } - - pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->txMsg.cmd = BB_232_CMD + pdrvBB232Link->port; - - pdpvtBitBusHead->rxMsg.data = (unsigned char *) (&(prdParm->buf[loopLen])); - - if (!(pdpvtBitBusHead->rxMsg.cmd & BB_232_EOI)) - { /* If we did not hit EOI yet, keep reading */ - - while (len && (pdpvtBitBusHead->status == BB_OK)) - { - if (len > BB_MAX_DAT_LEN) - loopLen = BB_MAX_DAT_LEN; - else - loopLen = len; - - pdpvtBitBusHead->rxMaxLen = loopLen + BB_MSG_HEADER_SIZE; - if (softBB232) - { - printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - pdpvtBitBusHead->status = BB_232_EOI; - } - else - { - if (drvBB232Debug > 10) - { - printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */ - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */ - - if (drvBB232Debug > 9) - { - printf("drvBB232.drvRead (rx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - } - - if (pdpvtBitBusHead->rxMsg.cmd & (~BB_232_EOI)) - { /* Something is wrong... */ - if (drvBB232Debug > 6) - { - printf("drvBB232.drvRead (rx L%d N%d P%d) Error response from BUG\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - pxact->status = XACT_IOERR; - break; /* note that we will fall thru to the null-term code */ - } - if (pdpvtBitBusHead->rxMsg.cmd & BB_232_EOI) - { - pdpvtBitBusHead->rxMsg.data += pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - len -= pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - break; - } - - pdpvtBitBusHead->rxMsg.data += loopLen; - len -= loopLen; - } - } - /* Null-terminate the input string (if there is room) */ - if (len) - *(pdpvtBitBusHead->rxMsg.data) = '\0'; - else - pxact->status = XACT_LENGTH; - - /* Note that the following error check, takes priority over a length error */ - if (pdpvtBitBusHead->status != BB_OK) - { - if (drvBB232Debug) - printf("BB232 read error on link %d, node %d, port %d\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - pxact->status = XACT_IOERR; - } - -/* BUG -- this can print unterminated strings !! */ - if (drvBB232Debug > 7) - printf("drvRead: got >%s<\n", prdParm->buf); - - pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; /* in case keep reading */ - return(pxact->status); -} - -/****************************************************************************** - * - * This handles any IOCTL calls made to BB-232 devices. - * - ******************************************************************************/ -static long -drvIoctl(cmd, pparm) -int cmd; -void *pparm; -{ - switch (cmd) { - case MSGIOCTL_REPORT: - return(report()); - case MSGIOCTL_INIT: - return(init(pparm)); - case MSGIOCTL_INITREC: - if (drvBB232Debug) - printf("drvBB232Block.drvIoctl got a MSGIOCTL_INITREC request!\n"); - return(ERROR); - case MSGIOCTL_GENXACT: - return(genXact(pparm)); - case MSGIOCTL_GENHWPVT: - return(genHwpvt(pparm)); - case MSGIOCTL_GENLINK: - return(genLink(pparm)); - case MSGIOCTL_CHECKEVENT: - return(checkEvent(pparm)); - case MSGIOCTL_COMMAND: - return(command(pparm)); - } - return(ERROR); -} - - -msgDrvBlock drvBB232Block = { - "BB232", /* taskName */ - BB232LINK_PRI, /* taskPri */ - BB232LINK_OPT, /* taskOpt */ - BB232LINK_STACK, /* taskStack */ - NULL, /* pmsgLink (linked list header) */ - drvWrite, /* drvWrite */ - drvRead, /* drvRead */ - drvIoctl /* drvIoctl */ -}; diff --git a/src/drv/drvBBMsg.c b/src/drv/drvBBMsg.c deleted file mode 100644 index a693d71b7..000000000 --- a/src/drv/drvBBMsg.c +++ /dev/null @@ -1,590 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 05-21-92 - * EPICS BITBUS driver for message based I/O - * - * 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-10-92 jrw created - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -int drvBBMsgDebug = 0; - -extern struct drvBitBusEt drvBitBus; - -/****************************************************************************** - * - ******************************************************************************/ -#define BBMSGLINK_PRI 50 -#define BBMSGLINK_OPT VX_FP_TASK|VX_STDIO -#define BBMSGLINK_STACK 5000 - - -/****************************************************************************** - * - ******************************************************************************/ -static long -report() -{ - printf("Report for BITBUS message driver\n"); - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -static long -init(pparms) -msgDrvIniParm *pparms; -{ - if (drvBBMsgDebug) - printf("Init for BITBUS message driver\n"); - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgXact structure. - * - * It is also responsible for filling in the msgXact.phwpvt pointer. - * - ******************************************************************************/ -static long -genXact(p) -msgDrvGenXParm *p; -{ - long stat = -1; - char message[100]; - drvBBMsgLink *pdrvBBMsgLink; - struct dpvtBitBusHead *pdpvtBitBusHead; - - if (p->plink->type != BITBUS_IO) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid device type in devSup.ascii (%d)\n", p->pmsgXact->prec->name, p->plink->type); - errMessage(S_db_badField, message); - return(ERROR); - } - - if (drvBBMsgDebug) - printf("BBMsg genXact entered for link %d, bug %d, port %d, parm %s\n", p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, p->plink->value.bitbusio.port, p->plink->value.bitbusio.parm); - - p->pmsgXact->phwpvt = p->pmsgXact->pparmBlock->pmsgHwpvt; - - /* try to find the hwpvt structure for the required link, bug, and port */ - while ((p->pmsgXact->phwpvt != NULL) && (stat == -1)) - { - pdrvBBMsgLink = (drvBBMsgLink *)(p->pmsgXact->phwpvt->pmsgLink->p); - - if ((pdrvBBMsgLink->link == p->plink->value.bitbusio.link) - && (pdrvBBMsgLink->node == p->plink->value.bitbusio.node) - && (pdrvBBMsgLink->port == p->plink->value.bitbusio.port)) - { - if (pdrvBBMsgLink->pparmBlock != p->pmsgXact->pparmBlock) - { - sprintf(message, "%s: Two different devices on same BBMsg port\n", p->pmsgXact->prec->name); - errMessage(S_db_badField, message); - return(ERROR); - } - else - stat = 0; /* Found the correct hwpvt structure */ - } - else - p->pmsgXact->phwpvt = p->pmsgXact->phwpvt->next; - } - if (stat != 0) - { /* Could not find a msgHwpvt for the right link, create a new one */ - if ((p->pmsgXact->phwpvt = drvMsg_genHwpvt(p->pmsgXact->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - /* Set again in case hwpvt was just allocated (and to make compiler happy) */ - pdrvBBMsgLink = (drvBBMsgLink *)(p->pmsgXact->phwpvt->pmsgLink->p); - - p->pmsgXact->callback.callback = NULL; - p->pmsgXact->psyncSem = NULL; - - /* Create the skeleton bitbus driver message */ - pdpvtBitBusHead = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead)); - (struct dpvtBitBusHead *)(p->pmsgXact->p) = pdpvtBitBusHead; - - pdpvtBitBusHead->finishProc = NULL; - pdpvtBitBusHead->psyncSem = malloc(sizeof(SEM_ID)); - *(pdpvtBitBusHead->psyncSem) = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pdpvtBitBusHead->link = pdrvBBMsgLink->link; - - pdpvtBitBusHead->txMsg.route = BB_STANDARD_TX_ROUTE; - pdpvtBitBusHead->txMsg.node = pdrvBBMsgLink->node; - pdpvtBitBusHead->txMsg.tasks = BB_MSG_TASK; - pdpvtBitBusHead->txMsg.cmd = 0xff; - - pdpvtBitBusHead->rxMsg.data = (unsigned char *) malloc(BB_MAX_DAT_LEN); - - /* in case I read before write */ - pdpvtBitBusHead->rxMsg.cmd = 0; - pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->status = BB_OK; - - pdpvtBitBusHead->rxMaxLen = 0; - pdpvtBitBusHead->ageLimit = 0; - - if (sscanf(p->plink->value.bitbusio.parm,"%d", &(p->pmsgXact->parm)) != 1) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid parameter string >%s<\n", p->pmsgXact->prec->name, p->plink->value.bitbusio.parm); - errMessage(S_db_badField, message); - return(ERROR); - } - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgHwpvt structure. - * - * It is also responsible for filling in the msgHwpvt.pmsgLink pointer. - * - ******************************************************************************/ -static long -genHwpvt(p) -msgDrvGenHParm *p; -{ - int stat = ERROR; - - if (drvBBMsgDebug) - printf("BBMSG genHwpvt entered\n"); - - p->pmsgHwpvt->pmsgLink = drvBBMSGBlock.pmsgLink; - while ((p->pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR)) - { - if ((((drvBBMsgLink *)(p->pmsgHwpvt->pmsgLink->p))->link == p->plink->value.bitbusio.link) - && (((drvBBMsgLink *)(p->pmsgHwpvt->pmsgLink->p))->node == p->plink->value.bitbusio.node) - && (((drvBBMsgLink *)(p->pmsgHwpvt->pmsgLink->p))->port == p->plink->value.bitbusio.port)) - stat = OK; - else - p->pmsgHwpvt->pmsgLink = p->pmsgHwpvt->pmsgLink->next; - } - if (stat != OK) - { - if ((p->pmsgHwpvt->pmsgLink = drvMsg_genLink(p->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgLink structure. - * - ******************************************************************************/ -static long -genLink(p) -msgDrvGenLParm *p; -{ - char name[20]; - char message[100]; - drvBBMsgLink *pdrvBBMsgLink; - - if (drvBBMsgDebug) - printf("BBMsg genLink, link = %d, node = %d\n", p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, p->plink->value.bitbusio.port); - - switch (p->op) { - case MSG_GENLINK_CREATE: - -/* BUG -- verify that the link and node numbers are within range! */ - - if (p->plink->value.bitbusio.port & (~DD_MSG_PORT)) - { - sprintf(message, "drvBBMsg: port number %d out of range\n", p->plink->value.bitbusio.port); - errMessage(S_db_badField, message); - return(ERROR); - } - - if ((p->pmsgLink->p = malloc(sizeof(drvBBMsgLink))) == NULL) - return(ERROR); - - pdrvBBMsgLink = (drvBBMsgLink *)(p->pmsgLink->p); - - pdrvBBMsgLink->link = p->plink->value.bitbusio.link; - pdrvBBMsgLink->node = p->plink->value.bitbusio.node; - pdrvBBMsgLink->port = p->plink->value.bitbusio.port; - pdrvBBMsgLink->pparmBlock = p->pparmBlock; - - - return(OK); - - case MSG_GENLINK_ABORT: - - if (drvBBMsgDebug) - printf("BBMsg genLink: called with abort status\n"); - - pdrvBBMsgLink = (drvBBMsgLink *)(p->pmsgLink->p); - /* BUG - free(p->pmsgLink->p); Don't forget to take it out of the list */ - return(OK); - } - return(ERROR); -} - -/****************************************************************************** - * - * This function is called to allow the device to indicate that a device-related - * event has occurred. If an event had occurred, it would have to place the - * address of a valid transaction structure in pxact. This xact structure - * will then be processed by the message link task as indicated by the - * return code of this function. - * - * MSG_EVENT_NONE = no event has occurred, pxact not filled in. - * MSG_EVENT_WRITE = event occurred, process the writeOp assoc'd w/pxact. - * MSG_EVENT_READ = event occurred, process the readOp assoc'd w/pxact. - * - * Note that MSG_EVENT_READ only makes sense when returned with a transaction - * that has deferred readback specified for its readOp function. Because if - * it is NOT a deferred readback, it will be done immediately after the writeOp. - * Even if that writeOp was due to a MSG_EVENT_WRITE from this function. - * - ******************************************************************************/ -static long -checkEvent(p) -msgChkEParm *p; -{ - return(MSG_EVENT_NONE); -} -/****************************************************************************** - * - * This IOCTL function is used to handle non-I/O related operations required - * to operate the RS-MSG interface. - * - ******************************************************************************/ -static long -command(p) -ioctlCommand *p; -{ - msgXact *pxact; - struct dpvtBitBusHead *pdpvtBitBusHead; - drvBBMsgLink *pdrvBBMsgLink; - - switch (p->cmd) { - case IOCTLMSG_BREAK: /* send a BREAK signal to the serial port. */ - /* Build a break message to send */ - pxact = (msgXact *) (p->pparm); - pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - pdrvBBMsgLink = (drvBBMsgLink *)(pxact->phwpvt->pmsgLink->p); - pdpvtBitBusHead->status = BB_OK; - pdpvtBitBusHead->rxMaxLen = 0; - pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->txMsg.cmd = BB_MSG_BREAK + pdrvBBMsgLink->port; - pdpvtBitBusHead->rxMsg.cmd = 0; - - if (drvBBMsgDebug > 7) - { - printf("drvBBMsg.control (tx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); - - if ((pdpvtBitBusHead->status == BB_OK) && !(pdpvtBitBusHead->rxMsg.cmd & 1)) - return(OK); - else - return(ERROR); - } - - if (drvBBMsgDebug) - printf("drvBBMsg.control: bad command 0x%02.2X\n", p->cmd); - return(ERROR); -} - -/****************************************************************************** - * - * This function is used to write a string of characters out to an BB_MSG - * device. - * - * Note that the BUGs reply to the write messages with the first 13 bytes - * of the machine's response string (if there is one.) This response string - * will be left in the pdpvtBitBusHead->rxMsg buffer when the drvRead() - * function is called later. - * - ******************************************************************************/ -static long -drvWrite(pxact, pwrParm) -msgXact *pxact; -msgStrParm *pwrParm; -{ - int len; - drvBBMsgLink *pdrvBBMsgLink = (drvBBMsgLink *)(pxact->phwpvt->pmsgLink->p); - struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - unsigned char loopLen; - - /* build a bitbus message and call the bitbus driver */ - - if (pwrParm->len == -1) - len = strlen(pwrParm->buf); - else - len = pwrParm->len; - - pdpvtBitBusHead->txMsg.data = (unsigned char *) pwrParm->buf; - pdpvtBitBusHead->status = BB_OK; - pdpvtBitBusHead->rxMaxLen = BB_MAX_MSG_LENGTH; - - pdpvtBitBusHead->txMsg.cmd = BB_MSG_CMD + pdrvBBMsgLink->port; - pdpvtBitBusHead->rxMsg.cmd = 0; - - while (len && (pdpvtBitBusHead->status == BB_OK) && - !(pdpvtBitBusHead->rxMsg.cmd & 1)) - { - if (len > BB_MAX_DAT_LEN) - loopLen = BB_MAX_DAT_LEN; - else - loopLen = len; - - pdpvtBitBusHead->txMsg.length = loopLen + BB_MSG_HEADER_SIZE; - if (softBBMsg) - { - printf("drvBBMsg.drvWrite(tx L%d N%d P%d):\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - else - { - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */ - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */ - if (drvBBMsgDebug > 10) - { - printf("drvBBMsg.drvWrite (tx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - } - - pdpvtBitBusHead->txMsg.data += loopLen; - len -= loopLen; - } - - if ((pdpvtBitBusHead->status != BB_OK) || (pdpvtBitBusHead->rxMsg.cmd & 1)) - { - if (drvBBMsgDebug) - printf("BBMsg write error on link %d, node %d, port %d, driver %02.2X, message %02.2X\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port, pdpvtBitBusHead->status, pdpvtBitBusHead->rxMsg.cmd); - - pxact->status = XACT_IOERR; - } - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to read a string of characters from an RS-Msg device. - * - * It is assumed that pdpvtBitBusHead->rxMsg has already got up to 13 - * bytes of the response data already filled in (left there by the prior - * call to drvWrite().) If a call to this function is made when there is - * garbage in the initial pdpvtBitBusHead->rxMsg buffer, set the length field - * to 0 and the status field to BB_OK. - * - ******************************************************************************/ -static long -drvRead(pxact, prdParm) -msgXact *pxact; -msgStrParm *prdParm; -{ - drvBBMsgLink *pdrvBBMsgLink = (drvBBMsgLink *)(pxact->phwpvt->pmsgLink->p); - struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - int len = prdParm->len; - int loopLen = 0; - unsigned char *tmp = pdpvtBitBusHead->rxMsg.data; - - /* check if data already loaded into pdpvtBitBusHead->rxMsg */ - if ((pdpvtBitBusHead->rxMsg.length > BB_MSG_HEADER_SIZE) && (pdpvtBitBusHead->status == BB_OK)) - { - loopLen = pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - - if (prdParm->len < loopLen) - loopLen = prdParm->len; - - if (drvBBMsgDebug > 9) - { - printf("drvBBMsg.drvRead (rx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - bcopy(pdpvtBitBusHead->rxMsg.data, prdParm->buf, loopLen); - len -= loopLen; - } - - pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->txMsg.cmd = BB_MSG_CMD + pdrvBBMsgLink->port; - - pdpvtBitBusHead->rxMsg.data = (unsigned char *) (&(prdParm->buf[loopLen])); - - if (!(pdpvtBitBusHead->rxMsg.cmd & BB_MSG_EOI)) - { /* If we did not hit EOI yet, keep reading */ - - while (len && (pdpvtBitBusHead->status == BB_OK)) - { - if (len > BB_MAX_DAT_LEN) - loopLen = BB_MAX_DAT_LEN; - else - loopLen = len; - - pdpvtBitBusHead->rxMaxLen = loopLen + BB_MSG_HEADER_SIZE; - if (softBBMsg) - { - printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - pdpvtBitBusHead->status = BB_232_EOI; - } - else - { - if (drvBBMsgDebug > 10) - { - printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */ - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */ - - if (drvBBMsgDebug > 9) - { - printf("drvBB232.drvRead (rx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - } - - if (pdpvtBitBusHead->rxMsg.cmd & (~BB_232_EOI)) - { /* Something is wrong... */ - if (drvBBMsgDebug > 6) - { - printf("drvBB232.drvRead (rx L%d N%d P%d) Error response from BUG\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - pxact->status = XACT_IOERR; - break; /* note that we will fall thru to the null-term code */ - } - if (pdpvtBitBusHead->rxMsg.cmd & BB_232_EOI) - { - pdpvtBitBusHead->rxMsg.data += pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - len -= pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - break; - } - - pdpvtBitBusHead->rxMsg.data += loopLen; - len -= loopLen; - } - } - /* Null-terminate the input string (if there is room) */ - if (len) - *(pdpvtBitBusHead->rxMsg.data) = '\0'; - else - pxact->status = XACT_LENGTH; - - /* Note that the following error check, takes priority over a length error */ - if (pdpvtBitBusHead->status != BB_OK) - { - if (drvBBMsgDebug) - printf("BB232 read error on link %d, node %d, port %d\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - pxact->status = XACT_IOERR; - } - -/* BUG -- this can print unterminated strings !! */ - if (drvBBMsgDebug > 7) - printf("drvRead: got >%s<\n", prdParm->buf); - - pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; /* in case keep reading */ - return(pxact->status); -} - -/****************************************************************************** - * - * This handles any IOCTL calls made to BB-MSG devices. - * - ******************************************************************************/ -static long -drvIoctl(cmd, pparm) -int cmd; -void *pparm; -{ - switch (cmd) { - case MSGIOCTL_REPORT: - return(report()); - case MSGIOCTL_INIT: - return(init(pparm)); - case MSGIOCTL_INITREC: - if (drvBBMsgDebug) - printf("drvBBMsgBlock.drvIoctl got a MSGIOCTL_INITREC request!\n"); - return(ERROR); - case MSGIOCTL_GENXACT: - return(genXact(pparm)); - case MSGIOCTL_GENHWPVT: - return(genHwpvt(pparm)); - case MSGIOCTL_GENLINK: - return(genLink(pparm)); - case MSGIOCTL_CHECKEVENT: - return(checkEvent(pparm)); - case MSGIOCTL_COMMAND: - return(command(pparm)); - } - return(ERROR); -} - - -msgDrvBlock drvBBMsgBlock = { - "BBMSG", /* taskName */ - BBMSGLINK_PRI, /* taskPri */ - BBMSGLINK_OPT, /* taskOpt */ - BBMSGLINK_STACK, /* taskStack */ - NULL, /* pmsgLink (linked list header) */ - drvWrite, /* drvWrite */ - drvRead, /* drvRead */ - drvIoctl /* drvIoctl */ -}; diff --git a/src/drv/drvBb902.c b/src/drv/drvBb902.c deleted file mode 100644 index 429f88e3e..000000000 --- a/src/drv/drvBb902.c +++ /dev/null @@ -1,202 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * subroutines that are used to interface to the binary output cards - * - * Author: Bob Dalesio - * Date: 5-26-88 - * - * 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 10-31-91 bg broke bb902 code out of bo_driver.c - * .02 02-20-92 bg Added level to io_report. Added ability - * to read out raw values on card if level - * > 0. - * .03 08-10-92 joh made number of cards runtime configurable - * .04 08-25-92 mrk made masks a macro - * .05 09-14-93 mrk Let report just display one hex value - * - */ - -static char SccsId[] = "@(#)drvBb902.c 1.6 9/14/92 "; - -/* - * Code Portions: - * - * bo_drv_init Finds and initializes all binary output cards present - * bo_driver Interfaces to the binary output cards present - */ - -#include -#include -#include -#include - -static long report(); -static long init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvBb902={ - 2, - report, - init}; - -static long report(level) - int level; -{ - int i; - - bb902_io_report(level); - return(0); -} - -static long init() -{ - int status; - - bb902_driver_init(); - return(0); -} - -#define MAX_BB_BO_CARDS (bo_num_cards[BB902]) - -/* Burr-Brown 902 binary output memory structure */ -struct bo_bb902{ - short csr; /* control status register */ - unsigned short low_value; /* low order 16 bits value */ - unsigned short high_value; /* high order 16 bits value */ - char end_pad[0x100-6]; /* pad until next card */ -}; - -static char *bb902_shortaddr; - -/* pointers to the binary output cards */ -struct bo_bb902 **pbo_bb902s; /* Burr-Brown 902s */ - - -/* - * BO_DRIVER_INIT - * - * intialization for the binary output cards - */ -int bb902_driver_init(){ - int bomode; - int status; - short i; - struct bo_bb902 *pbo_bb902; - - pbo_bb902s = (struct bo_bb902 **)calloc(MAX_BB_BO_CARDS, - sizeof(*pbo_bb902s)); - if(!pbo_bb902s){ - return ERROR; - } - - /* intialize the Burr-Brown 902 binary output cards */ - - /* base address of the burr-brown 902 binary output cards */ - - status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,bo_addrs[BB902],&bb902_shortaddr); - if (status != OK){ - printf("Addressing error in bb902 driver\n"); - return (ERROR); - } - pbo_bb902 = (struct bo_bb902 *)bb902_shortaddr; - /* determine which cards are present */ - for (i = 0; i < bo_num_cards[BB902]; i++,pbo_bb902++){ - if (vxMemProbe(pbo_bb902,READ,sizeof(short),&bomode) == OK) - pbo_bb902s[i] = pbo_bb902; - else - pbo_bb902s[i] = 0; - } - return (0); - -} - -/* - * BB902_DRIVER - * - * interface to the Burr-Brown binary outputs - */ - -int bb902_driver(card,val,mask) -unsigned short card; -unsigned long val; -unsigned long mask; -{ - unsigned int work; - - /* verify card exists */ - if (!pbo_bb902s[card]) - return (-1); - /* use structure to handle high and low short swap */ - /* get current output */ - work = (pbo_bb902s[card]->high_value << 16) /* high */ - + pbo_bb902s[card]->low_value; /* low */ - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - /* write new output */ - pbo_bb902s[card]->high_value = (unsigned short)(work >> 16); - pbo_bb902s[card]->low_value = (unsigned short)work; - return (0); -} - -/* - * bb902_read - * - * read the binary output - */ -int bb902_read(card,mask,pval) -unsigned short card; -unsigned int mask; -unsigned int *pval; -{ - unsigned int work; - - /* verify card exists */ - if (!pbo_bb902s[card]) return (-1); - /* readback */ - *pval = (pbo_bb902s[card]->high_value << 16) /* high */ - + pbo_bb902s[card]->low_value; /* low */ - *pval &= mask; - return(0); -} - -void bb902_io_report(level) - short int level; -{ - unsigned int value; - int card; - - for (card = 0; card < MAX_BB_BO_CARDS; card++){ - if (pbo_bb902s[card]){ - value = (pbo_bb902s[card]->high_value << 16) - + pbo_bb902s[card]->low_value; - printf("BO: BB902: card %d value=0x%08.8x\n",card,value); - } - } - -} diff --git a/src/drv/drvBb910.c b/src/drv/drvBb910.c deleted file mode 100644 index 19db9cbfd..000000000 --- a/src/drv/drvBb910.c +++ /dev/null @@ -1,212 +0,0 @@ -/* bb910_driver.c */ -/* base/src/drv $Id$ */ -/* - * subroutines that are used to interface to the binary input cards - * - * Author: Bob Dalesio - * Date: 6-13-88 - * - * 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 02-09-89 lrd moved I/O addresses to module_types.h - * .02 11-20-89 joh added call to at5vxi driver - * .03 09-11-91 bg added bb910_io_report - * .04 10-31-91 bg broke bb910 code out of bi_driver.c - * .05 02-04-92 bg added the argument level to - * bb910_io_report() and gave it the ability - * to read raw values from card if level > 0 - * .06 08-10-92 joh made the number of cards runtime - * .07 08-25-92 mrk made masks a macro - */ - -/* - * Code Portions: - * - * bi_driver_init Finds and initializes all binary input cards present - * bi_driver Interfaces to the binary input cards present - */ - - -#include -#include -#include -#include - -static long report(); -static long init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvBb910={ - 2, - report, - init}; - -static long report(level) - int level; -{ - register int i; - - bb910_io_report(level); - return(0); -} -static long init() -{ - int status; - - bb910_driver_init(); - return(0); -} - -static char SccsId[] = "@(#)drvBb910.c 1.6\t6/3/93"; - -#define MAX_BB_BI_CARDS (bi_num_cards[BB910]) - -/* Burr-Brown 910 binary input memory structure */ -/* Note: the high and low order words are switched from the io card */ -struct bi_bb910{ - unsigned short csr; /* control status register */ - unsigned short low_value; /* low order 16 bits value */ - unsigned short high_value; /* high order 16 bits value */ - char end_pad[0x100-6]; /* pad until next card */ -}; - -/* pointers to the binary input cards */ -struct bi_bb910 **pbi_bb910s; /* Burr-Brown 910s */ - -/* test word for forcing bi_driver */ -int bi_test; - -static char *bb910_shortaddr; - - -/* - * BI_DRIVER_INIT - * - * intialization for the binary input cards - */ - -bb910_driver_init(){ - int bimode; - int status; - register short i; - struct bi_bb910 *pbi_bb910; - - pbi_bb910s = (struct bi_bb910 **) - calloc(MAX_BB_BI_CARDS, sizeof(*pbi_bb910s)); - if(!pbi_bb910s){ - return ERROR; - } - - /* intialize the Burr-Brown 910 binary input cards */ - /* base address of the burr-brown 910 binary input cards */ - - status=sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,bi_addrs[BB910],&bb910_shortaddr); - if (status != OK){ - printf("Addressing error in bb910 driver\n"); - return ERROR; - } - pbi_bb910 = (struct bi_bb910 *)bb910_shortaddr; - - /* determine which cards are present */ - for (i = 0; i < bi_num_cards[BB910]; i++,pbi_bb910++){ - if (vxMemProbe(pbi_bb910,READ,sizeof(short),&bimode) == OK){ - pbi_bb910s[i] = pbi_bb910; - } - else { - pbi_bb910s[i] = 0; - } - } - - return (0); - -} - - -bb910_driver(card,mask,prval) - - register unsigned short card; - unsigned int mask; - register unsigned int *prval; -{ - register unsigned int work; - - if (!pbi_bb910s[card]) - return (-1); - - /* read */ - - work = (pbi_bb910s[card]->high_value << 16) /* high */ - + pbi_bb910s[card]->low_value; /* low */ - /* apply mask */ - *prval = work & mask; - - return (0); - } - -#define masks(K) ((1< 0){ - num_chans = bi_num_channels[BB910]; - for(j=0,k=1,l=2,m=3;j < num_chans,k < num_chans, l < num_chans,m < num_chans; - j+=IOR_MAX_COLS,k+= IOR_MAX_COLS,l+= IOR_MAX_COLS,m += IOR_MAX_COLS){ - if(j < num_chans){ - bb910_driver(i,masks(j),BB910,&jval); - if (jval != 0) - jval = 1; - printf("Chan %d = %x\t ",j,jval); - } - if(k < num_chans){ - bb910_driver(i,masks(k),BB910,&kval); - if (kval != 0) - kval = 1; - printf("Chan %d = %x\t ",k,kval); - } - if(l < num_chans){ - bb910_driver(i,masks(l),BB910,&lval); - if (lval != 0) - lval = 1; - printf("Chan %d = %x \t",l,lval); - } - if(m < num_chans){ - bb910_driver(i,masks(m),BB910,&mval); - if (mval != 0) - mval = 1; - printf("Chan %d = %x \n",m,mval); - } - } - } - } - } - } diff --git a/src/drv/drvBitBus.c b/src/drv/drvBitBus.c deleted file mode 100644 index 944738c20..000000000 --- a/src/drv/drvBitBus.c +++ /dev/null @@ -1,2616 +0,0 @@ -/* #define XYCOM_DO_RESET_AND_OFFLINE */ -/* #define PEP_DO_RESET_AND_OFFLINE */ - - -/* - changes to UI: - - XYCOM_BB_MAX_OUTSTAND_MSGS -> XycomMaxOutstandMsgs - - - - TODO: - - 1) Synthetic delays after 91s. - 2) Rebuild the link kill stuff so that it does not mess with the WDtask. - 3) Verify race conditions on the slave reset function. - 4) Write a callable bug-syncer that uses the RAC get function ID command. - 5) Merge the watchdog tasks into one. - 6) Try merging the TX and RX tasks. - -*/ - -/* - * Original Author: Ned Arnold - * Author: John Winans - * Date: 09-10-91 - * XVME-402 and PB-bit BitBus driver - * - * 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 09-30-91 jrw Completely redesigned and rewritten - * .02 12-02-91 jrw Changed priority info to arrays - * .03 12-16-91 jrw Made the data portion of the message a pointer - * .04 01-21-91 jrw moved the task parameters into task_params.h - * .05 02-12-92 jrw removed IRQ based transmission. - * .06 04-08-92 jrw moved the device configs into module_types.h - * .07 09-28-92 jrw upped the reset delay time to 1/2 second - * .08 08-02-93 mrk Added call to taskwdInsert - * .09 06-28-94 jrw Major work on RAC_RESET and NODE_OFFLINE stuff. - * .10 07-01-94 jrw Merged PEP and Xycom versions together. - * ANSIficated this code - * - * NOTES: - * This driver currently needs work on error message generation. - * - * $Log$ - * Revision 1.36 1994/12/16 16:11:26 winans - * Added debug flag guards to ALL printing. The default debug level is set - * to 1 -- this provides the same output as the old version. - * - * Revision 1.35 1994/12/12 16:02:57 winans - * Rewrote the init code so that it always returns a zero (don't kill the - * startup.cmd file.) It is possible that this could cause some confusion - * to the database, should it decide to then use a link that did not init - * properly. - * - * Revision 1.34 1994/10/19 18:31:22 winans - * ANSIfied the bitbus driver so that the compiler stopped warning about - * exery third line of code. - * - * Revision 1.33 1994/10/04 18:42:42 winans - * Added an extensive debugging facility. - * - * - */ - -#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 "drvBitBus.h" - -#define STATIC static - -#define BB_DEFAULT_RETIRE_TIME 5 /* Seconds to wait for a response */ - -STATIC long reportBB(void); -STATIC long initBB(void); -STATIC long qBBReq(struct dpvtBitBusHead *pdpvt, int prio); - -STATIC int xvmeReset(int link); -STATIC int xvmeTmoHandler(int link); -STATIC int xvmeRxTask(int link); -STATIC int xvmeTxTask(int link); -STATIC int xvmeWdTask(int link); -STATIC int xvmeIrqRdav(int link); -STATIC int xvmeIrqRcmd(int link); - -STATIC int pepReset(int link); -STATIC int pepTmoHandler(int link); -STATIC int pepRxTask(int link); -STATIC int pepTxTask(int link); -STATIC int pepWdTask(int link); -STATIC int pepIrqRdav(int link); - -STATIC int bbKill(int link); -STATIC void BBrebootFunc(void); - -STATIC int txStuck(int link); -int BBConfig(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); -int __BBConfig(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); - -#ifdef BB_SUPER_DEBUG -int BBHistDump(int link); -STATIC int BBDumpXactHistory(XactHistStruct *pXact); -#endif - - -/***************************************************************************** - * - * Used to limit the TOTAL number of simultaneous messages that can be - * outstanding on a single Xycom link. (Shell settable.) - * - *****************************************************************************/ -int XycomMaxOutstandMsgs = XYCOM_BB_MAX_OUTSTAND_MSGS; - -/***************************************************************************** - * - * Debugging flags that may be set from the shell. - * - * bbDebug Used to get status information from the driver's internals. - * May be set with a value from 0 to 40. the higher the number - * the more information. 0 will provide no internal debugging. - * - * bbDebugLink Used to get general status information about a single slave - * bbDebugNode node. - * To disable this feature, set one of them to -1. - * - *****************************************************************************/ -int bbDebug = 1; -int bbDebugLink=-1; -int bbDebugNode=-1; - -#ifdef BB_SUPER_DEBUG -static int BBSetHistEvent(int link, struct dpvtBitBusHead *pXact, int State); -#endif - -/****************************************************************************** - * - * This structure contains a list of the outside-callable functions. - * - ******************************************************************************/ -struct drvBitBusEt drvBitBus = { - 3, - reportBB, - initBB, - qBBReq -}; - -#if 0 -/* JRW --> get rid of this crap */ -STATIC char BitbusInitCalled = 0; /* to insure that init is done first */ -STATIC void *short_base; /* base of short address space */ -#endif - - -STATIC BitbusLinkStruct *pBBLink[BB_NUM_LINKS]; /* NULL if link not config'd */ - /*************************************************************************** - * - * User-callable configuration function. - * - * This function is used to configure the type of link as well as to - * initialize it for operation. - * - *****************************************************************************/ -int BBConfig(unsigned long Link, - unsigned long LinkType, - unsigned long BaseAddr, - unsigned long IrqVector, - unsigned long IrqLevel) -{ - __BBConfig(Link, LinkType, BaseAddr, IrqVector, IrqLevel); - return(0); -} - -int __BBConfig(unsigned long Link, - unsigned long LinkType, - unsigned long BaseAddr, - unsigned long IrqVector, - unsigned long IrqLevel) -{ - void *pVoid; - int j; - static int FirstTime = 1; - char nameTemp[30]; - int taskId; - - if (FirstTime) - { - rebootHookAdd(BBrebootFunc); - FirstTime = 0; - } - if (Link >= BB_NUM_LINKS) - { - logMsg("Error: Invalid link (%d) specified in BBConfig()\n", Link); - return(-1); - } - if ((LinkType != BB_CONF_TYPE_XYCOM) && (LinkType != BB_CONF_TYPE_PEP)) - { - logMsg("Error: Invalid link type (%d) specified in BBConfig()\n", LinkType); - return(-1); - } - if (pBBLink[Link] != NULL) - { - logMsg("Error: BBConfig() Attempt to reconfigure link %d!\n", Link); - return(-1); - } - - if ((pBBLink[Link] = (BitbusLinkStruct *) malloc(sizeof(BitbusLinkStruct))) == NULL) - { - logMsg("Error: BBConfig() cannot malloc\n"); - return(-1); - } - - pBBLink[Link]->LinkType = BB_CONF_HOSED; /* Changed if all goes well */ - pBBLink[Link]->BaseAddr = BaseAddr; - pBBLink[Link]->IrqVector = IrqVector; - pBBLink[Link]->IrqLevel = IrqLevel; - -#ifdef BB_SUPER_DEBUG - /* Init the history FIFO to empty */ - pBBLink[Link]->History.sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - pBBLink[Link]->History.Next = 0; - pBBLink[Link]->History.Num = 0; -#endif - - pBBLink[Link]->linkEventSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - if (sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO , BaseAddr, &pVoid) != OK) - { - logMsg("Error: BBConfig() can not translate requested A16 address(0x%8.8X\n", BaseAddr); - pBBLink[Link] = NULL; - return(-1); - } - - /* - * Interface specific I/O mapping and registration - */ - - switch (LinkType) - { - case BB_CONF_TYPE_XYCOM: - pBBLink[Link]->l.XycomLink.rxInt = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pBBLink[Link]->l.XycomLink.bbRegs = (XycomBBRegsStruct *)pVoid; - if (devRegisterAddress("Xycom Bitbus", atVMEA16, (void*)BaseAddr, sizeof(XycomBBRegsStruct), NULL) != 0) - { - logMsg("Error: BBConfig() can not register address %8.8X\n", pVoid); - pBBLink[Link] = NULL; - return(-1); /* BUG */ - } - break; - case BB_CONF_TYPE_PEP: - pBBLink[Link]->l.PepLink.rxInt = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pBBLink[Link]->l.PepLink.bbRegs = (PepBBRegsStruct *)pVoid; - if (devRegisterAddress("PEP Bitbus", atVMEA16, (void*)BaseAddr, sizeof(PepBBRegsStruct), NULL) != 0) - { - logMsg("Error: BBConfig() can not register address %8.8X\n", pVoid); - pBBLink[Link] = NULL; - return(-1); /* BUG */ - } - break; - } - - /* - * Common data structure initialization. - */ - - /* Init the prioritized queue lists */ - for (j=0; jqueue[j].head = NULL; - pBBLink[Link]->queue[j].tail = NULL; - pBBLink[Link]->queue[j].sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - pBBLink[Link]->queue[j].elements = 0; - } - - /* Init the busy message list */ - pBBLink[Link]->busyList.sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - pBBLink[Link]->busyList.head = NULL; - pBBLink[Link]->busyList.tail = NULL; - pBBLink[Link]->busyList.elements = 0; - - for (j=0; jdeviceStatus[j] = BB_IDLE; - pBBLink[Link]->syntheticDelay[j] = 0; - } - pBBLink[Link]->DelayCount = 0; - - pBBLink[Link]->watchDogId = wdCreate(); - pBBLink[Link]->watchDogSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - /* Clear the link abort status */ - pBBLink[Link]->abortFlag = 0; - pBBLink[Link]->txAbortAck = 0; - pBBLink[Link]->rxAbortAck = 0; - - /* - * Interface type specific initialization of management tasks. - */ - - if (LinkType == BB_CONF_TYPE_XYCOM) - { - /* BOARD SPECIFIC INIT CODE for XYCOM */ - if (xvmeReset(Link) != 0) - { - pBBLink[Link] = NULL; - return(-1); - } - - pBBLink[Link]->LinkType = LinkType; - - /* attach the interrupt handler routines */ - intConnect((BB_IVEC_BASE + 1 + (Link*4)) * 4, xvmeIrqRcmd, Link); - intConnect((BB_IVEC_BASE + 3 + (Link*4)) * 4, xvmeIrqRdav, Link); - - /* Start a task to manage the TX link */ - sprintf(nameTemp, "%s%d-xy", BBTXLINK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBTXLINK_PRI, BBTXLINK_OPT, BBTXLINK_STACK, xvmeTxTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start TX link task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - /* Start a task to manage the RX link */ - sprintf(nameTemp, "%s%d-xy", BBRXLINK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBRXLINK_PRI, BBRXLINK_OPT, BBRXLINK_STACK, xvmeRxTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start RX link task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - /* Start a task to keep an eye on the busy list */ - sprintf(nameTemp, "%s%d-xy", BBWDTASK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBWDTASK_PRI, BBWDTASK_OPT, BBWDTASK_STACK, xvmeWdTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start watchdog task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - } - else if (LinkType == BB_CONF_TYPE_PEP) - { - /* PEP specific init code */ - if (pepReset(Link) != 0) - { - pBBLink[Link] = NULL; - return(-1); - } - - pBBLink[Link]->LinkType = LinkType; - - /* attach the interrupt handler routines */ - intConnect(INUM_TO_IVEC(PEP_BB_IVEC_BASE + (Link*2)), pepIrqRdav, Link); - - /* Start a task to manage the TX link */ - sprintf(nameTemp, "%s%d-pep", BBTXLINK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBTXLINK_PRI, BBTXLINK_OPT, BBTXLINK_STACK, pepTxTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start TX link task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - /* Start a task to manage the RX link */ - sprintf(nameTemp, "%s%d-pep", BBRXLINK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBRXLINK_PRI, BBRXLINK_OPT, BBRXLINK_STACK, pepRxTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start RX link task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - /* Start a task to keep an eye on the busy list */ - sprintf(nameTemp, "%s%d-pep", BBWDTASK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBWDTASK_PRI, BBWDTASK_OPT, BBWDTASK_STACK, pepWdTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start watchdog task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - } - sysIntEnable(IrqLevel); - return(0); -} - /****************************************************************** - * - * The EPICS init routine is not needed. - * - ******************************************************************/ -STATIC long initBB(void) -{ - return(0); -} - -/****************************************************************** - * FUNCTION: reportBB() - * PURPOSE : Prints a message indicating the presence of each - * bitbus module found in system. - * ARGS IN : none - * ARGS OUT: none - * GLOBALS: checks pBBLink[i] for NULL - ******************************************************************/ - -STATIC long reportBB(void) -{ - int i; - - if (bbDebug>1) - printf("Bitbus debugging flag is set to %d\n", bbDebug); - - for (i=0; i< BB_NUM_LINKS; i++) - { - if (pBBLink[i] != NULL) - { - if (pBBLink[i]->LinkType == BB_CONF_TYPE_XYCOM) - printf("Bitbus link %d present at %p IV=0x%2.2X IL=%d (XYCOM)\n", i, pBBLink[i]->l.XycomLink.bbRegs, pBBLink[i]->IrqVector, pBBLink[i]->IrqLevel); - else if (pBBLink[i]->LinkType == BB_CONF_TYPE_PEP) - printf("Bitbus link %d present at %p IV=0x%2.2X IL=%d (PEP)\n", i, pBBLink[i]->l.PepLink.bbRegs, pBBLink[i]->IrqVector, pBBLink[i]->IrqLevel); - } - } - return(OK); -} - /****************************************************************** - * FUNCTION: pepReset() - * PURPOSE : Performs firmware reset of PB-BIT module corresponding - * to link. Attempts to empty any data sitting in receive - * FIFO. Interrupts are disabled and Rx task is unblocked. - * ARGS IN : xvmeRegs ptr to register structure of PB-BIT module - * link link number serviced by PB-BIT module - * ARGS OUT: none - * GLOBALS: twiddles board - ******************************************************************/ -STATIC int -pepReset(int link) -{ - char trash; - int j; - int lockKey; - int probeValue; - - if (bbDebug) - printf("pepReset(%d): Resetting pep module\n", link); - - probeValue = 0; - if (vxMemProbe(&(pBBLink[link]->l.PepLink.bbRegs->int_vec), WRITE, 1, &probeValue) < OK) - { /* no BB board present here */ - logMsg("ERROR: PEP Bitbus link %d not present at 0x%8.8X\n", link, pBBLink[link]->l.PepLink.bbRegs); - return(-1); - } - - /* Write firmware reset package (2 bytes) to board */ - pBBLink[link]->l.PepLink.bbRegs->data = 0x83; - pBBLink[link]->l.PepLink.bbRegs->stat_ctl = 0x01; - - taskDelay(20); /* give the 80152 time to self check */ - - if ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & 0x10) != 0x0) - { - if (bbDebug) - printf("pepReset(%d): PB-BIT firmware reset failed!\n", link); - return(ERROR); - } - - j = 1026; /* 1K deep receive fifo */ - /* flush receive fifo if junk in it */ - while ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_RFNE) && --j) - trash = pBBLink[link]->l.PepLink.bbRegs->data; - - if (!j) - { - if (bbDebug) - printf("pepReset(%d): receive fifo will not clear after reset!\n", link); - return(ERROR); - } - - /* Disable interrupts */ - lockKey = intLock(); - pBBLink[link]->l.PepLink.bbRegs->int_vec = 0; - intUnlock(lockKey); - - /* Tell pepRxTask to Re-enable ints */ - semGive(pBBLink[link]->l.PepLink.rxInt); - - return(OK); -} - /**************************************************************************** - * - * Reset an xvme-402 BitBus card by cycling the reset bit in the fifo - * status register. - * - ****************************************************************************/ -STATIC int xvmeReset(int link) -{ - char trash; - int j; - int lockKey; - int probeValue; - - - if (bbDebug) - printf("xvmeReset(%d): Resetting xvme module\n", link); - - probeValue = XVME_RESET; - if (vxMemProbe(&(pBBLink[link]->l.XycomLink.bbRegs->fifo_stat), WRITE, 1, &probeValue) < OK) - { /* no BB board present here */ - logMsg("ERROR: Xycom Bitbus link %d not present at 0x%8.8X\n", link, pBBLink[link]->l.XycomLink.bbRegs); - return(-1); - } - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_RESET); -#endif - - taskDelay(2); - pBBLink[link]->l.XycomLink.bbRegs->fifo_stat = 0; /* clear reset pulse */ - taskDelay(30); /* give the 8044 time to self check */ - - j = 100; /* give up after this */ - while ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RCMD) && --j) - trash = pBBLink[link]->l.XycomLink.bbRegs->cmnd; /* flush command buffer if junk in it */ - - if (!j) - { - if (bbDebug) - printf("xvmeReset(%d): Command buffer will not clear after reset!\n", link); - return(ERROR); - } - - j = 100; - while ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RFNE) && --j) - trash = pBBLink[link]->l.XycomLink.bbRegs->data; /* flush data buffer if junk in it */ - - if (!j) - { - if (bbDebug) - printf("xvmeReset(%d): Data buffer will not clear after reset!\n", link); - return(ERROR); - } - - if ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_FSVALID) != XVME_FSIDLE) - { - if (bbDebug) - printf("xvmeReset(%d): XVME board not returning to idle status after reset!\n", link); - return(ERROR); - } - - /* set the interrupt vector */ - lockKey = intLock(); - pBBLink[link]->l.XycomLink.bbRegs->stat_ctl = 0; /* disable all interupts */ - pBBLink[link]->l.XycomLink.bbRegs->int_vec = BB_IVEC_BASE + (link*4);/* set the int vector */ - intUnlock(lockKey); - - semGive(pBBLink[link]->l.XycomLink.rxInt); /* Tell xvmeRxTask to Re-enable interrupts */ - - return(OK); -} - /**************************************************************************** - * - * This function is used to add a node to the HEAD of a list. - * - ****************************************************************************/ -static int -listAddHead(struct bbList *plist, struct dpvtBitBusHead *pnode) -{ - pnode->prev = NULL; - pnode->next = plist->head; - - if (plist->head != NULL) - plist->head->prev = pnode; - - if (plist->tail == NULL) - plist->tail = pnode; - - plist->head = pnode; - - plist->elements++; - - return(0); -} -/****************************************************************************** - * - * This function is used to add a node to the TAIL of a list. - * - ******************************************************************************/ -static int -listAddTail(struct bbList *plist, struct dpvtBitBusHead *pnode) -{ - pnode->next = NULL; /* No next node if this is the TAIL */ - pnode->prev = plist->tail; /* previous node is the 'old' TAIL node */ - - if (plist->tail != NULL) - plist->tail->next = pnode; /* link the 'old' tail to the 'new' tail node */ - - if (plist->head == NULL) - plist->head = pnode; - - plist->tail = pnode; /* this is the 'new' tail node */ - - plist->elements++; - - return(0); -} - /*************************************************************************** - * - * This function is used to delete a node from a list. - * - ***************************************************************************/ -static int -listDel(struct bbList *plist, struct dpvtBitBusHead *pnode) -{ - if (pnode->next != NULL) - pnode->next->prev = pnode->prev; - - if (pnode->prev != NULL) - pnode->prev->next = pnode->next; - - if (plist->head == pnode) - plist->head = pnode->next; - - if (plist->tail == pnode) - plist->tail = pnode->prev; - - plist->elements--; - - return(0); -} - /**************************************************************************** - * - * xycom IRQ handler for receiver data bytes. - * - ****************************************************************************/ -static int -xvmeIrqRdav(int link) -{ - if (bbDebug > 30) - logMsg("bitbus rx IRQ on link %d\n", link); - semGive(pBBLink[link]->l.XycomLink.rxInt); /* deliver the groceries */ - return(0); -} - -/**************************************************************************** - * - * xycom IRQ handler invoked when the BitBus controller has completed the - * transfer of a RECEIVED message. - * - ****************************************************************************/ -static int -xvmeIrqRcmd(int link) -{ - if (bbDebug > 30) - logMsg("bitbus rcmd IRQ on link %d\n", link); - semGive(pBBLink[link]->l.XycomLink.rxInt); /* deliver the groceries */ - return(0); -} - /****************************************************************** - * FUNCTION: pepIrqRdav() - * PURPOSE : Invoked when PB-BIT module has received a complete - * bitbus message (ie. not on a byte-by-byte basis). - * ARGS IN : link link number upon which message has arrived - * ARGS OUT: none - * GLOBALS: unblocks Rx task (if it is not already running) - ******************************************************************/ -STATIC int -pepIrqRdav(int link) -{ - pBBLink[link]->l.PepLink.bbRegs->int_vec = 0; /* disable IRQs */ - - if (bbDebug > 30) - logMsg("PEP bitbus rx IRQ on link %d\n", link); - - semGive(pBBLink[link]->l.PepLink.rxInt); /* unblock it */ - return(0); -} - /****************************************************************** - * FUNCTION: pepTmoHandler() - * PURPOSE : Invoked whenever a watchdog timer times out. Watchdogs - * are running whenever the busyList has any elements on - * it. The idea here is that the watchdog handler scans - * through the busyList, looking for old requests that have - * not been replied to in too long a time. If there are - * any old ones around, they are removed from the list, - * and the associated node is reset and marked offline. - * - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int -pepTmoHandler(int link) -{ - if (bbDebug > 25) - logMsg("pepTmoHandler(%d): Watch dog interrupt\n", link); - - semGive(pBBLink[link]->watchDogSem); /* unblock Wd task */ - return(0); -} - -/****************************************************************************** - * - * Watchdogs are running when ever the busy list has any elements in it. - * The idea here is that the watchdog handler scans thru the busy list, - * looking for old requests that have not been replied to in too long - * a time. If there are any old ones around, they are removed from the - * list and marked as un-replied to. - * - ******************************************************************************/ -static int -xvmeTmoHandler(int link) -{ - if (bbDebug > 25) - logMsg("xvmeTmoHandler(%d): Watch dog interrupt\n", link); - - semGive(pBBLink[link]->watchDogSem); - return(0); -} - /**************************************************************************** - * - * Given a link number, make sure it is valid. - * - ****************************************************************************/ -static int -checkLink(int link) -{ - if ((link<0) || (link>BB_NUM_LINKS)) - return(ERROR); /* link number out of range */ - - if (pBBLink[link] == NULL) - return(ERROR); /* link number has no card installed */ - - return(OK); -} - /*************************************************************************** - * - * This function is started as a task during driver init time. It's purpose - * is to read messages that are received from the bitbus link. After a message - * is received, the soliciting message's completion routines are started by - * the use of semaphores and/or a callbackRequest(). - * - ***************************************************************************/ -static int -xvmeRxTask(int link) -{ - int rxState; /* current state of the receiver */ -#define BBRX_HEAD 1 -#define BBRX_DATA 2 -#define BBRX_RCMD 3 -#define BBRX_IGN 4 - - unsigned char rxHead[5]; /* room for header of current rx msg */ - unsigned char *rxMsg; /* where to place next byte (after header) */ - int rxTCount; /* byte counter for data in rxHead */ - unsigned char ch; - struct dpvtBitBusHead *rxDpvtHead; /* for message currently receiving */ - - struct dpvtBitBusHead UselessMsg; /* to hold unsolicited responses */ - unsigned char UselessData[BB_MAX_MSG_LENGTH]; - - int lockKey; /* used for intLock calls */ - - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - /* Dummy up the UselessMsg fields so we can use it */ - UselessMsg.rxMaxLen = BB_MAX_MSG_LENGTH; - UselessMsg.rxMsg.data = UselessData; - UselessMsg.link = link; - UselessMsg.ageLimit = 0; - UselessMsg.retire = 0; - - while (1) - { - /* Wait for RX interrupts, but only if no chars are ready */ - if ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RFNE) == 0) - { - /* Enable interrupts and check again because xycom blew it */ - lockKey = intLock(); - pBBLink[link]->l.XycomLink.bbRegs->stat_ctl = XVME_ENABLE_INT | XVME_RX_INT; - intUnlock(lockKey); - - while (((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RFNE) == 0) && (pBBLink[link]->abortFlag == 0)) - { - /* Re-enable ints here each time in case board got reset */ - lockKey = intLock(); - pBBLink[link]->l.XycomLink.bbRegs->stat_ctl = XVME_ENABLE_INT | XVME_RX_INT; - intUnlock(lockKey); - - /* Wait for groceries */ - semTake(pBBLink[link]->l.XycomLink.rxInt, WAIT_FOREVER); - } - /* Disable RX Interrupts (prevents unnecessary context switching) */ - lockKey = intLock(); - pBBLink[link]->l.XycomLink.bbRegs->stat_ctl = 0; - intUnlock(lockKey); - } - if (pBBLink[link]->abortFlag == 0) - { - /* check to see if we got a data byte or a command byte */ - if ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RCMD) == XVME_RCMD) - rxState = BBRX_RCMD; - - switch (rxState) { - case BBRX_HEAD: /* getting the head of a new message */ - rxHead[rxTCount] = pBBLink[link]->l.XycomLink.bbRegs->data; - if (bbDebug>21) - printf("xvmeRxTask(%d): >%2.2X< (Header)\n", link, rxHead[rxTCount]); - - if (++rxTCount == 5) - { /* find the message this is a reply to */ - rxTCount += 2; /* adjust for the link field space */ - - /* Lock the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - - rxDpvtHead = pBBLink[link]->busyList.head; - while (rxDpvtHead != NULL) - { - if (bbDebug>19) - printf("xvmeRxTask(%d): checking reply against %p\n", link, rxDpvtHead); - - /* see if node's match */ - if (rxDpvtHead->txMsg.node == rxHead[2]) - { /* see if the tasks match */ - if (rxDpvtHead->txMsg.tasks == rxHead[3]) - { /* They match, finish putting response into the rxMsg buffer */ - if (bbDebug>4) - printf("xvmeRxTask(%d): reply to %p\n", link, rxDpvtHead); - - /* Delete the node from the list */ - listDel(&(pBBLink[link]->busyList), rxDpvtHead); - - /* If busy list is empty, stop the dog */ - if (pBBLink[link]->busyList.head == NULL) - wdCancel(pBBLink[link]->watchDogId); - - if (rxHead[4] == 0x91) - { /* something bad happened... inject a delay to the */ - /* requested timeout duration. */ - - if (bbDebug) - printf("xvmeRxTask(%d): 0x91 from node %d, invoking synthetic delay\n", link, rxHead[2]); - (pBBLink[link]->syntheticDelay[rxDpvtHead->txMsg.node]) = rxDpvtHead->retire; - pBBLink[link]->DelayCount++; - } - else - { /* decrement the number of outstanding messages to the node */ - (pBBLink[link]->deviceStatus[rxDpvtHead->txMsg.node])--; - } - - /* Wake up Link Task in case was waiting on "this" node */ - semGive(pBBLink[link]->linkEventSem); - -#if 0 - semGive(pXvmeLink[link]->pbbLink->busyList.sem); - - rxDpvtHead->rxMsg.length = rxHead[0]; - rxDpvtHead->rxMsg.route = rxHead[1]; - rxDpvtHead->rxMsg.node = rxHead[2]; - rxDpvtHead->rxMsg.tasks = rxHead[3]; - rxDpvtHead->rxMsg.cmd = rxHead[4]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ -#endif - break; /* get out of the while() */ - } - } - rxDpvtHead = rxDpvtHead->next; /* Keep looking */ - } - - semGive(pBBLink[link]->busyList.sem); - - /* Couldn't find a match... fake one so can print the bad message */ - if (rxDpvtHead == NULL) - rxDpvtHead = &UselessMsg; - - rxDpvtHead->rxMsg.length = rxHead[0]; - rxDpvtHead->rxMsg.route = rxHead[1]; - rxDpvtHead->rxMsg.node = rxHead[2]; - rxDpvtHead->rxMsg.tasks = rxHead[3]; - rxDpvtHead->rxMsg.cmd = rxHead[4]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ - } - break; - - case BBRX_DATA: /* finish reading data portion of message */ - ch = pBBLink[link]->l.XycomLink.bbRegs->data; - if (rxTCount >= rxDpvtHead->rxMaxLen) - { - rxState = BBRX_IGN; /* toss the rest of the data */ - rxDpvtHead->status = BB_LENGTH; /* set driver status */ - if (bbDebug>22) - printf("xvmeRxTask(%d): %2.2X (Ignored)\n", link, ch); - } - else - { - *rxMsg = ch; - if (bbDebug>22) - printf("xvmeRxTask(%d): %2.2X (Data)\n", link, ch); - rxMsg++; - rxTCount++; - } - break; - - case BBRX_IGN: - ch = pBBLink[link]->l.XycomLink.bbRegs->data; - if (bbDebug>22) - printf("xvmeRxTask(%d): %2.2X (Ignored)\n", link, ch); - break; - - case BBRX_RCMD: - if (rxDpvtHead == NULL) - { - ch = pBBLink[link]->l.XycomLink.bbRegs->cmnd; - if (bbDebug) - printf("xvmeRxTask(%d): got unexpected XVME_RCMD\n", link); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_RX_URCMD); -#endif - } - else if (rxDpvtHead == &UselessMsg) - { - rxDpvtHead->status = BB_OK; - rxDpvtHead->rxCmd = pBBLink[link]->l.XycomLink.bbRegs->cmnd; - - if (bbDebug) - { - printf("xvmeRxTask(%d): msg from node %d unsolicited:", link, rxDpvtHead->rxMsg.node); - drvBitBusDumpMsg(&(rxDpvtHead->rxMsg)); - } -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX_UNSOLICITED); -#endif - } - else - { - rxDpvtHead->status = BB_OK; - rxDpvtHead->rxCmd = pBBLink[link]->l.XycomLink.bbRegs->cmnd; - - if (bbDebug>24) - printf("xvmeRxTask(%d):RX command byte = %2.2X\n", link, rxDpvtHead->rxCmd); - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX); -#endif - if (rxDpvtHead->finishProc != NULL) - { - if (bbDebug>8) - printf("xvmeRxTask(%d): invoking the callbackRequest\n", link); - callbackRequest(rxDpvtHead); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (rxDpvtHead->psyncSem != NULL) - semGive(*(rxDpvtHead->psyncSem)); - } - } - /* Reset the state of the RxTask to expect a new message */ - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - break; - } - } - else - { /* Link abort state is active reset receiver link status now */ - if (rxDpvtHead != NULL) - { /* This xact is not on the busy list, put it back on */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - (pBBLink[link]->deviceStatus[rxDpvtHead->txMsg.node])++; - listAddTail(&(pBBLink[link]->busyList), rxDpvtHead); - semGive(pBBLink[link]->busyList.sem); - } - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX_ABORT); -#endif - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - /* Tell the watch dog I am ready for the reset (reset in the dog task) */ - pBBLink[link]->rxAbortAck = 1; - - if (bbDebug) - printf("xvmeRxTask(%d): resetting due to abort status\n", link); - - /* wait for link state to become active again */ - while (pBBLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); - - if (bbDebug) - printf("xvmeRxTask(%d): restarting after abort\n", link); - } - } -} - -/****************************************************************************** - * - * A user callable link resetter. This sets a flag and releases the dog - * task to reset the link. - * - ******************************************************************************/ -int -bbReset(int link) -{ - if (checkLink(link) != ERROR) - { - pBBLink[link]->nukeEm = 1; - semGive(pBBLink[link]->watchDogSem); - } - else - printf("Link %d not installed.\n", link); - - return(0); -} - -/****************************************************************************** - * - * BUG -- this does not do the nuke=2 reset and kill link operations like - * the PEP does. - * - ******************************************************************************/ -static int -xvmeWdTask(int link) -{ - struct dpvtBitBusHead *pnode; - struct dpvtBitBusHead *npnode; - unsigned long now; - -#ifdef XYCOM_DO_RESET_AND_OFFLINE - SEM_ID syncSem; - - struct dpvtBitBusHead resetNode; - unsigned char resetNodeData; /* 1-byte data field for RAC_OFFLINE */ - - /* init the SEM used when sending the reset message */ - syncSem = semBCreate(SEM_EMPTY, SEM_Q_PRIORITY); - - /* - * Hand-craft a RAC_OFFLINE message to use when a message times out. - * NOTE that having only one copy is OK provided that the dog waits for - * a response before sending it again! - */ - resetNode.finishProc = NULL; /* no callback routine used */ - resetNode.psyncSem = &syncSem;/* do a semGive on this SEM when done sending */ - resetNode.link = link; /* which bitbus link to send message out on */ - resetNode.rxMaxLen = 7; /* Chop off the response... we don't care */ - resetNode.ageLimit = sysClkRateGet()*100; /* make sure this never times out */ - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.node = 0xff; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.cmd = RAC_OFFLINE; - resetNode.txMsg.data = &resetNodeData; -#endif - - pBBLink[link]->nukeEm = 0; /* Make sure the nuke status is clear */ - while(1) - { - semTake(pBBLink[link]->watchDogSem, WAIT_FOREVER); - now = tickGet(); /* what time is it? */ - - if (pBBLink[link]->nukeEm != 0) - printf("Bitbus manual reset being issued on link %d\n", link); - - if (bbDebug>4) - printf("xvmeWdTask(%d): (Watchdog) checking busy list\n", link); - - pBBLink[link]->rxAbortAck = 0; /* In case we need to use them */ - pBBLink[link]->txAbortAck = 0; - - if (pBBLink[link]->nukeEm != 0) - { /* set abort status and wait for the abort acks */ - pBBLink[link]->abortFlag = 1; - - /* wake up the Tx task so it can observe the abort status */ - semGive(pBBLink[link]->linkEventSem); - - /* wake up the Rx task so it can observe the abort ststus */ - semGive(pBBLink[link]->l.XycomLink.rxInt); - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pBBLink[link]->rxAbortAck == 0) && (pBBLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - -#ifdef BB_SUPER_DEBUG - if (pBBLink[link]->nukeEm < 2) - { /* Do a history dump since this is not supposed to happen */ - BBHistDump(link); - } -#endif - } - /* - * Run thru entire busy list to see if there are any transactions - * that have been waiting on a response for too long a period. - */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - pnode = pBBLink[link]->busyList.head; - - while (pnode != NULL) - { - npnode = pnode->next; /* remember where we were in the list */ - - if ((pBBLink[link]->nukeEm != 0) || (pnode->retire <= now)) - { - /* Get rid of the request and set error status etc... */ - listDel(&(pBBLink[link]->busyList), pnode); - - if (bbDebug) - { -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_WD_TIMEOUT); -#endif - printf("xvmeWdTask(%d): TIMEOUT on bitbus message:\n", link); - drvBitBusDumpMsg(&pnode->txMsg); - } - - /* BUG -- do this here or defer until RX gets a response? */ - (pBBLink[link]->deviceStatus[pnode->txMsg.node])--; /* fix device status */ - pnode->status = BB_TIMEOUT; - -#ifdef XYCOM_DO_RESET_AND_OFFLINE - /* BUG ----- wait for the response from the last one first? */ - - /* Do now in case we need it later */ - resetNodeData = pnode->txMsg.node; /* mark the node number */ -#endif - - /* Make the callbackRequest if one was spec'd */ - if(pnode->finishProc != NULL) - { - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* Release a completion lock if one was spec'd */ - if (pnode->psyncSem != NULL) - semGive(*(pnode->psyncSem)); - } - -#ifdef XYCOM_DO_RESET_AND_OFFLINE - /* If we are not going to reboot the link... */ - if (pBBLink[link]->nukeEm == 0) - { /* Send out a RAC_NODE_OFFLINE to the controller */ - semGive(pBBLink[link]->busyList.sem); - - if (bbDebug) - printf("issuing a node offline for link %d node %d\n", link, resetNodeData); - - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &resetNode); - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); - - semGive(pBBLink[link]->linkEventSem); /* Tell TxTask to send the message */ - - if (semTake(syncSem, sysClkRateGet()/4) == ERROR) - { - if (bbDebug) - printf("xvmeWdTask(%d): link dead, trying manual reboot\n", link); - pBBLink[link]->nukeEm = 1; - - pBBLink[link]->abortFlag = 1; /* Start the abort sequence */ - semGive(pBBLink[link]->linkEventSem); /* Let Tx task observe abort status */ - semGive(pBBLink[link]->l.XycomLink.rxInt); /* Let Rx task observe abort ststus */ - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pBBLink[link]->rxAbortAck == 0) && (pBBLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - } - /* Start over since released the busy list */ - - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - npnode = pBBLink[link]->busyList.head; - } -#else - semGive(pBBLink[link]->linkEventSem); -#endif - } - pnode = npnode; - } - if (pBBLink[link]->busyList.head != NULL) - { /* Restart the dog timer */ - - if (bbDebug>5) - printf("xvmeWdTask(%d): restarting watch dog timer\n", link); - - wdStart(pBBLink[link]->watchDogId, pBBLink[link]->busyList.head->retire - now, xvmeTmoHandler, link); - } - semGive(pBBLink[link]->busyList.sem); - - /* Finish the link reboot if necessary */ - if (pBBLink[link]->nukeEm != 0) - { - xvmeReset(link); - - /* clear the abort_flag */ - pBBLink[link]->abortFlag = 0; - - pBBLink[link]->nukeEm = 0; - } - } -} - -/****************************************************************************** - * - * This function is started as a task during driver init time. It's purpose - * is to keep the link busy. It awaits user-calls to qBbReq() with new work - * as well as wake-up calls from the watchdog timer. - * - * At the time this function is started as its own task, the linked list - * structures will have been created and initialized. - * - ******************************************************************************/ -static int -xvmeTxTask(int link) -{ - struct dpvtBitBusHead *pnode; - int prio; - int working; - int dogStart; - int stuck; - - int txTCount; - int txCCount; - unsigned char *txMsg; - register int x; - unsigned long now; - SEM_ID resetNodeSem; - struct dpvtBitBusHead resetNode; - unsigned char resetNodeData; /* 1-byte data field for RAC_OFFLINE */ - - if (bbDebug) - printf("xvmeTxTask started for link %d\n", link); - - /* hand-craft a RAC_OFFLINE message for use with RAC_RESET_SLAVE commands */ - /* NOTE that having only one copy is OK provided that this message is */ - /* sent immediately following the RAC_RESET_SLAVE message. */ - - resetNodeSem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - - resetNode.finishProc = NULL; - resetNode.psyncSem = &resetNodeSem; - resetNode.link = link; - resetNode.rxMaxLen = 7; /* Chop it off, we don't care */ - resetNode.ageLimit = sysClkRateGet(); - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.node = 0xff; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.cmd = RAC_OFFLINE; - resetNode.txMsg.data = &resetNodeData; - - while(1) - { - if (pBBLink[link]->abortFlag != 0) - { - pBBLink[link]->txAbortAck = 1; /* let the dog know we are ready */ -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_TX_ABORT); -#endif - - if (bbDebug) - printf("xvmeTxTask(%d): resetting due to abort status\n", link); - - while (pBBLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); /* wait for link to reset */ - - if (bbDebug) - printf("xvmeTxTask(%d): restarting after abort\n", link); - } - else - { - if (pBBLink[link]->DelayCount) - semTake(pBBLink[link]->linkEventSem, 2 * sysClkRateGet()); - else - semTake(pBBLink[link]->linkEventSem, WAIT_FOREVER); - } - - if (bbDebug>5) - printf("xvmeTxTask(%d): got an event\n", link); - - working = 1; - while ((working != 0) && (pBBLink[link]->abortFlag == 0) && (pBBLink[link]->busyList.elements < XycomMaxOutstandMsgs)) - { - working = 0; - - prio = BB_NUM_PRIO-1; - while ((prio >= 0) && (pBBLink[link]->abortFlag == 0)) - { - /* see if the queue has anything in it */ - semTake(pBBLink[link]->queue[prio].sem, WAIT_FOREVER); - - if ((pnode = pBBLink[link]->queue[prio].head) != NULL) - { - now = tickGet(); - while (pBBLink[link]->deviceStatus[pnode->txMsg.node] == BB_BUSY) - { - if ((pBBLink[link]->syntheticDelay[pnode->txMsg.node] != 0) - && (pBBLink[link]->syntheticDelay[pnode->txMsg.node] < now)) - { - if (bbDebug) - printf("xvmeTxTask(%d): terminating synthetic idle on node %d\n", link, pnode->txMsg.node); - (pBBLink[link]->deviceStatus[pnode->txMsg.node])--; - pBBLink[link]->syntheticDelay[pnode->txMsg.node] = 0; - pBBLink[link]-> DelayCount--; - } - else - { - if ((pnode = pnode->next) == NULL) - break; - } - } - } - if (pnode != NULL) - { /* have an xact to start processing */ - working = 1; /* indicate work being done */ - - /* delete the node from the inbound fifo queue */ - listDel(&(pBBLink[link]->queue[prio]), pnode); - - semGive(pBBLink[link]->queue[prio].sem); - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX); -#endif - if (bbDebug>3) - printf("xvmeTxTask(%d): got xact, pnode=%p\n", link, pnode); - - /* Send the message in polled mode */ - - txTCount = pnode->txMsg.length - 2; - txCCount = 0; - txMsg = &(pnode->txMsg.length); - - while ((txCCount <= txTCount) && (pBBLink[link]->abortFlag == 0)) - { - stuck = 1000; - while (((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_TFNF) != XVME_TFNF) && (pBBLink[link]->abortFlag == 0) && --stuck) - for(x=0;x<100;x++); /* wait for TX ready */ - - if (!stuck) - { -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_STUCK); -#endif - txStuck(link); /* will end up setting abortFlag */ - } - else if (txCCount < txTCount) /* on last time, just wait, no data */ - { - pBBLink[link]->l.XycomLink.bbRegs->data = *txMsg; /* send next byte */ - if (bbDebug>30) - printf("xvmeTxTask(%d): outputting %2.2X\n", link, *txMsg); - - /* On 5th byte, we are dun w/header, set start w/data buffer */ - if (txCCount != 4) - txMsg++; - else - txMsg = pnode->txMsg.data; - } - txCCount++; - } - - if (pBBLink[link]->abortFlag == 0) - { - - /* All data bytes have been sent, put on busy list and release */ - - /* Don't add to busy list if was a RAC_RESET_SLAVE */ - if ((pnode->txMsg.cmd == RAC_RESET_SLAVE) && (pnode->txMsg.tasks == 0)) - { /* Finish the transaction here if was a RAC_RESET_SLAVE */ -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_RESET); -#endif - if (bbDebug) - printf("xvmeTxTask(%d): RAC_RESET_SLAVE sent, resetting node %d\n", link, pnode->txMsg.node); - - pnode->status = BB_OK; - - if (pnode->finishProc != NULL) - { - if (bbDebug>4) - printf("xvmeTxTask(%d): invoking callbackRequest\n", link); - - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (pnode->psyncSem != NULL) - semGive(*(pnode->psyncSem)); - } - - /* Wait for last NODE_OFFLINE to finish (if still pending) */ - semTake(resetNodeSem, WAIT_FOREVER); - - /* have to reset the master so it won't wait on a response */ - resetNodeData = pnode->txMsg.node; /* mark the node number */ - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &resetNode); - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); - - /* taskDelay(15); */ /* wait while bug is resetting */ - } - else - { - /* Lock the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - - /* set the retire time */ - pnode->retire = tickGet(); - if (pnode->ageLimit) - pnode->retire += pnode->ageLimit; - else - pnode->retire += BB_DEFAULT_RETIRE_TIME * sysClkRateGet(); - - if (pBBLink[link]->busyList.head == NULL) - dogStart = 1; - else - dogStart = 0; - - /* Add pnode to the busy list */ - listAddTail(&(pBBLink[link]->busyList), pnode); - - /* Count the outstanding messages */ - (pBBLink[link]->deviceStatus[pnode->txMsg.node])++; - - semGive(pBBLink[link]->busyList.sem); - - /* If just added something to an empty busy list, start the dog */ - if (dogStart) - { - now = tickGet(); - wdStart(pBBLink[link]->watchDogId, pBBLink[link]->busyList.head->retire - now, xvmeTmoHandler, link); - } - } - - /* Tell the 8044 to fire out the message now */ - pBBLink[link]->l.XycomLink.bbRegs->cmnd = BB_SEND_CMD; /* forward it now */ - } - else - { /* Aborted transmission operation, re-queue the message */ - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), pnode); - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_ABORT); -#endif - if (bbDebug) - { - printf("Message in progress when abort issued:\n"); - drvBitBusDumpMsg(&pnode->txMsg); - } - } -/* BUG -- I don't really need this */ - /* break;*/ /* stop checking the fifo queues */ - } - else - { /* we have no xacts that can be processed at this time */ - semGive(pBBLink[link]->queue[prio].sem); - } - prio--; /* look at the next prio queue */ - } - } - } -} - -/****************************************************************************** - * - * This gets called by the transmit task if it gets stuck waiting to send a - * byte to the transmit fifo. - * - ******************************************************************************/ -STATIC int txStuck(int link) -{ - if (bbDebug) - printf("bitbus transmitter task stuck, resetting link %d\n", link); - - bbReset(link); - while (pBBLink[link]->abortFlag == 0) - taskDelay(1); - - return(OK); -} - -/****************************************************************************** - * - * This function is called by user programs to queue an I/O transaction request - * for the BB driver. It is the only user-callable function provided in this - * driver. - * - ******************************************************************************/ -STATIC long qBBReq(struct dpvtBitBusHead *pdpvt, int prio) -{ - static linkErrFlags[BB_NUM_LINKS]; /* Supposedly init'd to zero */ - char message[200]; - - if ((prio < 0) || (prio >= BB_NUM_PRIO)) - { - sprintf(message, "invalid priority requested in call to qbbreq(%p, %d)\n", pdpvt, prio); - errMessage(S_BB_badPrio, message); - return(ERROR); - } - if (checkLink(pdpvt->link) == ERROR) - { - if (pdpvt->link >= BB_NUM_LINKS) - { - sprintf(message, "qbbreq(%p, %d) %d\n", pdpvt, prio, pdpvt->link); - errMessage(S_BB_badlink, message); - } - else if (linkErrFlags[pdpvt->link] == 0) - { /* Anti-message swamping check */ - linkErrFlags[pdpvt->link] = 1; - sprintf(message, "qbbreq(%p, %d) %d... card not present\n", pdpvt, prio, pdpvt->link); - errMessage(S_BB_badlink, message); - } - return(ERROR); - } - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(pdpvt->link, pdpvt, XACT_HIST_STATE_QUEUE); -#endif - - if (bbDebug>5) - printf("qbbreq(%p, %d): transaction queued\n", pdpvt, prio); - if (bbDebug>6) - drvBitBusDumpMsg(&(pdpvt->txMsg)); - - semTake(pBBLink[pdpvt->link]->queue[prio].sem, WAIT_FOREVER); - - /* Add to the end of the queue of waiting transactions */ - listAddTail(&(pBBLink[pdpvt->link]->queue[prio]), pdpvt); - - semGive(pBBLink[pdpvt->link]->queue[prio].sem); - - semGive(pBBLink[pdpvt->link]->linkEventSem); - - return(OK); -} - - -/****************************************************************** - * - * Reset hook function... takes down ALL the bitbus links and leaves - * them down. - * - ******************************************************************/ -STATIC void BBrebootFunc(void) -{ - int i; - - for (i=0; inukeEm = 2; - semGive(pBBLink[link]->watchDogSem); - } - else - printf("Link %d not installed.\n", link); - - return(0); -} - - - /****************************************************************** - * - * Super debugging facility. - * - ******************************************************************/ -int -drvBitBusDumpMsg(struct bitBusMsg *pbbMsg) -{ - char ascBuf[15]; /* for ascii xlation part of the dump */ - int x; - int y; - int z; - - printf("Link 0x%4.4X, length 0x%2.2X, route 0x%2.2X, node 0x%2.2X, tasks 0x%2.2X, cmd %2.2X\n", pbbMsg->link, pbbMsg->length, pbbMsg->route, pbbMsg->node, pbbMsg->tasks, pbbMsg->cmd); - - x = BB_MSG_HEADER_SIZE; - y = pbbMsg->length; - z = 0; - - while (x < y) - { - printf("%2.2X ", pbbMsg->data[z]); - ascBuf[z] = pbbMsg->data[z]; - - if (!((ascBuf[z] >= 0x20) && (ascBuf[z] <= 0x7e))) - ascBuf[z] = '.'; - - x++; - z++; - } - - while (x < BB_MAX_MSG_LENGTH) - { - printf(" "); - x++; - } - - ascBuf[z] = '\0'; - printf(" *%s*\n", ascBuf); - return(OK); -} - -#ifdef BB_SUPER_DEBUG -/* - * Place an event into the history buffer. - */ -static int BBSetHistEvent(int link, struct dpvtBitBusHead *pXact, int State) -{ - semTake(pBBLink[link]->History.sem, WAIT_FOREVER); - - - pBBLink[link]->History.Num++; - - pBBLink[link]->History.Xact[pBBLink[link]->History.Next].Time = tickGet(); - pBBLink[link]->History.Xact[pBBLink[link]->History.Next].State = State; - if (pXact != NULL) - memcpy (&pBBLink[link]->History.Xact[pBBLink[link]->History.Next].Xact, pXact, sizeof(struct dpvtBitBusHead)); - - if (link==bbDebugLink && pBBLink[link]->History.Xact[pBBLink[link]->History.Next].Xact.txMsg.node==bbDebugNode) - BBDumpXactHistory(&pBBLink[link]->History.Xact[pBBLink[link]->History.Next]); - - if (++pBBLink[link]->History.Next == BB_SUPER_DEBUG_HIST_SIZ) - pBBLink[link]->History.Next = 0; - - semGive(pBBLink[link]->History.sem); - return(0); -} - -int BBHistDump(int link) -{ - int count; - int ix; - - if (checkLink(link) == ERROR) - { - printf(" Link %d is not valid\n", link); - return(-1); - } - printf("Dumping bitbus history for link %d\n", link); - semTake(pBBLink[link]->History.sem, WAIT_FOREVER); - - if (pBBLink[link]->History.Num < BB_SUPER_DEBUG_HIST_SIZ) - { - count = pBBLink[link]->History.Num; - ix = 0; - } - else - { - count = BB_SUPER_DEBUG_HIST_SIZ; - ix = pBBLink[link]->History.Next; - } - - while(count) - { - printf("%8.8d:", pBBLink[link]->History.Xact[ix].Time); - - if (BBDumpXactHistory(&pBBLink[link]->History.Xact[ix]) != 0) - count = 0; - else - --count; - - if (++ix >= BB_SUPER_DEBUG_HIST_SIZ) - ix = 0; - } - - semGive(pBBLink[link]->History.sem); - return(0); -} -STATIC int BBDumpXactHistory(XactHistStruct *pXact) -{ - switch (pXact->State) - { - /* No BB message present */ - case XACT_HIST_STATE_RESET: - printf("Link Reset:\n"); - break; - case XACT_HIST_STATE_RX_ABORT: - printf("Link RX aborted\n"); - break; - case XACT_HIST_STATE_TX_ABORT: - printf("Link TX aborted\n"); - break; - case XACT_HIST_STATE_RX_URCMD: - printf("Link RX got unexpected RCMD\n"); - break; - - /* TX message only */ - case XACT_HIST_STATE_QUEUE: - printf("Message Queued:\n"); - goto do_tx_only; - case XACT_HIST_STATE_TX: - printf("Message Transmitted:\n"); - goto do_tx_only; - case XACT_HIST_STATE_WD_TIMEOUT: - printf("Watchdog Timeout:\n"); - goto do_tx_only; - case XACT_HIST_STATE_TX_STUCK: - printf("Transmitter stuck:\n"); - goto do_tx_only; - case XACT_HIST_STATE_TX_RESET: - printf("TX just sent a RAC RESET:\n"); - - do_tx_only: - drvBitBusDumpMsg(&pXact->Xact.txMsg); - break; - - /* RX message only */ - case XACT_HIST_STATE_RX_UNSOLICITED: - printf("RX unsolicited message:\n"); - drvBitBusDumpMsg(&pXact->Xact.rxMsg); - break; - - /* TX and RX messages present */ - case XACT_HIST_STATE_RX: - printf("RX response... complete transaction:\n"); - drvBitBusDumpMsg(&pXact->Xact.txMsg); - drvBitBusDumpMsg(&pXact->Xact.rxMsg); - break; - - default: - printf("Corrupt bitbus debug state!\n"); - return(-1); - } - return(0); -} -#endif - -/****************************************************************************** - * - * A user callable function that may be used to reset the specified slave - * node. - * - * This routine is NOT reenterant but contains a monitor so that it always - * operates properly. - * - ******************************************************************************/ -int ResetBug(int node, int link) -{ - static int FirstTime = 1; - static SEM_ID monLock; - static SEM_ID syncSem; /* Semaphore to use for completion */ - struct dpvtBitBusHead resetNode; /* actual message to send out */ - unsigned char resetNodeData; /* 1-byte data field for RAC_RESET */ - - if (FirstTime) - { - monLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - FirstTime = 0; - } - - semTake(monLock, WAIT_FOREVER); - - resetNode.finishProc = NULL; /* no callback routine used */ - resetNode.psyncSem = &syncSem;/* do a semGive on this SEM when done sending */ - resetNode.link = link; /* which bitbus link to send message out on */ - resetNode.rxMaxLen = 7; /* Chop off the response... we don't care */ - resetNode.ageLimit = sysClkRateGet()*2; - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.node = node; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.cmd = RAC_RESET_SLAVE; - resetNode.txMsg.data = &resetNodeData; - - qBBReq(&resetNode, 0); - semTake(syncSem, WAIT_FOREVER); - semGive(monLock); - - return(0); -} - /****************************************************************** - * FUNCTION: pepRxTask() - * PURPOSE : This function is started as a task during driver init - * time. It's purpose is to read messages off the receive - * FIFO. After a complete message is read, the soliciting - * message's completion routines are started by the use - * of semaphores and/or a callbackRequest(). - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int -pepRxTask(int link) -{ - int rxState; /* current state of the receiver */ -#define BBRX_HEAD 1 -#define BBRX_DATA 2 -#define BBRX_RCMD 3 -#define BBRX_IGN 4 - - unsigned char rxHead[7]; /* room for header of current rx msg */ - unsigned char *rxMsg; /* where to place next byte (after header) */ - int rxTCount; /* byte counter for data in rxHead */ - unsigned char ch; - struct dpvtBitBusHead *rxDpvtHead; /* for message currently receiving */ - - struct dpvtBitBusHead UselessMsg; /* to hold unsolicited responses */ - unsigned char UselessData[BB_MAX_MSG_LENGTH]; - - int lockKey; /* used for intLock calls */ - int packageComplete; /* indicates end of package read */ - - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - packageComplete = 0; - - /* Dummy up the UselessMsg fields so we can use it */ - UselessMsg.rxMaxLen = BB_MAX_MSG_LENGTH; - UselessMsg.rxMsg.data = UselessData; - UselessMsg.link = link; - UselessMsg.ageLimit = 0; - UselessMsg.retire = 0; - - while (1) - { - /* Wait for RX interrupts, but only if no chars are ready */ - if ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_RFNE) == 0) - { - /* Enable interrupts and check again in case PB-BIT blew it */ - lockKey = intLock(); - pBBLink[link]->l.PepLink.bbRegs->int_vec = PEP_BB_IVEC_BASE +(link*2); - intUnlock(lockKey); - - while (((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_RFNE) == 0) - && (pBBLink[link]->abortFlag == 0)) - { - /* Re-enable ints here each time in case board got reset */ - lockKey = intLock(); - pBBLink[link]->l.PepLink.bbRegs->int_vec = PEP_BB_IVEC_BASE +(link*2); - intUnlock(lockKey); - - if (bbDebug>35) - printf("pepRxTask(%d): waiting on IRQ\n", link); - - /* wait for data bytes */ - semTake(pBBLink[link]->l.PepLink.rxInt, WAIT_FOREVER); - } - /* Disable RX Interrupts (prevents unnecessary context switching) */ - lockKey = intLock(); - pBBLink[link]->l.PepLink.bbRegs->int_vec = 0; - intUnlock(lockKey); - } - - if (pBBLink[link]->abortFlag == 0) - { - /* READ ONE CHAR FROM RECEIVE FIFO */ - ch = pBBLink[link]->l.PepLink.bbRegs->data; - - /* check to see if we got a data byte or a command byte */ - if ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_RCMD) == PEP_BB_RCMD) - packageComplete = 1; - - switch (rxState) { - case BBRX_HEAD: /* getting the head of a new message */ - if (rxTCount > 1) /* Toss the 2 PEP specific header bytes */ - rxHead[rxTCount] = ch; - if (bbDebug>21) - printf("pepRxTask(%d): >%2.2X< (Header)\n", link, ch); - - if (++rxTCount == 7) - { - /* find the message this is a reply to */ - /* rxTCount += 2; PEP header bytes already messed up the count (jrw)*/ - - /* Lock the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - - rxDpvtHead = pBBLink[link]->busyList.head; - while (rxDpvtHead != NULL) { - if (bbDebug>19) - printf("pepRxTask(%d): checking reply against %p\n", - link, rxDpvtHead); - - /* see if node's match */ - if (rxDpvtHead->txMsg.node == rxHead[4]) { - /* see if the tasks match */ - /* if (rxDpvtHead->txMsg.tasks == rxHead[5]) */ - { - /* They match, finish putting response into the rxMsg buffer */ - if (bbDebug>4) - printf("pepRxTask(%d): reply to %p\n", - link, rxDpvtHead); - - /* Delete the node from the list */ - listDel(&(pBBLink[link]->busyList), rxDpvtHead); - - /* If busy list is empty, stop the dog */ - if (pBBLink[link]->busyList.head == NULL) - wdCancel(pBBLink[link]->watchDogId); - - if (rxHead[6] == 0x91) - { /* something bad happened... inject a delay to the */ - /* requested timeout duration. */ - if (bbDebug) - printf("pepRxTask(%d): 0x91 from node %d, invoking synthetic delay\n", link, rxHead[4]); - (pBBLink[link]->syntheticDelay[rxDpvtHead->txMsg.node]) = rxDpvtHead->retire; - pBBLink[link]->DelayCount++; - } - else - { /* decrement the number of outstanding messages to the node */ - (pBBLink[link]->deviceStatus[rxDpvtHead->txMsg.node])--; - } - - /* Wake up Link Task in case was waiting on "this" node */ - semGive(pBBLink[link]->linkEventSem); -#if 0 - semGive(pXvmeLink[link]->pbbLink->busyList.sem); - - rxDpvtHead->rxMsg.length = rxHead[2]; - rxDpvtHead->rxMsg.route = rxHead[3]; - rxDpvtHead->rxMsg.node = rxHead[4]; - rxDpvtHead->rxMsg.tasks = rxHead[5]; - rxDpvtHead->rxMsg.cmd = rxHead[6]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ -#endif - break; /* get out of the while() */ - } - } - rxDpvtHead = rxDpvtHead->next; /* Keep looking */ - } - - semGive(pBBLink[link]->busyList.sem); - - /* Couldn't find a match... fake one so can print the bad message */ - if (rxDpvtHead == NULL) - rxDpvtHead = &UselessMsg; - - rxDpvtHead->rxMsg.length = rxHead[2]; - rxDpvtHead->rxMsg.route = rxHead[3]; - rxDpvtHead->rxMsg.node = rxHead[4]; - rxDpvtHead->rxMsg.tasks = rxHead[5]; - rxDpvtHead->rxMsg.cmd = rxHead[6]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ - } - break; - - case BBRX_DATA: /* finish reading data portion of message */ - if (rxTCount >= rxDpvtHead->rxMaxLen) { - rxState = BBRX_IGN; /* toss the rest of the data */ - rxDpvtHead->status = BB_LENGTH; /* set driver status */ - if (bbDebug>22) - printf("pepRxTask(%d): %2.2X (Ignored)\n", link, ch); - - } - else { - *rxMsg = ch; - if (bbDebug>22) - printf("pepRxTask(%d): %2.2X (Data)\n", link, ch); - rxMsg++; - rxTCount++; - } - break; - - case BBRX_IGN: - if (bbDebug>22) - printf("pepRxTask(%d): %2.2X (Ignored)\n", link, ch); - break; - } - - if (packageComplete) - { - if (rxDpvtHead == NULL) - { - if (bbDebug > 22) - printf("pepRxTask(%d): got unexpected completion status\n", link); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_RX_URCMD); -#endif - } - else if (rxDpvtHead == &UselessMsg) - { - rxDpvtHead->status = BB_OK; - if (bbDebug) - { - printf("pepRxTask(%d): msg from node %d unsolicited:\n", link, rxDpvtHead->rxMsg.node); - drvBitBusDumpMsg(&(rxDpvtHead->rxMsg)); - } -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX_UNSOLICITED); -#endif - } - else - { - rxDpvtHead->status = BB_OK; - if (bbDebug>24) - printf("pepRxTask(%d): RX command byte = %2.2X\n", link, ch); - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX); -#endif - - if (rxDpvtHead->finishProc != NULL) - { - if (bbDebug>8) - printf("pepRxTask(%d): invoking the callbackRequest\n", link); - callbackRequest(rxDpvtHead); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (rxDpvtHead->psyncSem != NULL) - semGive(*(rxDpvtHead->psyncSem)); - } - } - /* Reset the state of the RxTask to expect a new message */ - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - packageComplete = 0; - } - } - else - { - /* Link abort state is active reset receiver link status now */ - if (rxDpvtHead != NULL) - { - /* This xact is not on the busy list, put it back on */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - (pBBLink[link]->deviceStatus[rxDpvtHead->txMsg.node])++; - listAddTail(&(pBBLink[link]->busyList), rxDpvtHead); - semGive(pBBLink[link]->busyList.sem); - } -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX_ABORT); -#endif - - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - /* Tell the watch dog I am ready for the reset (reset in the dog task) */ - pBBLink[link]->rxAbortAck = 1; - - if (bbDebug) - printf("pepRxTask(%d): resetting due to abort status\n", link); - - /* wait for link state to become active again */ - while (pBBLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); - - if (bbDebug) - printf("pepRxTask(%d): restarting after abort\n", link); - } - } -} - -/****************************************************************** - * FUNCTION: pepWdTask() - * PURPOSE : - * - * ARGS IN : none - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int pepWdTask(int link) -{ - struct dpvtBitBusHead *pnode; - struct dpvtBitBusHead *npnode; - unsigned long now; - -#ifdef PEP_DO_RESET_AND_OFFLINE - SEM_ID syncSem; - - struct dpvtBitBusHead resetNode; - unsigned char resetNodeData; /* 1-byte data field for RAC_RESET */ - unsigned char responseData; - - struct dpvtBitBusHead offlnNode; - unsigned char offlnNodeData; /* 1-byte data field for RAC_OFFLN */ - unsigned char response1Data; /* 1-byte response data field */ - - /* init the SEM used when sending the RAC_OFFLNE message */ - syncSem = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY); - - /* - * Hand-craft a RAC_RESET and RAC_OFFLINE message to use when - * a message times out. - * NOTE that having only one copy is OK provided that the dog waits for - * a response before sending it again! - */ - resetNode.finishProc = NULL; /* no callback routine used */ - resetNode.psyncSem = NULL; - resetNode.link = link; /* which bitbus link to send message out on */ - resetNode.rxMaxLen = 10; - resetNode.ageLimit = sysClkRateGet()*100; /* make sure this never times out */ - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.data = &resetNodeData; - resetNode.rxMsg.data = &responseData; - - offlnNode.finishProc = NULL; /* no callback routine used */ - offlnNode.psyncSem = &syncSem;/* do a semGive on this SEM when responded to*/ - offlnNode.link = link; /* which bitbus link to send message out on */ - offlnNode.rxMaxLen = 10; - offlnNode.ageLimit = sysClkRateGet()*100; /* make sure this never times out */ - - offlnNode.txMsg.length = 8; - offlnNode.txMsg.route = BB_STANDARD_TX_ROUTE; - offlnNode.txMsg.tasks = 0x0; - offlnNode.txMsg.data = &offlnNodeData; - offlnNode.rxMsg.data = &response1Data; -#endif - - pBBLink[link]->nukeEm = 0; /* Make sure the nuke status is clear */ - while(1) { - /* SLEEP UNTIL WATCHDOG TIMER ROUTINE GIVES SEMAPHORE */ - semTake(pBBLink[link]->watchDogSem, WAIT_FOREVER); - now = tickGet(); /* what time is it? */ - - if (pBBLink[link]->nukeEm != 0) - printf("Bitbus manual reset being issued on link %d\n", link); - - if (bbDebug>4) - printf("pepWdTask(%d): (Watchdog) checking busy list\n", link); - - pBBLink[link]->rxAbortAck = 0; - pBBLink[link]->txAbortAck = 0; - - if (pBBLink[link]->nukeEm != 0) { - /* set abort status and wait for the abort acks */ - pBBLink[link]->abortFlag = 1; - - /* wake up the Tx task so it can observe the abort status */ - semGive(pBBLink[link]->linkEventSem); - - /* wake up the Rx task so it can observe the abort status */ - semGive(pBBLink[link]->l.PepLink.rxInt); - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pBBLink[link]->rxAbortAck == 0) && - (pBBLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - -#ifdef BB_SUPER_DEBUG - if (pBBLink[link]->nukeEm < 2) - { /* Do a history dump since this is not supposed to happen */ - BBHistDump(link); - } -#endif - } - /* - * Run thru entire busy list to see if there are any transactions - * that have been waiting on a response for too long a period. - */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - pnode = pBBLink[link]->busyList.head; - - while (pnode != NULL) { - npnode = pnode->next; /* remember where we were in the list */ - - if ((pBBLink[link]->nukeEm != 0) || (pnode->retire <= now)) { - /* Get rid of the request and set error status etc... */ - listDel(&(pBBLink[link]->busyList), pnode); - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_WD_TIMEOUT); -#endif - if (bbDebug) - { - printf("pepWdTask(%d): TIMEOUT on bitbus message:\n", link); - drvBitBusDumpMsg(&pnode->txMsg); - } - - /* BUG -- do this here or defer until RX gets a response? */ - (pBBLink[link]->deviceStatus[pnode->txMsg.node])--; /* fix device status */ - pnode->status = BB_TIMEOUT; - -#ifdef PEP_DO_RESET_AND_OFFLINE - /* Gotta do this now in case we need the info after the completion */ - resetNode.txMsg.node = pnode->txMsg.node; - offlnNodeData = pnode->txMsg.node; /* mark the node number */ -#endif - /* Make the callbackRequest if one was spec'd */ - if(pnode->finishProc != NULL) - { - if (bbDebug>2) - { - printf("pepWdTask(%d): invoking the callbackRequest %p %d\n", link, pnode->finishProc, pnode->priority); - } - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* Release a completion lock if one was spec'd */ - if (pnode->psyncSem != NULL && pBBLink[link]->nukeEm == 0) - semGive(*(pnode->psyncSem)); - } - -#ifdef PEP_DO_RESET_AND_OFFLINE - /* If we are not going to reboot the link... */ - if ( pBBLink[link]->nukeEm == 0 ) { - /* Send out a RAC_RESET/RAC_OFFLINE pair */ - semGive(pBBLink[link]->busyList.sem); - - /* Configure message for a RAC_RESET */ - resetNode.txMsg.cmd = 0x00; - - /* Configure message for a RAC_OFFLINE */ - offlnNode.txMsg.cmd = RAC_OFFLINE; - offlnNode.txMsg.node = 0xff; - - /* Queue the messages (high priority, reset first) */ - - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &offlnNode); -/* listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &resetNode); */ - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); - - semGive(pBBLink[link]->linkEventSem); /* Tell TxTask to send the messages */ - - if (semTake(syncSem, (sysClkRateGet()) ) == ERROR) - { - if (bbDebug) - printf("pepWdTask(%d): link dead, trying manual reboot\n", link); - - pBBLink[link]->nukeEm = 1; - pBBLink[link]->abortFlag = 1; - semGive(pBBLink[link]->linkEventSem); - semGive(pBBLink[link]->rxInt); - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pBBLink[link]->rxAbortAck == 0) && - (pBBLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - } - - /* Start over since released the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - npnode = pBBLink[link]->busyList.head; - } -#endif - - } - pnode = npnode; - } - - /* Finish the link reboot if necessary */ - if (pBBLink[link]->nukeEm != 0) - { - /* shut down the bitbus card. */ - pepReset(link); - - if (pBBLink[link]->nukeEm == 2) - { - /* - * Stop the watchdog task so the link stays dead. - * Since the busy list is locked and the nukeEm flag is still set, - * this link can not do any more work. - */ - abort(); - } - - /* clear the abort_flag */ - pBBLink[link]->abortFlag = 0; - - pBBLink[link]->nukeEm = 0; - } - - if (pBBLink[link]->busyList.head != NULL) { - /* Restart the dog timer */ - if (bbDebug>5) - printf("pepWdTask(%d): restarting watch dog timer\n", link); - - wdStart(pBBLink[link]->watchDogId, pBBLink[link]->busyList.head->retire - now, - pepTmoHandler, link); - } - - semGive(pBBLink[link]->busyList.sem); - - /* In case the TX is waiting on a node that just timed out */ - semGive(pBBLink[link]->linkEventSem); - } -} - -/****************************************************************** - * FUNCTION: pepTxTask() - * PURPOSE : This function is started as a task during driver init - * time. It's purpose is to keep the link busy with - * outgoing messages. It awaits user-calls to qBBReq() - * (new message to send). It also awaits wake up calls - * from the Wd timer (a timed out message to a node, - * once handled, means Tx is free to send again to that - * node). - * - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int pepTxTask(int link) -{ - struct dpvtBitBusHead *pnode; - int prio; - int working; - int dogStart; - int stuck; - - int txTCount; - int txCCount; - unsigned char *txMsg; - register int x; - unsigned long now; - - if (bbDebug>1) - printf("pepTxTask started for link %d\n", link); - - while(1) { - if (pBBLink[link]->abortFlag != 0) { - /* let the dog know we are ready */ - pBBLink[link]->txAbortAck = 1; - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_TX_ABORT); -#endif - - if (bbDebug) - printf("pepTxTask(%d): resetting due to abort status\n", link); - - while (pBBLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); /* wait for link to reset */ - - if (bbDebug) - printf("pepTxTask(%d): restarting after abort\n", link); - } - else - { - if (pBBLink[link]->DelayCount) - semTake(pBBLink[link]->linkEventSem, 2 * sysClkRateGet()); - else - semTake(pBBLink[link]->linkEventSem, WAIT_FOREVER); - } - - if (bbDebug>5) - printf("pepTxTask(%d): got an event\n", link); - - working = 1; - while ((working != 0) && (pBBLink[link]->abortFlag == 0)) { - working = 0; - - prio = BB_NUM_PRIO-1; - while ((prio >= 0) && (pBBLink[link]->abortFlag == 0)) { - /* see if the queue has anything in it */ - semTake(pBBLink[link]->queue[prio].sem, WAIT_FOREVER); - - if ((pnode = pBBLink[link]->queue[prio].head) != NULL) - { - now = tickGet(); - while (pBBLink[link]->deviceStatus[pnode->txMsg.node] == BB_BUSY) - { - if ((pBBLink[link]->syntheticDelay[pnode->txMsg.node] != 0) - && (pBBLink[link]->syntheticDelay[pnode->txMsg.node] < now)) - { - if (bbDebug) - printf("pepTxTask(%d): terminating synthetic idle on node %d\n", link, pnode->txMsg.node); - (pBBLink[link]->deviceStatus[pnode->txMsg.node])--; - pBBLink[link]->syntheticDelay[pnode->txMsg.node] = 0; - pBBLink[link]->DelayCount--; - } - else - { - if ((pnode = pnode->next) == NULL) - break; - } - } - } - - if (pnode != NULL) { /* have an xact to start processing */ - working = 1; - - /* delete the node from the inbound fifo queue */ - listDel(&(pBBLink[link]->queue[prio]), pnode); - - semGive(pBBLink[link]->queue[prio].sem); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX); -#endif - - - if (bbDebug>3) - printf("pepTxTask(%d): got xact, pnode=%p\n", link, pnode); - - /* Send the message in polled mode */ - txTCount = pnode->txMsg.length; - - /* BUG -- would be nice if we verify the length >6 here */ - - txCCount = 0; - txMsg = &(pnode->txMsg.length); - - while ((txCCount < txTCount -1) && (pBBLink[link]->abortFlag == 0)) { - - stuck = 1000; - while (((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_TFNF) - != PEP_BB_TFNF) && - (pBBLink[link]->abortFlag == 0) && - --stuck) - for(x=0;x<100;x++); /* wait for TX ready */ - - if (!stuck) - { -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_STUCK); -#endif - txStuck(link); - } - else if (txCCount == 0) { /* first byte is package type */ - if (bbDebug>30) - printf("pepTxTask(%d): outputting %2.2X\n",link,0x81); - pBBLink[link]->l.PepLink.bbRegs->data = 0x81; - } - else if (txCCount == 1) { /* unused 2nd byte of package */ - if (bbDebug>30) - printf("pepTxTask(%d): outputting %2.2X\n",link,0x00); - pBBLink[link]->l.PepLink.bbRegs->data = 0x00; -#if 0 - } else if (txCCount == (txTCount -1)) { /* last byte of package */ - pBBLink[link]->l.PepLink.bbRegs->stat_ctl = *txMsg; - if (bbDebug>30) - printf("pepTxTask(%d): outputting last byte %2.2X\n", - link,*txMsg); -#endif - } else { /* regular ol' message byte */ - pBBLink[link]->l.PepLink.bbRegs->data = *txMsg; - if (bbDebug>30) - printf("pepTxTask(%d): outputting %2.2X\n",link,*txMsg); - if (txCCount != 6) - txMsg++; - else - txMsg = pnode->txMsg.data; - } - txCCount++; - } - - if (pBBLink[link]->abortFlag == 0) { - - /* don't add to busy list if was a RAC_RESET_SLAVE */ - if ((pnode->txMsg.cmd == RAC_RESET_SLAVE) && (pnode->txMsg.tasks == 0)) - { -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_RESET); -#endif - if (bbDebug) - printf("pepTxTask(%d): RAC_RESET_SLAVE sent\n", link); - - pnode->status = BB_OK; - - if (pnode->finishProc != NULL) { - if (bbDebug>4) - printf("pepTxTask(%d): invoking the callbackRequest\n", - link); - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (pnode->psyncSem != NULL) - semGive(*(pnode->psyncSem)); - } - taskDelay(15); - } - else - { - /* Lock the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - - pBBLink[link]->l.PepLink.bbRegs->stat_ctl = *txMsg; - if (bbDebug>30) - printf("pepTxTask(%d): outputting last byte %2.2X\n", - link,*txMsg); - - /* set the retire time */ - pnode->retire = tickGet(); - if (pnode->ageLimit) - pnode->retire += pnode->ageLimit; - else - pnode->retire += BB_DEFAULT_RETIRE_TIME * sysClkRateGet(); - - if (pBBLink[link]->busyList.head == NULL) - dogStart = 1; - else - dogStart = 0; - - /* Add pnode to the busy list */ - listAddTail(&(pBBLink[link]->busyList), pnode); - - /* Count the outstanding messages */ - (pBBLink[link]->deviceStatus[pnode->txMsg.node])++; - - semGive(pBBLink[link]->busyList.sem); - - /* If something just added to empty busy list, start the dog */ - if (dogStart) { - now = tickGet(); - wdStart(pBBLink[link]->watchDogId, - pBBLink[link]->busyList.head->retire - now, - pepTmoHandler, link); - } - } - } else { /* if abortFlag != 0 */ - /* Aborted transmission operation, re-queue the message */ - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), pnode); - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_ABORT); -#endif - } - - } else { /* if pnode == NULL */ - /* we have no xacts that can be processed at this time */ - semGive(pBBLink[link]->queue[prio].sem); - } - prio--; /* look at the next prio queue */ - } - } - } -} - /****************************************************************** - * FUNCTION: dumpStat() - * PURPOSE : Temporary function. Shows contents of status - * register on PB-BIT module corresponding to link. - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -int pepDumpStat(int link) -{ - unsigned char stat_ctl; - - stat_ctl = pBBLink[link]->l.PepLink.bbRegs->stat_ctl; - - printf("stat_ctl reg: %2X\n",stat_ctl); - return(OK); -} diff --git a/src/drv/drvBitBus.h b/src/drv/drvBitBus.h deleted file mode 100644 index ab5bc100f..000000000 --- a/src/drv/drvBitBus.h +++ /dev/null @@ -1,303 +0,0 @@ -#ifndef EPICS_DRVBITBUS_H -#define EPICS_DRVBITBUS_H - -/* #define BB_SUPER_DEBUG */ - -/* - * Author: John Winans - * Date: 09-10-91 - * BitBus driver - * - * 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 09-30-91 jrw Written - * .02 12-10-91 jrw moved some stuff over to drvBitBusInterface.h - * .03 07-01-94 jrw Bigtime hacking... merged PEP and Xycom. - * - * $Log$ - * Revision 1.8 1994/10/04 18:42:44 winans - * Added an extensive debugging facility. - * - * - */ - -/***************************************************************************** - * - * This history stuff below is used to save the recent history of operation. - * This history includes dumps of messages that are queued, transmitted and - * received. This information is saved along with the relative tick time. - * - *****************************************************************************/ -#ifdef BB_SUPER_DEBUG -#define BB_SUPER_DEBUG_HIST_SIZ 50 /* How many messages to save */ - -typedef struct XactHistStruct -{ - struct dpvtBitBusHead Xact; /* BB message operated on */ - unsigned long Time; /* getTick() when operated on */ - int State; /* What was being done to the message */ -} XactHistStruct; - -#define XACT_HIST_STATE_QUEUE 0 /* Some task queued a transaction */ -#define XACT_HIST_STATE_TX 1 /* Transmitter sent a transaction */ -#define XACT_HIST_STATE_RX 2 /* Receiver received a response */ -#define XACT_HIST_STATE_WD_TIMEOUT 3 /* Watchdog times out a transaction */ -#define XACT_HIST_STATE_RESET 4 /* No message... link was reset */ -#define XACT_HIST_STATE_RX_UNSOLICITED 5 /* RX'd message not solicited */ -#define XACT_HIST_STATE_RX_ABORT 6 /* RX task got a link about status */ -#define XACT_HIST_STATE_TX_ABORT 7 /* TX task got a link about status */ -#define XACT_HIST_STATE_RX_URCMD 8 /* RX task got unsolicited RCMD */ -#define XACT_HIST_STATE_TX_RESET 9 /* TX task got a link about status */ -#define XACT_HIST_STATE_TX_STUCK 10 /* TX fifo is stuck on the 8044 */ - -/* One of these is allocated for each bitbus link */ -typedef struct HistoryStruct -{ - SEM_ID sem; /* Use when 'making' history */ - XactHistStruct Xact[BB_SUPER_DEBUG_HIST_SIZ]; - int Next; /* Next history slot to use */ - unsigned long Num; /* Total history messages */ -} HistoryStruct; - -static int BBSetHistEvent(int link, struct dpvtBitBusHead *pXact, int State); -#endif - - -/****************************************************************************** - * - * The BUSY/IDLE notion is used to count the number of outstanding - * messages for a specific node. The idea is that up to BUSY messages - * can be sent to a node before waiting before deciding not to send any more. - * According to the BitBus specs, this value is 7. However, it also - * states that responses can come back out of order. If this is even true - * for messages sent to the SAME TASK ON THE SAME NODE, the received messages - * CAN NOT be routed back to their initiators properly. Because the node# - * and task# is all we have to identify what a response message is for, - * I am limiting the per-node maximum to 1. - * - ******************************************************************************/ - -#define BB_BUSY 1 /* deviceStatus value if device is currently busy */ -#define BB_IDLE 0 /* deviceStatus value if device is currently idle */ - -/****************************************************************************** - * - * This list structure is used in the bitbus driver to represent its queues. - * - ******************************************************************************/ -struct bbList { - struct dpvtBitBusHead *head; /* head of the linked list */ - struct dpvtBitBusHead *tail; /* tail of the linked list */ - int elements; /* holds number of elements on the list */ - SEM_ID sem; /* semaphore for the queue list */ -}; - /***************************************************************************** - * Memory Map of XVME-402 BITBUS CARD - * - * This board is rather stupid in that it wastes a whole Kilo of space - * for its 5 1-byte regs. So the dm* fields in the structure below are - * for those filler locations. - * - *****************************************************************************/ -typedef struct XycomBBRegsStruct { - unsigned char dm0; - unsigned char stat_ctl; - unsigned char dm2; - unsigned char int_vec; - unsigned char dm4; - unsigned char data; - unsigned char dm6; - unsigned char cmnd; - unsigned char dm8; - unsigned char fifo_stat; - unsigned char dmA[1014]; /* Board occupies 1024 bytes in memory*/ -} XycomBBRegsStruct; - -#define XYCOM_BB_MAX_OUTSTAND_MSGS 4 /* per-link max pending messages */ -#define RESET_POLL_TIME 10 /* time to sleep when waiting on a link abort */ - -#define BB_SEND_CMD 0x0 /* command to initiate sending of msg */ - -#define XVME_ENABLE_INT 0x08 /* Allow xvme interupts */ - -#define XVME_TX_INT 0x20 /* int enable TX only */ -#define XVME_TX_PEND 0x10 /* transmit interrupt currently pending */ - -#define XVME_RX_INT 0x80 /* int exable RX only */ -#define XVME_RX_PEND 0x40 /* receive interrupt currently pending */ - -#define XVME_NO_INT 0 /* disable all interrupts */ - -/****************************************************************************** - * - * Fifo status register format for Xycom board - * - * +----+----+----+----+----+----+----+----+ - * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bits - * +----+----+----+----+----+----+----+----+ - * "1" "1" RCMD RFNE "1" "1" "1" TFNF data - * - * RCMD = "1"= command received ( end of message ) - * "0"= No command - * - * RFNE = "1" = Receive Fifo Not Empty - * "0" = Receive Fifo empty - * - * TFNF = "1" = Transmit Fifo Not Full - * "0" = transmit fifo full - * - * NOTE: - * A write to bit 7 of the Fifo status register can be used to reset the - * xvme board. - * - *****************************************************************************/ -#define XVME_RCMD 0x20 /* Command has been received */ -#define XVME_RFNE 0x10 /* Receive Fifo is Not Empty */ -#define XVME_TFNF 0x01 /* Transmit FIFO is Not Full */ -#define XVME_FSVALID 0x31 /* these are the only valid status bits */ -#define XVME_FSIDLE 0x01 /* fifo_stat & FSVALID = 0x1 when it is idle */ -#define XVME_RESET 0x80 /* Write this and you reset the XVME card */ - -/****************************************************************************** - * - * The XycomBBLinkStruct structure holds all the xvme-card specific data - * required for the operation of the link. - * - ******************************************************************************/ -typedef struct XycomBBLinkStruct { - volatile XycomBBRegsStruct *bbRegs;/* pointer to board registers */ - SEM_ID rxInt; /* given when rx interrupts occur */ -} XycomBBLinkStruct; - - /**************************************************************************** - * Memory Map of PEP Modular PB-BIT BITBUS CARD - * - * This board is rather stupid in that it wastes a bunch of bytes - * for its regs. So the dm* fields in the structure below are - * for those filler locations. - * - ***************************************************************************/ -typedef struct PepBBRegsStruct { - unsigned char dm0; - unsigned char data; - unsigned char dm2; - unsigned char stat_ctl; - unsigned char dm[29]; - unsigned char int_vec; -} PepBBRegsStruct; - -/****************************************************************************** - * - * status register format for PEP's PB-BIT board - * - * +----+----+----+----+----+----+----+----+ - * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bits - * +----+----+----+----+----+----+----+----+ - * X X X STF LBP TFF RFNE IRQP - * - * STF = "1"= self-test failed - * "0"= passed - * - * LBP = "1"= last data byte was last of package - * "0"= 1+ bytes left - * - * TFF = "1"= only one more byte may be written to TFIFO - * "0"= 1+ more bytes may be written - * - * RFNE = "1"= Receive Fifo Not Empty - * "0"= Receive Fifo empty - * - * IRQP = "1"= no irq pending - * "0"= irq pending - * - * - *****************************************************************************/ -#define PEP_BB_RCMD 0x08 /* Command has been received */ -#define PEP_BB_RFNE 0x02 /* Receive Fifo is Not Empty */ -#define PEP_BB_TFNF 0x04 /* Transmit FIFO is Not Full */ -#define PEP_BB_FSVALID 0x1f /* these are the only valid status bits */ - -/****************************************************************************** - * - * The PepBBLinkStruct structure holds all the card specific data required for - * the operation of the link. - * - ******************************************************************************/ -typedef struct PepBBLinkStruct { - - volatile PepBBRegsStruct *bbRegs; /* pointer to board registers */ - SEM_ID rxInt; /* given when rx interrupts occur */ - -} PepBBLinkStruct; - /***************************************************************************** - * - * Holds the user-configured board addresses etc. These MUST be set before - * the driver is initialized. And may not be changed after the init phase. - * - * NOTE: - * The setting of these items is intended to be done via records in the future. - * - * The busyList.sem is used to lock the busyList as well as the deviceStatus - * table. - * - *****************************************************************************/ -typedef struct BitbusLinkStruct -{ - unsigned long LinkType; /* Type of link (XYCOM, PEP,...) */ - unsigned long BaseAddr; /* Base address within A16 */ - unsigned long IrqVector; /* Irq vector base */ - unsigned long IrqLevel; /* Irq level */ - - WDOG_ID watchDogId; /* watchdog for timeouts */ - SEM_ID watchDogSem; /* set by the watch dog int handler */ - - unsigned char abortFlag; /* set to 1 if link is being reset by the dog */ - unsigned char txAbortAck; /* set to 1 by txTask to ack abort Sequence */ - unsigned char rxAbortAck; /* set to 1 by rxTask to ack abort Sequence */ - - int nukeEm; /* manual link restart flag */ - SEM_ID linkEventSem; /* given when this link requires service */ - struct bbList queue[BB_NUM_PRIO]; /* prioritized request queues */ - struct bbList busyList; /* messages waiting on a response */ - unsigned char deviceStatus[BB_APERLINK];/* mark a device as idle or busy */ - unsigned long syntheticDelay[BB_APERLINK]; /* holds the wakeup time for 91-delays */ - int DelayCount; /* holds total number of syntheticDelays in progress */ - - union - { - PepBBLinkStruct PepLink; - XycomBBLinkStruct XycomLink; - } l; - -#ifdef BB_SUPER_DEBUG - HistoryStruct History; -#endif - -} BitbusLinkStruct; - -#define BB_CONF_HOSED 0 /* Link is not present */ -#define BB_CONF_TYPE_XYCOM 1 /* Link is a Xycom board */ -#define BB_CONF_TYPE_PEP 2 /* Link is a PEP board */ - -#endif diff --git a/src/drv/drvCaenV265.c b/src/drv/drvCaenV265.c deleted file mode 100644 index ed42f1f3b..000000000 --- a/src/drv/drvCaenV265.c +++ /dev/null @@ -1,807 +0,0 @@ -/* share/src/drv @(#)drvCaenV265.c 1.1 9/2/94 */ -/* drvCaenV265.c - Driver/Device Support Routines for CAEN V265 - * - * Author: Jeff Hill (johill@lanl.gov) - * Date: 8-11-94 - * - * 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 - * MIT Bates Lab - * - * Modification Log: - * ----------------- - */ - -/* - * ANSI C Includes - */ -#include -#include -#include -#include - -/* - * vxWorks includes - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * EPICS include - */ -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * base address, base interrupt vector, - * number of cards, & interrupt level - */ -#define CAIN_V265_A24_BASE (0x000000) -#define CAIN_V265_INTVEC_BASE (0xA0) -#define CAIN_V265_MAX_CARD_COUNT (8) -#define CAIN_V265_INT_LEVEL (6) - - - - -/* - * all device registers declared - * ANSI C volatile so we dont need to - * use the -fvolatile flag (and dont - * limit the optimizer) - */ -typedef volatile int16_t devReg; - -struct caenV265 { - devReg csr; - devReg clear; - devReg DAC; - devReg gate; - const devReg data; - const devReg pad1[(0xf8-0x8)/2]; - const devReg fixed; - const devReg identifier; - const devReg version; -}; -#define CAENV265ID 0x0812 - -/* - * Insert or extract a bit field using the standard - * masks and shifts defined below - */ -#ifdef __STDC__ -#define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S)) -#define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M)) -#else /*__STDC__*/ -#define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S)) -#define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M)) -#endif /*__STDC__*/ - -/* - * in the constants below _M is a right justified mask - * and _S is a shift required to right justify the field - */ - -/* - * csr register - */ -#define FD_FULL_M (0x1) -#define FD_FULL_S (14) -#define FD_READY_M (0x1) -#define FD_READY_S (15) -#define FD_BUSY_FULL_M (0x3) -#define FD_BUSY_FULL_S (14) -#define FD_IVEC_M (0xff) -#define FD_IVEC_S (0) -#define FD_ILEVEL_M (0x7) -#define FD_ILEVEL_S (8) - -/* - * series/version register - */ -#define FD_SERIES_M (0xfff) -#define FD_SERIES_S (0) -#define FD_VERSION_M (0xf) -#define FD_VERSION_S (12) - -/* - * data register - */ -#define FD_CHANNEL_M (0x7) -#define FD_CHANNEL_S (13) -#define FD_RANGE_M (1) -#define FD_RANGE_S (12) -#define FD_DATA_M (0xfff) -#define FD_DATA_S (0) - -struct channel{ - int16_t signal; - char newData; -}; - -enum adc_range {adc_12, adc_15, NUMBER_OF_ADC_RANGES}; -#define NUMBER_OF_SIGNALS 8 -#define NUMBER_OF_FIFO_ENTRIES (16*NUMBER_OF_SIGNALS*NUMBER_OF_ADC_RANGES) -LOCAL struct caenV265Config{ - struct caenV265 *pCaenV265; /* pointer to the card */ - struct channel chan[NUMBER_OF_SIGNALS][NUMBER_OF_ADC_RANGES]; - IOSCANPVT scanpvt; - WDOG_ID wdid; -}caenV265Info[CAIN_V265_MAX_CARD_COUNT]; - -#ifdef __STDC__ -#define SHOW_OFFSET(STRUCT,FIELD) \ -printf( "%s.%s is at 0x%X\n", \ - #STRUCT, \ - #FIELD, \ - offsetof(struct STRUCT, FIELD)) -#endif - -LOCAL void caenV265ISR(unsigned card); -LOCAL int caenV265Shutdown(void); -LOCAL int caenV265IdTest(struct caenV265 *pCaenV265); -int caenV265Test(unsigned card); -LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config); -LOCAL int caenV265TestVal(unsigned card, unsigned dacVal); -LOCAL int caenV265IntEnable(unsigned card); - -/* - * device support entry table - */ -LOCAL long caenV265InitRecord(struct aiRecord *pai); -LOCAL long caenV265AiRead(struct aiRecord *pai); -LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after); -LOCAL long caenV265GetIoIntInfo(int cmd, struct aiRecord *pai, IOSCANPVT *ppvt); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} devCaenV265 ={ - 6, - NULL, - NULL, - caenV265InitRecord, - caenV265GetIoIntInfo, - caenV265AiRead, - caenV265SpecialLinconv}; - -/* - * driver support entry table - */ -LOCAL long caenV265Init(void); -LOCAL long caenV265IOReport(int level); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvCaenV265 ={ - 2, - caenV265IOReport, - caenV265Init}; - - - -/* - * verify that register - * offsets match the doc. - */ -#ifdef DEBUG -void offsettest() -{ - SHOW_OFFSET(caenV265, version); - SHOW_OFFSET(caenV265, identifier); - SHOW_OFFSET(caenV265, fixed); - SHOW_OFFSET(caenV265, data); - SHOW_OFFSET(caenV265, gate); - SHOW_OFFSET(caenV265, DAC); - SHOW_OFFSET(caenV265, clear); - SHOW_OFFSET(caenV265, csr); - - return; -} -#endif - - -/* - * caenV265InitRecord() - */ -LOCAL long caenV265InitRecord(struct aiRecord *pai) -{ - struct vmeio *pvmeio; - - /* ai.inp must be an VME_IO */ - switch (pai->inp.type) { - case (VME_IO): - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiXy566Se (init_record) Illegal INP field"); - return(S_db_badField); - } - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad signal or card number - */ - if ( pvmeio->signal >= NUMBER_OF_SIGNALS || - pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 bad card or signal number"); - return -1; - } - - if(!caenV265Info[pvmeio->card].pCaenV265){ - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 card does not exist"); - return -1; - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M; - - return(0); -} - - -/* - * caenV265AiRead() - */ -LOCAL long caenV265AiRead(struct aiRecord *pai) -{ - int16_t value; - struct vmeio *pvmeio; - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad signal or card number - */ - if ( pvmeio->signal >= NUMBER_OF_SIGNALS || - pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - - recGblSetSevr(pai, READ_ALARM, INVALID_ALARM); - return -1; - } - - /* - * uninitialized data? - */ - if (!caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].newData) { - recGblSetSevr(pai, READ_ALARM, INVALID_ALARM); - return -1; - } - - value = caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].signal; - pai->rval = value; - - return 0; -} - - -/* - * caenV265SpecialLinconv() - */ -LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after) -{ - if(!after) { - return 0; - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M; - return 0; -} - - -/* - * caenV265GetIoIntInfo() - */ -LOCAL long caenV265GetIoIntInfo( -int cmd, -struct aiRecord *pai, -IOSCANPVT *ppvt) -{ - struct vmeio *pvmeio; - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad card number - */ - if ( pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - logMsg( - "%s.%d:devCaenV265 bad card number %d %s\n", - (int)__FILE__, - __LINE__, - pvmeio->card, - (int)pai->name,0,0); - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 bad card number"); - return -1; - } - - *ppvt = &caenV265Info[pvmeio->card].scanpvt; - - return 0; -} - - -/* - * caenV265Init() - */ -LOCAL long caenV265Init(void) -{ - unsigned card; - struct caenV265 *pCaenV265; - int status; - - status = rebootHookAdd(caenV265Shutdown); - if(status){ - errMessage(S_dev_internal,"reboot hook add failed"); - return ERROR; - } - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - CAIN_V265_A24_BASE, - (char **)&pCaenV265); - if(status!=OK){ - errPrintf( - S_dev_badA24, - __FILE__, - __LINE__, - "caenV265Init"); - return ERROR; - } - - for(card=0; cardclear = 0; /* any rw op resets the device */ - pCaenV265->DAC = 0; /* set test-signal "offset" to zero */ - - /* - * attach ISR - */ - vec = CAIN_V265_INTVEC_BASE+card; - status = intConnect( - INUM_TO_IVEC(vec), - caenV265ISR, - card); - assert(status>=0); - - /* - * Enable interrupts - */ - caenV265IntEnable(card); - } - status = sysIntEnable(CAIN_V265_INT_LEVEL); - assert(status>=0); - - return OK; -} - - -/* - * caenV265ISR() - */ -LOCAL void caenV265ISR(unsigned card) -{ - struct caenV265Config *pCaenV256Config = &caenV265Info[card]; - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - unsigned signal; - int16_t csr; - static unsigned ticks; - unsigned newTicks; - - /* - * If its full then its more efficient - * to read it out without checking - * in between each read - */ - csr = pCaenV265->csr; - if (EXTRACT(FULL,csr)) { - for( signal=0; - signalcsr; - } - - /* - * limit the EPICS scan rate - */ - newTicks = tickGet(); - if(newTicks == ticks){ - /* - * Disable Interrupts - */ - pCaenV265->csr = 0; - - /* - * start a watch dog after one tick - * so that we limit the int rate to - * the system tick rate. - */ - wdStart(pCaenV256Config->wdid, - 1, - caenV265IntEnable, - card); - - return; - } - else{ - ticks = newTicks; - } - - /* - * tell EPICS to scan on int - */ - scanIoRequest(&caenV265Info[card].scanpvt); - - return; -} - - -/* - * caenV265IntEnable - */ -LOCAL int caenV265IntEnable(unsigned card) -{ - struct caenV265Config *pCaenV256Config = &caenV265Info[card]; - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - unsigned vec; - int16_t newcsr; - - - vec = CAIN_V265_INTVEC_BASE+card; - newcsr = INSERT(IVEC, vec) | INSERT(ILEVEL, CAIN_V265_INT_LEVEL); - pCaenV265->csr = newcsr; - - return OK; -} - - -/* - * caenV265ReadData() - */ -LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config) -{ - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - int16_t val = pCaenV265->data; - int16_t data = EXTRACT(DATA, val); - unsigned range = EXTRACT(RANGE, val); - unsigned signal = EXTRACT(CHANNEL, val); - - if(range>=NUMBER_OF_ADC_RANGES){ - logMsg("caenV265ReadData: bad range number\n",0,0,0,0,0,0); - return; - } - if(signal>=NUMBER_OF_SIGNALS){ - logMsg("caenV265ReadData: bad signal number\n",0,0,0,0,0,0); - return; - } - pCaenV256Config->chan[signal][range].signal=data; - pCaenV256Config->chan[signal][range].newData=TRUE; - - return; -} - - -/* - * caenV265IdTest() - */ -LOCAL int caenV265IdTest(struct caenV265 *pCaenV265) -{ - int status; - int16_t id; - - /* - * Is a card present - */ - status = vxMemProbe( - (char *)&pCaenV265->identifier, - READ, - sizeof(id), - (char *)&id); - if(status!=OK){ - return FALSE; - } - - /* - * Is the correct type of card present - */ - if(id!=CAENV265ID){ - errPrintf( - S_dev_wrongDevice, - __FILE__, - __LINE__, - "caenV265IdTest"); - return FALSE; - } - return TRUE; -} - - -/* - * caenV265Shutdown() - * turns off interrupts so that dont foul up the boot - */ -LOCAL int caenV265Shutdown(void) -{ - struct caenV265 *pCaenV265; - unsigned card; - - for(card=0; cardcsr=0; - } - } - return OK; -} - - -/* - * caenV265Test() - */ -int caenV265Test(unsigned card) -{ - unsigned dacVal; - struct caenV265Config cofigCpy; - unsigned range; - unsigned signal; - - - dacVal=0; - caenV265TestVal(card, dacVal); - while(dacValpCaenV265; - unsigned signal; - - if(!pCaenV265){ - return ERROR; - } - - if(!caenV265IdTest(pCaenV265)){ - return ERROR; - } - - /* - * clear the module - */ - pCaenV265->clear=0; - - /* - * generate a test signal - */ - pCaenV265->DAC=dacVal; - - /* - * generate a test gate - */ - for( signal=0; - signalgate=0; - taskDelay(1); - } - while(!caenV265Info[card].chan[signal][adc_12].newData){ - pCaenV265->gate=0; - taskDelay(1); - } - } - - /* - * turn off test signal - */ - pCaenV265->clear=0; - pCaenV265->DAC=0; - - return OK; -} - - -/* - * caenV265IOReport() - */ -LOCAL long caenV265IOReport(int level) -{ - struct caenV265 *pCaenV265; - unsigned card; - unsigned signal; - unsigned range; - char *pVersion[] = {"NIM","ECL"}; - char *pState[] = { - "FIFO empty", - "FIFO full", - "FIFO partially filled", - "FIFO full"}; - - for (card=0; cardversion)]); - printf("\tseries = %d\n", - EXTRACT(SERIES, pCaenV265->version)); - printf("\tstate = %s\n", - pState[EXTRACT(BUSY_FULL,pCaenV265->csr)]); - printf("\tint level = %d\n", - EXTRACT(ILEVEL,pCaenV265->csr)); - printf("\tint vec = 0x%02X\n", - EXTRACT(IVEC,pCaenV265->csr)); - printf( "\tbase addr= 0x%X on the %s\n", - (unsigned)caenV265Info[card].pCaenV265, - sysModel()); - - for( range=0; - range\n", - signal); - } - } - - } - } - return OK; -} diff --git a/src/drv/drvComet.c b/src/drv/drvComet.c deleted file mode 100644 index 10d650d4a..000000000 --- a/src/drv/drvComet.c +++ /dev/null @@ -1,639 +0,0 @@ -/* comet_driver.c */ -/* base/src/drv $Id$ */ -/* - * Author: Leo R. Dalesio - * Date: 5-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 joh 071092 added argument to calloc() - * .02 joh 071092 stripped the hkv2f specific portion off the comet - * std addr base specification and left it at base - * addr zero which is most likely wrong. - * .03 joh 071492 use extended (A32) address space - * instead of standard (A24) address space - * for the base address of the waveform memory - * (changed arg to sysBusToLocalAdrs() - * .04 joh 071592 fixed to use correct size when incrementing - * to the waveform memory of the second card - * .05 joh 071592 modified A16 & A32 base addr to match AT8 - * address standard - * .06 bg 071792 moved addresses to module_types.h - * .07 joh 080592 added io report routines - * .08 ms 080692 added comet_mode routine, modified comet_driver - * and cometDoneTask to allow an external routine - * to control hardware scan mode. Added variable - * scan_control to flag operating mode. - * .09 mrk 082692 added DSET - * .10 joh 082792 fixed uninitialized csr pointer in comet_driver() - * function - * .11 lrd 091692 add signal support - * .12 joh 092992 card number validation now based on module_types.h. - * signal number checking now based on the array element - * count. - * .13 mrk 080293 Added call to taskwdInsert - * .14 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals - */ - -static char *sccsID = "@(#)drvComet.c 1.11\t9/16/92"; - -/* - * Code Portions - * - * comet_init() - * comet_driver(card, pcbroutine, parg) - * cometDoneTask() - * comet_io_report() - * comet_mode(card,mode,arg,val) - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define COMET_NCHAN 4 -#define COMET_CHANNEL_MEM_SIZE 0x20000 /* bytes */ -#define COMET_DATA_MEM_SIZE (COMET_CHANNEL_MEM_SIZE*COMET_NCHAN) -static char *shortaddr; -static short scan_control; /* scan type/rate (if >0 normal, <=0 external control) */ - -/* comet conrtol register map */ -struct comet_cr{ - unsigned char csrh; /* control and status register - high byte */ - unsigned char csrl; /* control and status register - low byte */ - unsigned char lcrh; /* location status register - high byte */ - unsigned char lcrl; /* location status register - low byte */ - unsigned char gdcrh; /* gate duration status register - high byte*/ - unsigned char gdcrl; /* gate duration status register - low byte */ - unsigned char cdr; /* channel delay register */ - unsigned char acr; /* auxiliary control register */ - char pad[0x100-8]; -}; - - -/* defines for the control status register - high byte */ -#define DIGITIZER_ACTIVE 0x80 /* 1- Active */ -#define ARM_DIGITIZER 0x40 /* 1- Arm the digitizer */ -#define CIRC_BUFFER_ENABLED 0x20 /* 0- Stop when memory is full */ -#define WRAP_MODE_ENABLED 0x10 /* 0- Disable wrap around */ -#define AUTO_RESET_LOC_CNT 0x08 /* 1- Reset addr to 0 on trigger */ -#define EXTERNAL_TRIG_ENABLED 0x04 /* 1- use external clk to trigger */ -#define EXTERNAL_GATE_ENABLED 0x02 /* 0- use pulse start conversion */ -#define EXTERNAL_CLK_ENABLED 0x01 /* 0- uses the internal clock */ - - -/* commands for the COMET digitizer */ -#define COMET_INIT_CSRH -#define COMET_INIT_READ - -/* mode commands for the COMET digitizer */ -#define READREG 0 -#define WRITEREG 1 -#define SCANCONTROL 2 -#define SCANSENSE 3 -#define SCANDONE 4 - -/* register selects */ -#define COMET_CSR 0 -#define COMET_LCR 1 -#define COMET_GDCR 2 -#define COMET_CDACR 3 - -/* defines for the control status register - low byte */ -#define SOFTWARE_TRIGGER 0x80 /* 1- generates a software trigger */ -#define UNUSED 0x60 -#define CHAN_DELAY_ENABLE 0x10 /* 0- digitize on trigger */ -#define DIG_RATE_SELECT 0x0f - -/* digitizer rates - not defined but available for 250KHz to 122Hz */ -#define COMET_5MHZ 0x0000 -#define COMET_2MHZ 0x0001 -#define COMET_1MHZ 0x0002 -#define COMET_500KHZ 0x0003 - -/* defines for the auxiliary control register */ -#define ONE_SHOT 0x10 -#define ALL_CHANNEL_MODE 0x80 - - -/* comet configuration data */ -struct comet_config{ - struct comet_cr *pcomet_csr; /* pointer to the control/status register */ - unsigned short *pdata; /* pointer to data area for this COMET card */ - void (*psub)(); /* subroutine to call on end of conversion */ - void *parg[4]; /* argument to return to the arming routine */ - FAST_LOCK lock; /* mutual exclusion lock */ - IOSCANPVT ioscanpvt; - unsigned long nelements; /* number of elements to digitize/read */ - -}; - -/* task ID for the comet done task */ -int cometDoneTaskId; -struct comet_config *pcomet_config; - -static long report(); -static long init(); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvComet={ - 2, - report, - init}; - - -/* - * cometDoneTask - * - * wait for comet waveform record cycle complete - * and call back to the database with the waveform size and address - * - */ -void -cometDoneTask() -{ - register unsigned card; - register struct comet_config *pconfig; - register long i; - - while(TRUE) - { - - if (scan_control <= 0) - taskDelay(2); - else - { - taskDelay(scan_control); - -/* printf("DoneTask: entering for loop...\n"); */ - - /* check each card for end of conversion */ - for(card=0, pconfig = pcomet_config; card < 2;card++, pconfig++) - { -/* is the card present */ - if (!pconfig->pcomet_csr) - { - if (card == 0) - { -/* - printf("DoneTask: checking card present?...\n"); - printf("DoneTask: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); -*/ - } - continue; - } - -/* is the card armed */ - if (!pconfig->psub) - { - if (card == 0) - { -/* printf("DoneTask: checking card armed?...\n"); */ - } - continue; - } - -/* is the digitizer finished conversion */ -/* printf("pconfig->pdata: %x \n", pconfig->pdata); */ - - if (*(pconfig->pdata+pconfig->nelements) == 0xffff) - { - if (card == 0) - { -/* printf("DoneTask: finished conversion?...\n"); */ - } - continue; - } - -/* printf("DoneTask: pcomet_config->pcomet_csr %x...\n",pcomet_config->pcomet_csr); */ -/* printf("DoneTask: DONE\n"); */ - - -#if 0 - /* reset each of the control registers */ - pconfig->pcomet_csr->csrh = pconfig->pcomet_csr->csrl = 0; - pconfig->pcomet_csr->lcrh = pconfig->pcomet_csr->lcrl = 0; - pconfig->pcomet_csr->gdcrh = pconfig->pcomet_csr->gdcrl = 0; - pconfig->pcomet_csr->acr = 0; -#endif - - /* clear the pointer to the subroutine to allow rearming */ -/* pconfig->psub = NULL; */ - -/* post the event */ -/* - is there a bus error for long references to this card?? copy into VME mem? */ - - if(pconfig->parg[0]) - { - (*pconfig->psub)(pconfig->parg[0],pconfig->pdata); - } - if(pconfig->parg[1]) - { - (*pconfig->psub)(pconfig->parg[1],(((char*)pconfig->pdata)+0x20000)); - } - - if(pconfig->parg[2]) - { - (*pconfig->psub)(pconfig->parg[2],(((char*)pconfig->pdata)+0x40000)); - } - - if(pconfig->parg[3]) - { - (*pconfig->psub)(pconfig->parg[3],(((char*)pconfig->pdata)+0x60000)); - } - - - } - } - } -} - - - -/* - * COMET_INIT - * - * intialize the driver for the COMET digitizer from omnibyte - * - */ -comet_init() -{ - register struct comet_config *pconfig; - short readback,got_one,card; - int status; - struct comet_cr *pcomet_cr; - unsigned char *extaddr; - -/* free memory and delete tasks from previous initialization */ - if (cometDoneTaskId) - { - taskwdRemove(cometDoneTaskId); - if ((status = taskDelete(cometDoneTaskId)) < 0) - logMsg("\nCOMET: Failed to delete cometDoneTask: %d",status); - } - else - { - pcomet_config = (struct comet_config *)calloc(wf_num_cards[COMET],sizeof(struct comet_config)); - if (pcomet_config == 0) - { - logMsg("\nCOMET: Couldn't allocate memory for the configuration data"); - return; - } - } - -/* get the standard and short address locations */ - if ((status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,wf_addrs[COMET],&pcomet_cr)) != OK){ - logMsg("\nCOMET: failed to map VME A16 base address\n"); - return; - } - if ((status = sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,wf_memaddrs[COMET],&extaddr)) != OK){ - logMsg("\nCOMET: failed to map VME A32 base address\n"); - return; - } - -/* determine which cards are present */ - got_one = FALSE; - pconfig = pcomet_config; - - for ( card = 0; - card < 2; - card++, pconfig++, pcomet_cr++, extaddr+= COMET_DATA_MEM_SIZE){ - - /* is the card present */ - if (vxMemProbe(pcomet_cr,READ,sizeof(readback),&readback) != OK) - { - continue; - } - if (vxMemProbe(extaddr,READ,sizeof(readback),&readback) != OK) - { - logMsg("\nCOMET: Found CSR but not data RAM %x\n",extaddr); - continue; - } - - /* initialize the configuration data */ - pconfig->pcomet_csr = pcomet_cr; - pconfig->pdata = (unsigned short *) extaddr; - got_one = TRUE; - - - FASTLOCKINIT(&pcomet_config[card].lock); - - /* initialize the card */ - pcomet_cr->csrh = ARM_DIGITIZER | AUTO_RESET_LOC_CNT; - pcomet_cr->csrl = COMET_1MHZ; - pcomet_cr->lcrh = pcomet_cr->lcrl = 0; - pcomet_cr->gdcrh = 0; - pcomet_cr->gdcrl = 1; - pcomet_cr->cdr = 0; - - /* run it once */ - pcomet_cr->csrl |= SOFTWARE_TRIGGER; - taskDelay(1); - /* reset */ - pcomet_cr->csrl = COMET_5MHZ; - pcomet_cr->acr = ONE_SHOT | ALL_CHANNEL_MODE; - - scanIoInit(&pconfig->ioscanpvt); - - } /*end of for loop*/ - - /* initialization for processing comet digitizers */ - if(got_one) - { - /* start the waveform readback task */ - scan_control = 2; /* scan rate in vxWorks clock ticks */ - cometDoneTaskId = taskSpawn("cometWFTask",WFDONE_PRI,WFDONE_OPT,WFDONE_STACK,(FUNCPTR) cometDoneTask); - taskwdInsert(cometDoneTaskId,NULL,NULL); - } -} - - -static long report(level) - int level; -{ - comet_io_report(level); - return(0); -} - -static long init() -{ - - comet_init(); - return(0); -} - - -/* - * COMET_DRIVER - * - * initiate waveform read - * - */ -comet_driver(card, signal, pcbroutine, parg, nelements) -register short card; -register unsigned short signal; -unsigned int *pcbroutine; -unsigned int *parg; /* pointer to the waveform record */ -unsigned long nelements; -{ - register struct comet_cr *pcomet_csr; - register struct comet_config *pconfig; - register unsigned short *pcomet_data; - register char *dummy; - -/* printf("comet_driver: BEGIN...\n"); */ -/* printf("comet_driver: nelements: %d ...\n",nelements); */ - - /* check for valid card number */ - if(card >= wf_num_cards[COMET]) - return ERROR; - pconfig = (pcomet_config+card); - if(signal >= NELEMENTS(pconfig->parg)) - return ERROR; - pconfig->nelements = nelements * 2; - -/* printf("comet_driver: check for card present...\n"); */ - - /* check for card present */ - if(!pconfig->pcomet_csr) return ERROR; - - /* mutual exclusion area */ - FASTLOCK(&pconfig->lock); - -/* printf("comet_driver: mark the card as armed...\n"); */ - - /* mark the card as armed */ -/* if (pconfig->parg[signal] != 0) */ - pconfig->parg[signal] = parg; -/* if (pconfig->psub) return; */ - pconfig->psub = (void (*)()) pcbroutine; - - /* exit mutual exclusion area */ - FASTUNLOCK(&pconfig->lock); - - pcomet_csr = pconfig->pcomet_csr; - - /* reset each of the control registers */ - pcomet_csr->csrh = pcomet_csr->csrl = 0; - pcomet_csr->lcrh = pcomet_csr->lcrl = 0; - pcomet_csr->gdcrh = pcomet_csr->gdcrl = 0; - pcomet_csr->acr = 0; - - /* arm the card */ - *(pconfig->pdata+pconfig->nelements) = 0xffff; -/* printf("comet_driver: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); */ - - if (scan_control > 0) - { -#if 0 /* for debugging purposes */ - pcomet_csr->gdcrh = 0x03; /* # samples per channel */ - pcomet_csr->gdcrl = 0xe8; /* # samples per channel */ -#endif - - pcomet_csr->gdcrh = (pconfig->nelements >> 8) & 0xff; /* # samples per channel */ - pcomet_csr->gdcrl = pconfig->nelements & 0xff; /* # samples per channel */ - pcomet_csr->acr = ONE_SHOT | ALL_CHANNEL_MODE; /* disarm after the trigger */ - pcomet_csr->csrl = COMET_5MHZ; /* sample at 5MhZ */ - - /* arm, reset location counter to 0 on trigger, use external trigger */ - pcomet_csr->csrh = ARM_DIGITIZER | AUTO_RESET_LOC_CNT | EXTERNAL_TRIG_ENABLED; -/* printf("comet_driver: gdcrh: %x gdcrl: %x nelements: %x\n ",pcomet_csr->gdcrh,pcomet_csr->gdcrl, pconfig->nelements); */ - - } - else - pcomet_csr->csrh |= ARM_DIGITIZER; -/* printf("comet_driver: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); */ - -/* printf("comet_driver: END...\n"); */ - return OK; -} - - -/* - * COMET_IO_REPORT - * - * print status for all cards in the specified COMET address range - */ -comet_io_report(level) -short int level; -{ - struct comet_config *pconfig; - unsigned card; - unsigned nelements; - int status; - - pconfig = pcomet_config; - for(card=0; card < wf_num_cards[COMET]; card++){ - - if(!pconfig->pcomet_csr) - continue; - - printf( "WF: COMET:\tcard=%d\n", card); - if (level >= 2){ - printf("enter the number of elements to dump:"); - status = scanf("%d",&nelements); - if(status == 1){ - comet_dump(card, nelements); - } - } - pconfig++; - } - return OK; -} - - -/* - * comet_dump - * - */ -int comet_dump(card, n) -unsigned card; -unsigned n; -{ - unsigned short *pdata; - unsigned short *psave; - unsigned short *pbegin; - unsigned short *pend; - - if (card >= wf_num_cards[COMET]) - return ERROR; - - pdata = pcomet_config[card].pdata; - psave = (unsigned short *) malloc(n * sizeof(*psave)); - if(!psave){ - return ERROR; - } - - pbegin = psave; - pend = &psave[n]; - for( pdata = pcomet_config[card].pdata; - psave= wf_num_cards[COMET]) - return ERROR; - if (!pcomet_config[card].pcomet_csr) - return ERROR; - switch (mode) - { - case READREG: - /*cptr = (unsigned char *)pcomet_config[card].pcomet_csr; - for (i = 0; i < 6; i++, cptr++) - printf("%x %x\n",cptr,*cptr);*/ - cptr = (unsigned char *)pcomet_config[card].pcomet_csr; /* point to offset 0 */ - cptr += arg<<1; /* build new offset */ - val = (*cptr++)<<8; /* read value and return */ - val |= *cptr; - return val; - break; - case WRITEREG: - cptr = (unsigned char *)pcomet_config[card].pcomet_csr; - cptr += arg<<1; - *cptr++ = val>>8; - *cptr = val; - break; - case SCANCONTROL: - scan_control = val; - break; - case SCANSENSE: - return scan_control; - break; - case SCANDONE: - if (!pcomet_config[card].psub) - return ERROR; - /*pcomet_config[card].psub = NULL;*/ /* clear the pointer to subroutine to allow rearming */ - (*pcomet_config[card].psub)(pcomet_config[card].parg,0xffff,pcomet_config[card].pdata); - break; - default: - return ERROR; - } - return OK; -} - -/*********************************************/ -cometGetioscanpvt(card,scanpvt) -short card; -IOSCANPVT *scanpvt; -{ - register struct comet_config *pconfig; - - pconfig=pcomet_config; - pconfig+=card; - - if ((card >= wf_num_cards[COMET]) || (card < 0)) /* make sure hardware exists */ - return(0); - -/* -This is present in the mix driver...I don't know if I really need it. - if (!pconfig->present) - return(0); -*/ - - *scanpvt = pconfig->ioscanpvt; - - return(0); -} - diff --git a/src/drv/drvCompuSm.c b/src/drv/drvCompuSm.c deleted file mode 100644 index a1bd303b3..000000000 --- a/src/drv/drvCompuSm.c +++ /dev/null @@ -1,972 +0,0 @@ -/* drvCompuSm.c */ -/* base/src/drv $Id$ */ -/* - * subroutines and tasks that are used to interface to the Compumotor 1830 - * stepper motor drivers - * - * Author: Bob Dalesio - * Date: 01-03-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 02-07-90 lrd add command to read the motor status - * .02 04-11-90 lrd made velocity mode motor go active - * .03 04-12-90 lrd only allow one connection to a motor - * .04 04-13-90 lrd add externally initiated motor motion monitoring - * .05 09-05-91 joh updated for v5 vxWorks - * .06 10-09-91 lrd monitor for external motion once every 2 seconds - * not at 30 Hz (.04 was not implemented correctly) - * .06 11-31-91 bg added compu_sm_io_report. Added sysBusToLocalAdrs() - * for addressing. - * .07 03-02-92 bg added level and ability to print raw values to - * compu_sm_io_report for level > 0. - * .08 05-04-92 bg added compu_sm_reset and rebootHookAdd so ioc can be - * rebooted with control X. - * .09 06-25-92 bg Combined drvCompuSm.c and compu_sm_driver.c - * .10 06-26-92 bg Added level to compu_sm_io_report in drvCompuSm - * structure - * .11 06-29-92 joh took file ptr arg out of io report - * .12 08-06-92 joh merged compu sm include file - * .13 08-27-92 joh silenced ANSI C function proto warning - * .14 08-27-92 joh fixed no epics init - * .15 08-02-93 mrk Added call to taskwdInsert - * .16 10-29-93 jba Fixed max number of cards to use module_types.c - * Fixed error in calculating card addresses - */ -#include -#include -#include -#include /* library for semaphore support */ -#include -#include /* library for ring buffer support */ - -/* drvCompuSm.c - Driver Support Routines for CompuSm */ - -#include -#include -#include -#include -#include -#include - - -long compu_sm_io_report(); -long compu_driver_init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvCompuSm={ - 2, - compu_sm_io_report, - compu_driver_init}; - -/* compumotor vme interface information */ -#define MAX_COMPU_MOTORS 8 - -#define RESP_SZ 16 /* card returns 16 chars - cmd & resp */ -#define RESPBUF_SZ (RESP_SZ+1) /* intr routine also passes motor no. */ - -/* Control Byte bit definitions for the Compumotor 1830 */ - /* bits 0 and 1 are not used */ -#define CBEND 0x04 /* end of command string */ -#define CBLMR 0x08 /* last message byte read */ -#define CBCR 0x10 /* command ready in cm_idb */ -#define CBMA 0x20 /* message accepted from odb */ -#define CBEI 0x40 /* enable interrupts */ -#define CBBR 0x80 /* board reset */ -#define SND_MORE CBCR | CBEI /* more chars to send */ -#define SND_LAST CBEND | SND_MORE /* last char being sent */ -#define RD_MORE CBMA | CBEI /* more chars to read */ -#define RD_LAST CBLMR | RD_MORE /* last byte we need to read */ - -/* Status Byte bit definitions */ -#define SBIRDY 0x10 /* idb is ready */ - -/* Structure used for communication with a Compumotor 1830 -** Motor Controller. The data buffer is repeated 64 times -** on even word addresses (0xXXXXXX1,0xXXXXX5...) and the -** control location is repeated 64 times on odd word -** addresses (0xXXXXX3, 0xXXXXX7...). The registers must -** be read and written as bytes. -*/ -struct compumotor { - char cm_d1; /* not accessable */ - char cm_idb; /* input data buffer */ - char cm_d2; /* not accessable */ - char cm_cb; /* control byte */ - char cm_d3[0x100-4]; /* fill to next standard address */ -}; - - -/* This file includes defines for all compumotor 1830 controller -** commands. */ - -#define SM_NULL 0x0 /* Null command */ -#define SM_INT 0x1 /* Interrupt X */ -#define SM_WRT_STAT 0x8 /* Write X to the user defined status bits */ -#define SM_SET_STAT 0x9 /* Set user defined status bit number X */ -#define SM_CLR_STAT 0xa /* Clear user defined status bit number X */ -#define SM_SET_PROG 0xb /* Set programmable output bit X */ -#define SM_CLR_PROG 0xc /* Clear programmable output bit X */ -#define SM_WRT_PROG 0xd /* Write X to the programmable output bits */ -#define SM_DEF_X_TO_Y 0xf /* Define bit X to indicate state Y */ -#define SM_TOG_JOG 0x10 /* Disable/enable the JOG inputs */ -#define SM_DEF_JOG 0x11 /* Define JOG input functions */ -#define SM_TOG_REM_PWR 0x12 /* Turn off/on remote power shutdown */ -#define SM_TOG_REM_SHUT 0x13 /* Disable/enable the "remote shutdown" bit */ -#define SM_SET_CW_MOTN 0x14 /* Set CW motion equal to +- */ -#define SM_TOG_POS_MTN 0x18 /* Turn off/on post-move position maintenance */ -#define SM_TOG_STOP_STL 0x19 /* Turn off/on termination on stall detect */ -#define SM_REP_X_Y 0x20 /* Repeat the following X commands Y times */ -#define SM_REP_TIL_CONT 0x21 /* Repeat the following X commands - until a CONTINUE is received */ -#define SM_WAIT_CONT 0x28 /* Wait for a CONTINUE */ -#define SM_WAIT_MILLI 0x29 /* Wait X milliseconds */ -#define SM_WAIT_SECOND 0x2a /* Wait X seconds */ -#define SM_WAIT_MINUTE 0x2b /* Wait X minutes */ -#define SM_WAIT_TRIGGER 0x2c /* Wait for trigger X to go active */ -#define SM_DEF_A_OP_POS 0x2e /* Define the abs open-loop position as X */ -#define SM_DEF_A_CL_POS 0x2f /* Define absolute closed-loop position */ -#define SM_DEF_ABS_ZERO 0x30 /* Define the present position as the - absolute zero position */ -#define SM_DEF_VEL_ACC 0x31 /* Define default velocity and acceleration */ -#define SM_MOV_DEFAULT 0x32 /* Perform the default move (trapezoidal - continuous) */ -#define SM_MOV_REL_POS 0x33 /* Go to relative position X at default - velocity and acceleration */ -#define SM_MOV_ABS_POS 0x34 /* Go to absolute position X at default - velocity and acceleration */ -#define SM_MOV_REL_ENC 0x35 /* Go to relative encoder position X */ -#define SM_MOV_ABS_ENC 0x36 /* Go to absolute encoder position X */ -#define SM_DEF_OP_HOME 0x38 /* Define HOME location (open loop */ -#define SM_DEF_CL_HOME 0x38 /* Define HOME location (closed loop) */ -#define SM_MOV_HOME_POS 0x39 /* Go HOME at the default velocity and - acceleration */ -#define SM_MOV_HOME_ENC 0x3a /* Go to encoder HOME at the default - velocity and acceleration */ -#define SM_DO_MOV_X 0x40 /* Perform move number X */ -#define SM_DO_SEQ_X 0x41 /* Perform sequence buffer X */ -#define SM_DO_VEL_STR 0x42 /* Perform the velocity streaming buffer */ -#define SM_CONT 0x48 /* CONTINUE (perform next command) */ -#define SM_OP_LOOP_MODE 0x50 /* Enter open loop indexer mode */ -#define SM_VEL_DIS_MODE 0x51 /* Enter velocity-distance streaming mode */ -#define SM_VEL_TIM_MODE 0x52 /* Enter velocity-time streaming mode */ -#define SM_STOP 0x70 /* STOP motion */ -#define SM_DSC_SEQ 0x71 /* Discontinue the sequence buffer */ -#define SM_SSP_SEQ 0x72 /* Suspend the sequence buffer; - wait for a CONTINUE to resume */ -#define SM_DSC_SNGL 0x73 /* Discontinue any singular command - currently being performed */ -#define SM_STOP_ON_TRG 0x74 /* STOP motion when trigger X goes active */ -#define SM_DSC_SEQ_TRG 0x75 /* Discontinue the sequence buffer when - trigger X goes active */ -#define SM_SSP_SEQ_TRG 0x76 /* Suspend sequence buffer when trigger - X goes active */ -#define SM_DSC_SNGL_TRG 0x77 /* Discontinue any singular command when - trigger X goes active */ -#define SM_KILL 0x78 /* Kill motion */ -#define SM_KILL_SEQ 0x79 /* Kill the sequence buffer */ -#define SM_KILL_SEQ_SNGL 0x7a /* Kill current sequence singular command; - wait for CONTINUE */ -#define SM_KILL_VEL_STR 0x7b /* Kill the velocity streaming buffer */ -#define SM_KILL_ON_TRG 0x7c /* Kill motion when trigger X goes active */ -#define SM_KILL_SEQ_TRG 0x7d /* Kill the sequence buffer when trigger - X goes active */ -#define SM_KL_SQSNG_TRG 0x7e /* Kill current sequence singular command - when trigger X goes active; wait for - a continue */ -#define SM_KL_VLSTR_TRG 0x7f /* Kill the velocity streaming buffer - when trigger X goes active */ -#define SM_GET_B_REL_POS 0x80 /* Request position relative to the - beginning of the current move */ -#define SM_GET_E_REL_POS 0x81 /* Request position relative to the - end of the current move */ -#define SM_GET_H_REL_POS 0x82 /* Request position relative to the home - limit switch */ -#define SM_GET_Z_REL_POS 0x83 /* Request position relative to the - absolute zero position */ -#define SM_GET_CUR_DIR 0x84 /* Request current direction */ -#define SM_GET_VEL 0x85 /* Request current velocity */ -#define SM_GET_ACC 0x86 /* Request current acceleration */ -#define SM_GET_MOV_STAT 0x88 /* Request current move status */ -#define SM_GET_LIM_STAT 0x89 /* Request state of the limit switches */ -#define SM_GET_HOME_STAT 0x8a /* Request state of the HOME switch */ -#define SM_GET_TRV_DIR 0x8b /* Request direction of travel */ -#define SM_GET_MOT_MOV 0x8c /* Request whether motor is moving or not */ -#define SM_GET_MOT_CONST 0x8d /* Request whether motor is at constant, - nonzero velocity or not */ -#define SM_GET_MOT_ACC 0x8e /* Request whether motor is or is not - accelerating */ -#define SM_GET_MOT_DEC 0x8f /* Request whether motor is or is not - decelerating */ -#define SM_GET_MODE 0x90 /* Request present mode */ -#define SM_GET_MV_PARM 0x91 /* Request move parameters for move number X */ -#define SM_GET_SEQ_CMMD 0x92 /* request commands stored in the - sequence buffer */ -#define SM_GET_MVDEF_STAT 0x93 /* Request state of the move definitions */ -#define SM_GET_TRG_STAT 0x94 /* Request state of trigger inputs */ -#define SM_GET_JOG_STAT 0x95 /* Request state of JOG inputs */ -#define SM_GET_Z_STAT 0x96 /* Request state of the Channel Z home input */ -#define SM_GET_OUT_STAT 0x97 /* Request the state of the programmable - output bits */ -#define SM_GET_REL_ENC 0x98 /* Request relative encoder count */ -#define SM_GET_REL_ERR 0x99 /* Request relative error from desired - closed loop position */ -#define SM_GET_ABS_ENC 0x9a /* Request absolute encoder count */ -#define SM_GET_SLIP_STAT 0x9b /* Request slip detect status */ -#define SM_GET_RATIO 0x9c /* Request motor pulse to encoder pulse ratio */ -#define SM_GET_RESOLTN 0x9d /* Request motor resolution */ -#define SM_GET_BACK_SIG 0x9e /* Request backlash sigma (motor steps)*/ -#define SM_GET_ALG 0x9f /* Request position maintenance alg. - const, and max velocity */ -#define SM_INT_NXT_MOV 0xa0 /* Interrupt at start of next move */ -#define SM_INT_ALL_MOV 0xa1 /* Interrupt at the start of every move */ -#define SM_INT_NXT_NZ 0xa2 /* Interrupt at constant nonzero velocity - of next move */ -#define SM_INT_ALL_NZ 0xa3 /* Interrupt at constant nonzero velocity - of every move */ -#define SM_INT_NXT_END 0xa4 /* Interrupt at next end of motion */ -#define SM_INT_ALL_END 0xa5 /* Interrupt at every end of motion */ -#define SM_INT_NXT_STL 0xa6 /* Interrupt on next stall detect */ -#define SM_INT_ALL_STL 0xa7 /* Interrupt on every stall detect */ -#define SM_INT_NXT_PLIM 0xa8 /* Interrupt the next time the motor - hits the positive limit */ -#define SM_INT_ALL_PLIM 0xa9 /* Interrupt on every positive limit */ -#define SM_INT_NXT_NLIM 0xaa /* Interrupt the next time the motor - hits the negative limit */ -#define SM_INT_ALL_NLIM 0xab /* Interrupt on every negative limit */ -#define SM_INT_TRG 0xac /* Interrupt on trigger X active */ -#define SM_INT_INHBT 0xaf /* Inhibit all interrupts */ -#define SM_DEF_RATIO 0xb0 /* Define motor pulse to encoder pulse ratio */ -#define SM_DEF_RESOLTN 0xb1 /* Define motor resolution */ -#define SM_DEF_BACK_SIG 0xb2 /* Define backlash sigma (motor steps)*/ -#define SM_DEF_ALG 0xb3 /* Define position maintenance algorithm - const, and max velocity */ -#define SM_DEF_TEETH 0xb4 /* Define the number of rotor teeth */ -#define SM_DEF_DEADBAND 0xb5 /* Def the deadband region in encoder pulses */ -#define SM_DEF_REL_TRP 0xc8 /* Define move X as a relative, - trapezoidal move */ -#define SM_DEF_ABS_TRP 0xcb /* Define move X as an absolute - trapezoidal move */ -#define SM_DEF_CONT 0xce /* Define move X as a continuous move */ -#define SM_DEF_REL_CL 0xd4 /* Define move X, define it as relative, - closed-loop move */ -#define SM_DEF_ABS_CL 0xd5 /* Def move X as an abs, closed- loop move */ -#define SM_DEF_STSTP_VEL 0xd6 /* Define the start/stop velocity */ -#define SM_DEL_MOV_X 0xd7 /* Delete move X */ -#define SM_END_SEQ_DEF 0xd8 /* End definition of sequence buffer */ -#define SM_BEG_SEQ_DEF 0xd9 /* Begin definition of sequence buffer */ -#define SM_DEL_SEQ_X 0xda /* Delete sequence buffer X */ -#define SM_LD_VD_DATA 0xe0 /* Place data into the velocity-distance buffer */ -#define SM_LD_VT_DATA 0xe1 /* Place data into the velocity-time buffer */ -#define SM_GET_FREE_BYT 0xe2 /* Request number of free bytes in vel- - streaming/sequence buffer */ -#define SM_DEF_VS_CMMD 0xee /* Define command to be executed during - the velocity streaming buffer */ -#define SM_GET_NUM_REV 0xfd /* Request software part number and revision */ -#define SM_TEST_SWITCH 0xff /* Perform the test switch function */ - - -#define VELOCITY_MODE 0 -#define MAX_COMMANDS 256 -#define COMPU_INT_LEVEL 5 - -/* array of pointers to stepper motor driver cards present in system */ -struct compumotor *pcompu_motors[MAX_COMPU_MOTORS]; - -LOCAL SEM_ID compu_wakeup; /* compumotor data request task semaphore */ - -/* response variables */ -LOCAL SEM_ID smRespSem; /* task semaphore */ -LOCAL RING_ID smRespQ; /* ring buffer */ -int smRespId; /* task id */ -#define RESP_Q_SZ (RESPBUF_SZ * 50) /* response ring buffer size */ - -/* interrupt buffers */ -unsigned char sm_responses[MAX_COMPU_MOTORS][RESPBUF_SZ]; -unsigned short counts[MAX_COMPU_MOTORS]; - -/* VME memory Short Address Space is set up in gta_init */ -static int *compu_addr; - -/* motor information */ -struct compu_motor{ -short active; /* flag to tell the oms_task if the motor is moving */ -int callback; /* routine in database library to call with status */ -int callback_arg; /* argument to callback routine */ -short update_count; -short mode; -short motor_resolution; -}; -struct compu_motor compu_motor_array[MAX_COMPU_MOTORS]; - -/* Forward reference. */ -VOID compu_sm_reset(); -VOID compu_sm_stat(); - -/* motor status - returned to the database library routines */ -struct motor_data compu_motor_data_array[MAX_COMPU_MOTORS]; - -/* moving status bit descriptions */ -#define CW_LIMIT 0x01 /* clockwise???? limit */ -#define CCW_LIMIT 0x02 /* counter-clockwise???? limit */ -#define DIRECTION 0x08 /* direction bit */ -#define MOVING 0x10 /* moving status bit */ -#define CONSTANT_VEL 0x20 /* constant velocity */ - -/* directions in driver card-ese */ -#define CLKW 0 /* clockwise direction */ -#define CCLKW 1 /* counter clockwise direction */ - -/* - * Code Portions: - * - * smCmdTask Task which writes commands to the hardware - * smRespTask Task which places reponses from the hardware into resp buffers - * sm_intr Interrupt Handler - collects response data from the hardware - * sm_drv_init Initializes all motors, semaphores, ring buffers and interrupts - * sm_driver Subroutine for outside world to issue commands to motors - * motor_select Subroutine to setting callback arg and verifying no other user - * motor_deselect Subroutine to free the motor for other users - * - * Interaction Chart: - * -------------- ------------------- - * / \ / \ - * | smRespTask | | smCmdTask | - * \ / \ / - * --------------- ------------------- - * ^ ^ | - * TAKES | | GETS | - * | | | - * -------------- --------------- | - * Resp Semaphore Response Queue | - * -------------- --------------- | - * ^ ^ | - * GIVES | | PUTS | - * | | | - * --------------- | - * / \ | - * | sm_intr | | - * \ / | - * --------------- | - * ^ reads responses writes commands | - * | from hardware to hardware V - */ - -/* - * COMPU_RESP_TASK - * - * converts readback from the compumotor 1830 cards into a structure that - * is returned to the database library layer every .1 second while a motor - * is moving - */ -compu_resp_task() -{ - unsigned char resp[RESPBUF_SZ]; - register short i; - register struct motor_data *pmotor_data; - - FOREVER { - /* wait for somebody to wake us up */ - semTake (smRespSem, WAIT_FOREVER); - /* the response buffer contains: */ - /* 0 - motor number */ - /* 1 - the command which solicited this response */ - /* 2 - the first byte of the response */ - - /* process requests in the command ring buffer */ - while (rngBufGet(smRespQ,(char *)resp,RESPBUF_SZ) == RESPBUF_SZ){ - pmotor_data = &compu_motor_data_array[resp[0]]; - - /* convert argument */ - switch(resp[1]){ - - case (SM_GET_VEL): - { - register long *pvelocity = (long *)(&resp[3]); - pmotor_data->velocity = *pvelocity; - - break; - } - case (SM_GET_MOV_STAT): - { - register struct compu_motor *pcompu_motor; - register int (*psmcb_routine)(); - - pcompu_motor = &compu_motor_array[resp[0]]; - pmotor_data->moving = (resp[2] & MOVING)?1:0; - pmotor_data->constant_velocity = (resp[2] & CONSTANT_VEL)?1:0; - pmotor_data->cw_limit = (resp[2] & CW_LIMIT)?1:0; - pmotor_data->ccw_limit = (resp[2] & CCW_LIMIT)?1:0; - pmotor_data->direction = (resp[2] & DIRECTION)?1:0; - - /* post every .1 second or not moving */ - if ((pcompu_motor->update_count-- <= 0) - || (pmotor_data->moving == 0)){ - if (pcompu_motor->callback != 0){ - (int)psmcb_routine = pcompu_motor->callback; - (*psmcb_routine)(pmotor_data,pcompu_motor->callback_arg); - } - if (pmotor_data->moving){ - /* motors are reported at 10 Hz */ - pcompu_motor->update_count = 3; - }else{ - pcompu_motor->active = FALSE; - pcompu_motor->update_count = 0; - } - } - break; - } - case (SM_GET_ABS_ENC): - { - register long *pencoder = (long *)(&resp[2]); - pmotor_data->encoder_position = *pencoder; - break; - } - case (SM_GET_Z_REL_POS): - { - register long *pmotor = (long *)(&resp[4]); - pmotor_data->motor_position = *pmotor; - break; - } - case (SM_GET_CUR_DIR): - pmotor_data->direction = (resp[2] == 0xff)?CLKW:CCLKW; - break; - } - } - } -} - -/* Data request commands for the positional and velocity mode motors */ -char compu_velo_reqs[] = { SM_GET_VEL, SM_GET_MOV_STAT }; -#define NUM_VEL_REQS 2 -char compu_pos_reqs[] = { SM_GET_ABS_ENC, SM_GET_Z_REL_POS, SM_GET_MOV_STAT }; -#define NUM_POS_REQS 3 -/* - * COMPU_TASK - * - * task to solicit currnet status from the compumotor 1830 cards while they - * are active - */ -compu_task() -{ - register short inactive_count; - register short card; - register short i; - register struct compumotor *pmotor; - register char *preqs; - - /* inactive motors get monitored once every 2 seconds in case they are */ - /* being moved manually */ - inactive_count = 60; - while(1){ - /* This task is run 30 times a second */ - taskDelay(2); - for (card = 0; card < sm_num_cards[CM57_83E]; card++){ - pmotor = pcompu_motors[card]; - if (pmotor == 0) continue; - if ((compu_motor_array[card].active) - || (inactive_count <=0)){ - if (compu_motor_array[card].mode == VELOCITY_MODE){ - preqs = &compu_velo_reqs[0]; - /* request status data */ - for (i = 0; i < NUM_VEL_REQS; i++,preqs++) - compu_send_msg(pmotor,preqs,1); - }else{ - preqs = &compu_pos_reqs[0]; - /* request status data */ - for (i = 0; i < NUM_POS_REQS; i++,preqs++) - compu_send_msg(pmotor,preqs,1); - } - } - } - if (--inactive_count < 0) inactive_count = 60; - } -} - -/* - * COMPU_INTR - * - * interrupt vector for the compumotor 1830 card - */ -compu_intr(mdnum) -register int mdnum; -{ - register struct compumotor *pmtr; /* memory port to motor card */ - register int key; - - key = intLock(); - - /* pointer to the compumotor card interface */ - pmtr = pcompu_motors[mdnum]; - - /* place the response byte into the appropriate response buffer */ - sm_responses[mdnum][counts[mdnum]] = pmtr->cm_idb; - counts[mdnum]++; - - /* when the buffer is full pass it onto the repsonse task */ - if (counts[mdnum] == RESPBUF_SZ){ - if (rngBufPut(smRespQ,(char *)sm_responses[mdnum],RESPBUF_SZ) != RESPBUF_SZ) - logMsg("smRespQ %d - Full\n",mdnum); - else - semGive (smRespSem); - - /* the zero-th byte is the motor number */ - counts[mdnum] = 1; /* start with command */ - - /* inform the hardware that the response is complete */ - pmtr->cm_cb = RD_LAST; - }else{ - /* inform the hardware there is more to send */ - pmtr->cm_cb = RD_MORE; - } - - intUnlock(key); -} - -/* - * COMPU_DRIVER_INIT - * - * initialization for the compumotor 1830 card - */ -long -compu_driver_init(){ - register short i; - int status; - struct compumotor *pmtr; /* memory port to motor card */ - int cok = CBBR; /*to reset board */ - short none_found; /* flags a steppermotor is present */ - int taskId; - struct compumotor *pmtrb; - - /* intialize each driver which is present */ - none_found = TRUE; - rebootHookAdd((FUNCPTR)compu_sm_reset); - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - sm_addrs[CM57_83E], - (int **)&compu_addr); - if (status != OK){ - printf("%s: failed to map A16 base\n", __FILE__); - return ERROR; - } - - pmtrb = (struct compumotor *)compu_addr; - for (i = 0; i < sm_num_cards[CM57_83E]; i++) { - pmtr = (struct compumotor *)((int)pmtrb + (i<<8)); - - /* initialize when card is present */ - - if (vxMemProbe(&pmtr->cm_cb,WRITE,1,&cok) != ERROR){ - none_found = FALSE; - pcompu_motors[i] = pmtr; /* ptr to interface */ - intConnect((MD_INT_BASE+i)*4,compu_intr,i); /* interrupt enable */ - sysIntEnable(COMPU_INT_LEVEL); - - /* init interrupt receive buffers */ - sm_responses[i][0] = i; /* motor number */ - counts[i] = 1; /* buffer index */ - }else{ - pcompu_motors[i] = 0; /* flags no board is present */ - } - } - if (none_found) return(0); - - /* initialize the response task ring buffer */ - if ((smRespQ = rngCreate(RESP_Q_SZ)) == (RING_ID)NULL) - panic ("sm_init: cmRespQ\n"); - - /* intialize the semaphores which awakens the sleeping * - * stepper motor command task and the stepper motor response task */ - if(!(smRespSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))) - errMessage(0,"semBcreate failed in compu_driver_init"); - if(!(compu_wakeup=semBCreate(SEM_Q_FIFO,SEM_EMPTY))) - errMessage(0,"semBcreate failed in compu_driver_init"); - - /* spawn the sleeping motor driver command and response tasks */ - smRespId = - taskSpawn("compu_resp_task",SMRESP_PRI,SMRESP_OPT,SMRESP_STACK,compu_resp_task); - taskwdInsert(smRespId,NULL,NULL); - taskId = taskSpawn("compu_task",SMRESP_PRI,SMRESP_OPT,2000,compu_task); - taskwdInsert(taskId,NULL,NULL); - return(0); -} - -short trigger = 0; -/* - * COMPU_DRIVER - * - * driver interface to the database library layer - */ -compu_driver(card,value_flag,arg1,arg2) -register short card; -short value_flag; -register int arg1; -register int arg2; -{ - register int *pint; - register short *pshort; - short j,i; - char compu_msg[20]; - - /* verify the stepper motor driver card is present */ - if ((card < 0) || (card > sm_num_cards[CM57_83E]) || (!pcompu_motors[card])) - return (-1); - - switch (value_flag){ - case (SM_MODE): - /* set the motor mode */ - compu_motor_array[card].mode = arg1; - break; - - case (SM_VELOCITY): - compu_motor_data_array[card].velocity = arg1; - compu_motor_data_array[card].accel = arg2; - - /* set the velocity */ - compu_msg[0] = SM_DEF_VEL_ACC; - compu_msg[1] = 0; /* time is in seconds */ - compu_msg[2] = 0; - pint = (int *)&compu_msg[3]; /* velocity */ - *pint = arg1; - pint++; /* acceleration */ - *pint = arg2; - compu_send_msg(pcompu_motors[card],compu_msg,11); - - break; - - case (SM_MOVE): - if (compu_motor_array[card].mode == VELOCITY_MODE) - return(0); -i = 0; -switch (trigger){ -case (0): - /* move the motor */ - compu_msg[i++] = SM_MOV_REL_POS; - pint = (int *)&compu_msg[i]; - *pint = arg1; - i += 4; - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - break; -case (1): /* test sequnce buffer */ - compu_msg[i++] = 0xda; /* delete sequence buffer */ - compu_msg[i++] = 01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0xd9; /* fill sequence buffer */ - compu_msg[i++] = 01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = SM_MOV_REL_POS; - pint = (int *)&compu_msg[i]; - *pint = arg1; - i += 4; - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0xd8; /* end sequence buffer */ - compu_msg[i++] = 0x41; /* perform sequence buffer */ - compu_msg[i++] = 0x01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - break; -case (2): /* test move buffer */ - compu_msg[i++] = 0xc8; - compu_msg[i++] = 0x12; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x04; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x04; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x00; - pint = (int *)&compu_msg[i]; - *pint = arg1; - i += 4; - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0x40; - compu_msg[i++] = 0x12; - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - break; -case (3): /* test sequence buffer with move buffer */ - compu_msg[i++] = 0xc8; - compu_msg[i++] = 0x12; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x04; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x04; - compu_msg[i++] = 0x00; - compu_msg[i++] = 0x00; - pint = (int *)&compu_msg[i]; - *pint = arg1; - i += 4; - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0xda; /* delete sequence buffer */ - compu_msg[i++] = 01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0xd9; /* fill sequence buffer */ - compu_msg[i++] = 01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0x40; - compu_msg[i++] = 0x12; - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0xd8; /* end sequence buffer */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0x41; /* perform sequence buffer */ - compu_msg[i++] = 0x01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - break; -case (4): /* test sequence buffer with move buffer and trigger */ - compu_msg[i++] = 0xc8; - compu_msg[i++] = 0x12; - - compu_msg[i++] = 0x00; - pint = (int *)&compu_msg[i]; - *pint = compu_motor_data_array[card].velocity; - i += 4; - pint++; - *pint = compu_motor_data_array[card].accel; - i += 4; - pint++; - *pint = arg1; - i += 4; - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0xda; /* delete sequence buffer */ - compu_msg[i++] = 01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0xd9; /* fill sequence buffer */ - compu_msg[i++] = 01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0x2c; /* wait for trigger */ - compu_msg[i++] = 1; /*trigger 1 */ - compu_msg[i++] = 1; /* don't care about state */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0x40; - compu_msg[i++] = 0x12; - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0xd8; /* end sequence buffer */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - compu_msg[i++] = 0x41; /* perform sequence buffer */ - compu_msg[i++] = 0x01; /* buffer 1 */ - compu_send_msg(pcompu_motors[card],compu_msg,i); - i = 0; - break; -} -for (j = 0; j < i; j++){ -printf("%x ",compu_msg[j]); -} -/* compu_send_msg(pcompu_motors[card],compu_msg,i); -*/ - /* set the motor to active */ - compu_motor_array[card].active = TRUE; - - /* wakeup the compu task */ - semGive(compu_wakeup); - - break; - - case (SM_MOTION): - if (arg1 == 0){ - compu_msg[0] = SM_STOP; - compu_send_msg(pcompu_motors[card],compu_msg,1); - }else if (compu_motor_array[card].mode == VELOCITY_MODE){ - compu_msg[0] = SM_MOV_DEFAULT; - compu_msg[1] = arg2; /* direction */ - compu_send_msg(pcompu_motors[card],compu_msg,2); - compu_motor_array[card].active = TRUE; - } - - /* wakeup the compu task */ - semGive(compu_wakeup); - break; - - case (SM_CALLBACK): - /* put the callback routine and argument into the data array */ - i = 0; - if (compu_motor_array[card].callback != 0) return(-1); - compu_motor_array[card].callback = arg1; - compu_motor_array[card].callback_arg = arg2; - break; - - case (SM_SET_HOME): - if (compu_motor_array[card].mode == VELOCITY_MODE) - return(OK); - - /* set the motor and encoder position to zero */ - compu_msg[0] = SM_DEF_ABS_ZERO; - compu_send_msg(pcompu_motors[card],compu_msg,1); - - break; - - case (SM_ENCODER_RATIO): - compu_motor_array[card].motor_resolution = arg1; - - /* set the encoder ratio */ - compu_msg[0] = SM_DEF_RATIO; - pshort = (short *)&compu_msg[1]; - *pshort = arg1; /* motor resolution */ - pshort++; - *pshort = arg2; /* encoder resolution */ - compu_send_msg(pcompu_motors[card],compu_msg,5); - - /* set the motor resolution */ - compu_msg[0] = SM_DEF_RESOLTN; - pshort = (short *)&compu_msg[1]; - *pshort = 0; - pshort++; - *pshort = arg1; /* motor resolution */ - compu_send_msg(pcompu_motors[card],compu_msg,5); - - break; - case (SM_READ): - /* set the motor to active */ - compu_motor_array[card].active = TRUE; - - /* wakeup the compu task */ - semGive(compu_wakeup); - - break; - - } - return (OK); -} - -/* - * COMPU_SEND_MSG - * - * send a message to the compumotor 1830 - */ -int wait_count; -compu_send_msg(pmotor,pmsg,count) -register struct compumotor *pmotor; -register char *pmsg; -register short count; -{ - /* write out this command one byte at a time */ - while (count){ - - /* wait for the driver to be ready */ - while ((pmotor->cm_cb & SBIRDY) == 0){ - taskDelay(0); - wait_count++; - } - - /* next byte in the input data buffer of compumotor */ - pmotor->cm_idb = *pmsg; - pmsg++; - count--; - - /* tell compumotor more or complete */ - if (count == 0){ - pmotor->cm_cb = SND_LAST; - }else{ - pmotor->cm_cb = SND_MORE; - } - } -} - - -/* - * COMPU_SM_IO_REPORT - * - * send a message to the compumotor 1830 - */ - -long compu_sm_io_report(level) - short int level; - { - register int i; - - for (i = 0; i < sm_num_cards[CM57_83E]; i++){ - if (pcompu_motors[i]){ - - printf("SM: CM1830: card %d\n",i); - if (level > 0) - compu_sm_stat(i); - } - } - - return OK; - } - -VOID compu_sm_stat(compu_num) - short int compu_num; - { - struct motor_data *pmotor_data; - printf("\tCW limit = %d\t,CCW limit = %d\tMoving = %d\tDirection = %d\n", - compu_motor_data_array[compu_num].cw_limit, - compu_motor_data_array[compu_num].ccw_limit, - compu_motor_data_array[compu_num].moving, - compu_motor_data_array[compu_num].direction); - - printf("\tConstant Velocity = %d\t, Velocity = %d\t \n", - compu_motor_data_array[compu_num].constant_velocity, - compu_motor_data_array[compu_num].velocity); - - printf("\tAcceleration = %d\tEncoder Position = %d\tMotor Position = %d\n", - compu_motor_data_array[compu_num].accel, - compu_motor_data_array[compu_num].encoder_position, - compu_motor_data_array[compu_num].motor_position); - } - -/* - * - * Subroutine to be called during a CTL X reboot. Inhibits interrupts. - * - */ - -VOID compu_sm_reset() - { - short int i; - char compu_msg[20]; - - for (i = 0; i < sm_num_cards[CM57_83E]; i++){ - if (pcompu_motors[i]){ - compu_msg[0] = SM_INT_INHBT; - compu_send_msg(pcompu_motors[i],compu_msg,1); - } - } - } - diff --git a/src/drv/drvDvx.c b/src/drv/drvDvx.c deleted file mode 100644 index 5fc238bfb..000000000 --- a/src/drv/drvDvx.c +++ /dev/null @@ -1,1400 +0,0 @@ -/* share/src/drv/drvDvx.c - * base/src/drv $Id$ - * - * subroutines which are used to interface with the analogic 2502 - * A/D scanner cards - * - * Author: Matthew Stettler - * Date: 5-23-90 - * - * AT-8 hardware design - * - * Modules: - * - * dvx_driver_init Finds and initializes all 2502 cards - * dvx_dma_init Initializes Am9516 DMA controller - * dvx_driver Reads data from 2502 - * dvx_int Interrupt service routine - * - * Test Routines: - * - * dvx_dump dumps RAM buffer - * dvx_dread command line interface to dvx_driver - * dvx_fempty clears fifo from command line - * dvx_dma_stat displays DMA channel status - * - * 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: - * ----------------- - * MS 6/22/90 Modifications to aid in debugging interface to Mizar timing - * system. Interrupt service routine now counts words when clearing - * fifo, dvx_dump provides fifo status, and dvx_fempty added to - * clear fifo from command line. - * - * MS 7/9/90 Modifications to speed up interrupt service routine. - * - * MS 7/23/90 Added DMA control logic. - * - * MS 8/20/90 Added support for interrupt scanned records. - * - * MS 9/20/90 Changed data conversion to offset binary - * (only test routines affected) - * - * JH 07/25/91 added dvx_reset() and dvx_reset() on control X reboot - * - * JH 11/14/91 changed a sysBCLSet to sysIntEnable so ioc_core - * will load into the nat inst cpu030 - * - * JH 11/14/91 removed sysBCLSet enabling STD non priv and super - * access since this is already enabled if we are - * processor 0 - * JH 11/14/91 changed DVX_INTLEV from a mask to a level - * to support use of sysIntEnable() which - * is architecture independent - * BG 4/22/92 added sysBusToLocalAddr() for both short and standard - * addresses for this module. Moved DVX_ADDR0 to - * ai_addrs[DVX2502]in module_types.h. Also moved DVX_IVECO - * to module_types.h. - * BG 6/23/92 combined dvx_driver.c and drvDvx.c - * BG 06/26/92 added level to dvx_io_report in drvDvx structure. - * JH 06/29/92 moved the rest of the dvx io_report here - * BG 7/2/92 removed the semaphores from dvx_io_report - * JH 08/03/92 Removed hkv2f dependent base addr - * JH 08/03/92 moved interrupt vector base to module_types.h - * JH 08/05/92 dvx driver init is called from drvDvx now - * JH 08/10/92 merged dvx private include file into this source - * JH 09/09/92 ran through UNIX C beautifier and converted to ANSI C - * JH 09/09/92 check to see if A24 is open prior to mapping - * the seq ram. - * JH 09/14/92 Made taskDelays() CPU tick rate independent - * tick rate - * JH 09/15/92 made interrupt vector CPU independent - * MRK 09/16/92 Added support for new I/O event scanning - * JH 09/16/92 dont write wordcnt every time the fifo is unloaded - * JH 09/16/92 Use sysLocalToBusAdrs() to translate from an internal - * to a VME A24 address in case the internal base for A24 - * addressed local memory is not on a 16MB boundary. - * sysLocalToBusAdrs() is called for each malloc'ed - * pointer used by the DVX to verify that each one is - * within the portion of local memory mapped to A24. - * JH 09/17/92 one more sysLocalToBusAdrs() address translation - * needed - * JRW 01/18/92 Replaced init code to allow user to select the interrupt - * level value and to select the ports that are to be read. - * MGB 08/04/93 Removed V5/V4 and EPICS_V2 conditionals - * FRL 11/17/93 Added gain parameter to dvx_program - * - * - * NOTE (JRW 11-18-92): - * In a phone conversation with Analogic, Tech support said that when the start - * signal is de-asserted (when using external start/stop mode), the DMAC is - * told to start transferring more data. This is in case the sampling - * completes with less than 512 bytes in the fifo. - * - * In another phone conversation with Analogic, tech support told me that when - * the start signal is de-asserted (when using external start/stop mode), the - * sequence program pointer is reset to 0 (zero). This is fine and dandy, but - * it can cause the mux stage/pipeline to start improperly. Thus causing the - * first data sample to be corrupt. - * - * BUGS: - * The driver should inspect the VXI make and model codes and use a data type - * for the DMA buffer that is appropriate. - * - * $Log$ - * - */ - -static char *SccsId = "$Id$"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* general constants */ -#define DVX_ID 0xCFF5 /* analogic ID code */ -#define MAX_DVX_CARDS 5 /* max # of 2502 cards per IOC */ -#define MAX_PORTS 3 /* max # of 2601 cards per 2502 */ -#define DVX_DRATE 0xFFEC /* default scan rate of 184 KHz */ -#define DVX_SRATE 0xF201 /* slow scan used for run away mode */ -#define DVX_RAMSIZE 2048 /* sequence RAM size (words) */ -#define DVX_NBUF 1 /* default # of input buffers */ - -/* modes of operation */ -#define INIT_MODE 0 /* initialization mode */ -#define RUN_MODE 1 /* aquisition mode */ - -/* self test constants */ -#define TST_RATE 0x3ED /* self test scan rate */ -#define TST_THRESH 0xD00 /* mux card test threshold reg value */ - -/* csr command bits */ -#define CSR_RESET 0x01 /* software reset */ -#define CSR_M_START 0x10 /* internal scan start */ -#define CSR_M_ETRIG 0x40 /* external trigger enable */ -#define CSR_M_ESTART 0x20 /* external start enable */ -#define CSR_M_SYSFINH 0x02 /* system fail inhibit */ -#define CSR_M_A24 0x8000 /* enable sequence RAM */ -#define CSR_M_INT 0x80 /* interrupt enable */ -#define CSR_M_MXTST 0x3A /* mux card test bits */ - -/* csr status bits */ -#define S_NEPTY 0x02 /* fifo not empty when = 1 */ - -/* Sequence Program control codes */ -#define GAIN_CHANNEL 0x80 -#define ADVANCE_TRACK 0x40 -#define ADVANCE_HOLD 0xC0 -#define RESTART 0x00 - -/* analogic 2502 memory structure */ -struct dvx_2502 -{ - unsigned short dev_id; /* device id code (CFF5) */ - unsigned short dev_type; /* type code (B100) */ - unsigned short csr; /* control and status register */ - unsigned short seq_offst; /* sequence RAM offset register */ - unsigned short mem_attr; /* memory attribute register */ - unsigned short samp_rate; /* sample rate register */ - unsigned short dma_point; /* DMA pointer register */ - unsigned short dma_data; /* DMA data register */ - unsigned short thresh; /* threshold register */ - unsigned short fifo; /* input fifo */ - unsigned short end_pad[54]; /* pad to 64 byte boundary */ -}; - -/* input buffer */ -struct dvx_inbuf -{ - struct dvx_inbuf *link; /* link to next buffer */ - int wordcnt; /* # of words read to clear fifo */ - short *data; /* data buffer */ -}; - -/* analogic 2502 control structure */ -struct dvx_rec -{ - struct dvx_2502 *pdvx2502; /* pointer to device registers */ - short *sr_ptr; /* pointer to sequence RAM */ - struct dvx_inbuf *inbuf; /* pointer to current buffer */ - short unsigned csr_shadow; /* csr shadow register */ - short mode; /* operation mode (init or run) */ - int int_vector; /* interrupt vector */ - int intcnt; /* interrupt count # */ - int cnum; /* card number */ - - int dmaSize; /* samples to read before IRQ */ - unsigned int numChan; /* total number of ports to read */ - unsigned long pgmMask[8]; /* ports to be read by seq-program */ - unsigned short gain[8]; /* port gains */ - - int RearmMode; /* zero if auto-rearm, else manual */ - - IOSCANPVT *pioscanpvt; -}; - -/* dma chain table size */ -#define DVX_CTBL 34 /* max size of chain table */ - -/* am9516 register select constants. - * The DMA control registers are accessed through the dvx2502 registers - * dma_point and dma_data. The constants below are the addresses which must - * be loaded into the pointer register to access the named register through - * the data register. All dual registers are commented as #2. To access channel - * #1, OR the value M_CH1 with the channel #2 address. - */ -#define DMA_MMR 0x38 /* master mode register */ -#define DMA_CSR 0x2C /* command/status register #2 */ -#define DMA_CARAH 0x18 /* current address reg A high #2 */ -#define DMA_CARAL 0x08 /* current address reg A low #2 */ -#define DMA_CARBH 0x10 /* current address reg B high #2 */ -#define DMA_CARBL 0x00 /* current address reg B low #2 */ -#define DMA_BARAH 0x1C /* base address reg A high #2 */ -#define DMA_BARAL 0x0C /* base address reg A low #2 */ -#define DMA_BARBH 0x14 /* base address reg B high #2 */ -#define DMA_BARBL 0x04 /* base address reg B low #2 */ -#define DMA_COC 0x30 /* current operation count #2 */ -#define DMA_BOC 0x34 /* base operation count #2 */ -#define DMA_ISR 0x28 /* interrupt save register #2 */ -#define DMA_IVR 0x58 /* interrupt vector register #2 */ -#define DMA_CMRH 0x54 /* channel mode register #2 */ -#define DMA_CMRL 0x50 /* channel mode register #2 */ -#define DMA_CARH 0x24 /* chain address reg high #2 */ -#define DMA_CARL 0x20 /* chain address reg low #2 */ -#define M_CH1 0x2 /* mask for chan 1 reg addresses */ - -/* am9516 command constants - * All dual commands are commented as #1. To command channel #2, OR the - * valur M_CH2 with the channel #1 command. - */ -#define MMR_ENABLE 0x0D /* chip enable value */ -#define CMR_RESET 0x0 /* reset all channels */ -#define CMR_START 0xA0 /* start channel #1 */ -#define CMR_SSR 0x42 /* set software request #1 */ -#define CMR_CSR 0x40 /* clear software request #1 */ -#define CMR_SHM 0x82 /* set hardware mask #1 */ -#define CMR_CHM 0x80 /* clear hardware mask #1 */ -#define CMR_SC 0x22 /* set CIE/IP #1 */ -#define CMR_CC 0x20 /* clear CIE/IP #1 */ -#define CMR_SFB 0x62 /* set flip bit #1 */ -#define CMR_CFB 0x60 /* clear flip bit #1 */ -#define M_CIE 0x10 /* int enable bit mask (SC/CC cmd) */ -#define M_IP 0x4 /* int pending bit mask (SC/CC cmd) */ -#define M_CH2 0x1 /* mask for channel #2 commands */ - -/* am9516 chain reload constants */ -#define R_CAR 0x1 /* chain address */ -#define R_CMR 0x2 /* channel mode */ -#define R_IVR 0x4 /* interrupt vector */ -#define R_PMR 0x8 /* pattern and mask */ -#define R_BOC 0x10 /* base operation count */ -#define R_BAB 0x20 /* base address register B */ -#define R_BAA 0x40 /* base address register A */ -#define R_COC 0x80 /* current operation count */ -#define R_CAB 0x100 /* current address register B */ -#define R_CAA 0x200 /* current address register A */ - -/* If any of the following does not exist replace it with #define <> NULL */ -long dvx_io_report(int level); -static long dvx_driver_init(void); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvDvx={ - 2, - dvx_io_report, - dvx_driver_init}; - -static struct dvx_rec dvx[MAX_DVX_CARDS] = { -{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff} -,{0, 0, 0, 0, 0, 0, 0, 0}, -0 , NULL -}, -{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff} -,{0, 0, 0, 0, 0, 0, 0, 0}, -0, NULL -}, -{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff} -,{0, 0, 0, 0, 0, 0, 0, 0}, -0, NULL -}, -{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff} -,{0, 0, 0, 0, 0, 0, 0, 0}, -0, NULL -} -}; - -static int DVX_INTLEV=5; /* allow this to be user setable */ -static int dvxOnline = 0; /* 1 after init invoked */ - -#ifdef __STDC__ -int lclToA24(void *pLocal, void **ppA24); -static void dvx_reset(void); -static void dvx_int(struct dvx_rec *dvxptr); -static int muxtst(int card); -static int sramld(int card); -static int dvx_driver( int card, int chan, short *pval); -int dvx_dread(int card,int chan); -int dvx_dump(int card,int firstchan,int lastchan); -int dvx_chan_print(int dvx_card, int firstchan, int lastchan); -static int dvx_fempty(int card); -static int dvx_dma_init(struct dvx_rec *ptr); -static int dvx_dma_reset(struct dvx_rec *ptr); -int dvx_dma_stat(int card, int chan); -#else /* __STDC__ */ - -int lclToA24(); -static void dvx_reset(); -static void dvx_int(); -static int muxtst(); -static int sramld(); -int dvx_driver(); -int dvx_dread(); -int dvx_dump(); -int dvx_chan_print(); -static int dvx_fempty(); -static int dvx_dma_init(); -static int dvx_dma_reset(); -int dvx_dma_stat(); - - -#endif /* __STDC__ */ - - -int dvxDebug = 0; - - -/* - * dvx_int - * - * interrupt service routine - * - */ -LOCAL void -dvx_int(struct dvx_rec *dvxptr) -{ - /* BUG --- why are there STATIC variables in here????? */ - - static short i, junk; - register struct dvx_2502 *cptr; - static unsigned int tick, t, intlev; - - cptr = dvxptr->pdvx2502; - cptr->dma_point = DMA_CSR; - cptr->dma_data = CMR_CC | M_IP | M_CH2; /* clear dma int channel #2 */ - cptr->csr = dvxptr->csr_shadow & 0xff5f; /* disable fifo interrupts */ - switch (dvxptr->mode) - { - /* - * interrupt recieved during initialization - * - empty fifo and throw away data - */ - case INIT_MODE: - if(dvxDebug) - logMsg("dvx_int: INIT_MODE\n"); - dvxptr->intcnt = 0; /* initialize interrupt count */ - for (i = 0; cptr->csr & 0x2; i++) - junk = cptr->fifo; - break; - /* - * interrupt recieved during data aquisition - * - empty fifo into next input buffer, then make it current - */ - case RUN_MODE: - if(dvxDebug) - logMsg("dvx_int: RUN_MODE\n"); - dvxptr->intcnt++; /* incriment interrupt count */ - - dvxptr->inbuf = dvxptr->inbuf->link; /* update current data buffer */ - - for (i = 0; cptr->csr & S_NEPTY; i++, junk = cptr->fifo); - - dvxptr->inbuf->wordcnt = i; /* record # of words to clear fifo */ - - if (dvxptr->RearmMode == 0) - { - /* enable DMA opeations */ - cptr->dma_point = DMA_CSR; - - /* enable int channel #2 */ - cptr->dma_data = CMR_SC | M_CIE | M_CH2; - - /* start channel #2 */ - cptr->dma_data = CMR_START | M_CH2; - } - - scanIoRequest(*(dvxptr->pioscanpvt)); - break; - } - cptr->csr = dvxptr->csr_shadow; -} - -int dvx_RearmModeSet(int card, int mode) -{ - /* make sure hardware exists */ - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) - return(-1); - - dvx[card].RearmMode = mode; - return(0); -} - -int dvx_rearm(int card) -{ - struct dvx_rec *dvxptr; - struct dvx_2502 *cptr; - int i; - short junk; - - /* make sure hardware exists */ - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) - return(-1); - else if(dvx[card].pdvx2502 == NULL) - return(-2); - - dvxptr = &dvx[card]; - cptr = dvxptr->pdvx2502; - - if (dvxptr->RearmMode == 0) - return(-3); - -#if 0 - cptr = dvxptr->pdvx2502; - cptr->dma_point = DMA_CSR; - cptr->dma_data = CMR_CC | M_IP | M_CH2; /* clear dma int channel #2 */ - cptr->csr = dvxptr->csr_shadow & 0xff5f; /* disable fifo interrupts */ -#endif - - /* Drain the fifo of any crud */ - for (i = 0; cptr->csr & S_NEPTY; i++, junk = cptr->fifo); - - if (dvxDebug) - printf("dvx_rearm(%d) fifo residual = %d\n", card, i); - - /* enable DMA opeations */ - cptr->dma_point = DMA_CSR; - - /* enable int channel #2 */ - cptr->dma_data = CMR_SC | M_CIE | M_CH2; - - /* start channel #2 */ - cptr->dma_data = CMR_START | M_CH2; - - return(0); -} - - -/* - * dvx_driver_init - * - * initialization for 2502 cards - * - */ -LOCAL long dvx_driver_init(void) -{ - int i; - int j; - int status; - unsigned short card_id; - short *ramptr; - struct dvx_inbuf *ibptr; - struct dvx_inbuf *ibptra; - int intvec = DVX_IVEC0; - struct dvx_2502 *pDvxA16; - short *pDvxA24; - short *pDvxA24Bus; - - /* - * dont continue DMA while vxWorks is control X - * rebooting (and changing bus arbitration mode) - * joh 072591 - */ - rebootHookAdd(dvx_reset); - - dvxOnline = 1; /* do not allow any more user config modifications */ - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - ai_addrs[DVX2502], - &pDvxA16); - if (status != OK){ - logMsg( "%s: A16 base addr problems DVX 2502\n", - __FILE__); - return ERROR; - } - - - /* - * search for DVX cards - */ - for ( i = 0, pDvxA24Bus = (short *)ai_memaddrs[DVX2502]; - i < ai_num_cards[DVX2502]; - i++, pDvxA16++, pDvxA24Bus += DVX_RAMSIZE) - { -# ifdef DEBUG - logMsg("Probing for DVX at %x\n", pDvxA16); -# endif - - dvx[i].pdvx2502 = NULL; - status = vxMemProbe ( - &pDvxA16->dev_id, - READ, - sizeof(card_id), - &card_id); - if (status <0){ - continue; - } - if (card_id != DVX_ID){ /* see if detected card is a 2502 */ - logMsg("%s: Card installed at addr=0X%x is not a dvx2502\n", - __FILE__, - pDvxA16); - continue; - } - - /* Card found! Finish the init for it. */ - - dvx[i].cnum = i; /* record card number */ - pDvxA16->csr = CSR_RESET; /* software reset */ - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - pDvxA24Bus, - &pDvxA24); - if (status != OK){ - logMsg( "%s: A24 base addr problems DVX 2502 A24=%x\n", - __FILE__, - pDvxA24Bus); - continue; - } - - /* - * check for incorrectly addressed card in A24 - */ - status = vxMemProbe (pDvxA24, READ, sizeof(card_id), &card_id); - if (status == OK){ - logMsg( "%s: A24 responding where DVX should be addr=%x\n", - __FILE__, - pDvxA24); - logMsg( "%s: DVX card=%d ignored\n", - __FILE__, - i); - continue; - } - - - if ((dvx[i].pioscanpvt = (IOSCANPVT *) malloc(sizeof(IOSCANPVT))) == NULL) - return(-1); - if (dvx[i].dmaSize == 0) - { - logMsg("%s: No channels selected on card %d, init aborted\n", i); - continue; - } - - dvx[i].mode = INIT_MODE; /* initialization mode */ - /* create linked list of input buffers */ - for ( j = 0, ibptra = NULL; - j < DVX_NBUF; - j++, ibptra = ibptr) - { - - ibptr = (struct dvx_inbuf *)malloc(sizeof (struct dvx_inbuf)); - /* - * exit with error if buffer allocation fails - */ - if (ibptr == NULL) - return -1; /* unsuccessfull */ - - /* Needs to come from A24 mappable memory...? */ -#if 0 - if ((ibptr->data = (short *) malloc(dvx[i].dmaSize * sizeof(short))) == NULL) -#else - if ((ibptr->data = (short *) devLibA24Malloc(dvx[i].dmaSize * sizeof(short))) == NULL) -#endif - return(-1); - - if (dvxDebug) - printf("dvx_driver_init(%d) allocated ibp at %p buffer at %p\n", i, ibptr, ibptr->data); - if (j == 0){ - dvx[i].inbuf = ibptr; /* initialize if first */ - } - - ibptr->wordcnt = 0; - ibptr->link = ibptra; /* LINK TO last buffer */ - } - dvx[i].inbuf->link = ibptr; /* close list */ - - /* - * locate sequence RAM in an unassigned portion of VME A24 - * - * Use the A24 bus address since the processor may not have placed - * A24 on a 16 MB boundary - */ - pDvxA16->seq_offst = (int)pDvxA24Bus>>8; - dvx[i].csr_shadow = CSR_M_A24; /* enable sequence RAM (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* enable sequence RAM */ - - /* - * record card address and allocate input buffers - */ - dvx[i].pdvx2502 = pDvxA16; /* record card address */ - - /* - * locate and enable sequence RAM - */ - dvx[i].sr_ptr = pDvxA24; /* record seq RAM address */ - - /* - * set up interrupt handler - */ - dvx[i].csr_shadow |= (intvec<<8); /* load int vector (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* load int vector */ - dvx[i].int_vector = intvec; /* save interrupt vector # */ - status = intConnect(INUM_TO_IVEC(intvec),dvx_int,&dvx[i]); - if (status != OK) - return -2; /* abort if can't connect */ - sysIntEnable(DVX_INTLEV); /* enable interrupt level */ - - /* make sure the DMA chip is fully disabled */ - dvx_dma_reset(dvx[i].pdvx2502); - - dvx[i].csr_shadow |= CSR_M_INT; /* enable fifo int (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* enable fifo interrupts */ - intvec++; /* advance to next vector # */ - - /* - * test mux cards and load sequence RAM - */ - muxtst(i); /* test mux cards */ - sramld(i); /* load scan program */ - - dvx[i].csr_shadow ^= CSR_M_INT; /* disable fifo int (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* disable fifo interrupts */ - /* - * initialize DMA - */ - dvx_dma_init(&dvx[i]); /* initialize DMA controller */ - /* - * set scan rate and enable external start - */ - pDvxA16->samp_rate = DVX_DRATE; /* scan rate of 184 KHz */ - dvx[i].csr_shadow |= CSR_M_ESTART; /* enable ext start (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* enable external start */ - dvx[i].mode = RUN_MODE; /* ready to aquire data */ - scanIoInit(dvx[i].pioscanpvt); - } - - return 0; /* return 0 to database */ -} - - -/* - * muxtst - * - * test multiplexer cards - * I suspect this test does nothing more than light the pass LED on all - * the 2601 multiplexer cards. - * - */ -LOCAL int muxtst(int card) -{ - int i; - short *ramptr; - - /* - * inhibit sys fail and load test setup parameters - */ - dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_SYSFINH; - ramptr = dvx[card].sr_ptr; /* pointer to sequence RAM */ - dvx[card].pdvx2502->thresh = TST_THRESH; /* load test threshold */ - dvx[card].pdvx2502->samp_rate = TST_RATE; /* test sample rate */ - /* - * load test program into sequence RAM - */ - for (i = 0; i < MAX_PORTS; i++) - { - *ramptr++ = GAIN_CHANNEL; /* first sequence RAM value */ - *ramptr++ = ADVANCE_HOLD | i; /* mux card select */ - } - *ramptr++ = RESTART; /* end of scan */ - *ramptr = RESTART; - /* - * run test and restore csr - */ - dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_MXTST; - taskDelay(sysClkRateGet()); /* let test run */ - dvx[card].pdvx2502->csr = dvx[card].csr_shadow; - dvx[card].pdvx2502->thresh = 0; /* restore threshold */ -} - -/* - * dvx_program() is used to define what ports on what boards to scan - * when taking a sample. Each time a start pulse is supplied to the DVX - * board, it will read from the ports in the specified by the user. When - * dmaSize samples have been taken (possibly after many start pulses) the DMA - * controller will terminate transferring data and generate a completion event. - * After this event, the whole process starts over again with the next start - * pulse. - * - * The dvx_program() parms are simply a bit mask of what ports to read from - * each board. There may be up to 8 boards on one DVX master. The bit masks - * are 32 bit unsigned numbers that should be assigned during the startup - * script when booting the IOC. - * - * To program a DVX card (card 0) to read all ports from 2 S/H muxes (boards 2 - * and 6) and 1 mux (board 1). You may do the following. - * - * dvx_program(0, 2, 0x0000ffff, 0, 0) -- 16 ports from board 2 gain = 1 - * dvx_program(0, 6, 0x0000ffff, 0, 2) -- 16 ports from board 6 gain = 4 - * dvx_program(0, 1, 0xffffffff, 64, 3) -- 32 ports from board 1 gain = 8 - * - * The 64 on the last line specified that we want to read 64 samples before the - * DMA is considered complete. The last dvx_program() value for the dma size - * is the only one that is used, all previous are discarded. - * - * If so desired, the above example could have used 128 for the DMA size value. - * in this case, the dvx 'system' would not consider the sample complete until - * all the ports were read twice. - * - * NOTE: Each card has its own notion of DMA size. Each card also has its - * own notion of default values. If no programming is done for a - * specific card number, its default values will be used. - * - * The ports are read from the lowest board number and lowest port number first. - */ -int -dvx_program(int card, int board, unsigned long mask, int dmaSize, int gain) -{ - int i; - unsigned long maskCheck; - int numSamp; - static int firstTime = 1; - - if (dvxOnline) - { - printf("DVX cards are already on line, no modifications allowed\n"); - return(-1); - } - if ((card < 0) || (card > ai_num_cards[DVX2502])) - { - printf("dvx_program(%d, %d, 0x%08.8X): invalid card number specified\n", card, board, mask); - return(1); - } - if ((board < 0) || (board > 7)) - { - printf("dvx_program(%d, %d, 0x%08.8X): invalid board number specified\n", card, board, mask); - return(2); - } - if ((gain < 0) || (gain > 3)) - { - errPrintf(-1, __FILE__, __LINE__, - "dvx_program(%d, %d, 0x%08.8X, %d, %d): invalid gain specified\n", card, board, - mask, dmaSize, gain); - return(2); - } - if (firstTime) - { /* Clear out the default port numbers, this is the first dvx_program call */ - int i; - - firstTime=0; - for (i=0; i<8; i++) - dvx[card].pgmMask[i] = 0; - } - - dvx[card].pgmMask[board] = mask; - dvx[card].dmaSize = dmaSize; - dvx[card].gain[board] = gain; - - return(0); -} - -/* - * Allow the user to specify the interrupt level number - * - * It returns the 'old' IRQ level value. - * - * NOTE that off the shelf DVX2502s are set to use IRQ level 1 - */ - -int dvx_setIrqLevel(int level) -{ - int i; - - if (dvxOnline) - { - printf("DVX card(s) already initialized at level %d, new IRQ level ignored\n", DVX_INTLEV); - return(DVX_INTLEV); - } - i = DVX_INTLEV; - DVX_INTLEV = level; - return(i); -} - -/* - * This can be called by a user program to get information about how - * the dvx card is programmed. - */ -int dvx_getProgram(int card, int *dmaSize, int *numChan) -{ - *dmaSize = dvx[card].dmaSize; - *numChan = dvx[card].numChan; - - if (dvxDebug) - printf("total DMA samples=%d, total number of physical channels=%d\n", *dmaSize, *numChan); - - return(-1); -} - -/* - * This version of the sequence program loader allows the number of channels - * to be programmable. It is assumed that the programmable constants will - * be fetched from the user. - * - */ -LOCAL -int sramld(int card) -{ - short *ramptr; - int i, port, firstPort; - unsigned long mask; - - /* load sequence program */ - ramptr = dvx[card].sr_ptr; /* point to sequence RAM */ - dvx[card].numChan = 0; - - for (i=0; i<8; i++) - { - mask = 1; - port = 0; - firstPort = -1; - - while(port < 32) - { - if (mask & dvx[card].pgmMask[i]) - { /* I need to read a sample from this port */ - if (firstPort == -1) - { /* save this one for prescan */ - firstPort = port; - } - else - { - *ramptr++ = GAIN_CHANNEL | (dvx[card].gain[i] <<3) | ((port >> 3) & 3); - *ramptr++ = ADVANCE_HOLD | ((port & 0x07) << 3) | i; - dvx[card].numChan++; - if (dvxDebug) - printf("board %d, port %d\n", i, port); - } - } - mask <<= 1; - port++; - } - if (firstPort != -1) - { /* Put the first port number to read on each board, last in scan list. */ - *ramptr++ = GAIN_CHANNEL | (dvx[card].gain[i] << 3) | ((firstPort >> 3) & 3); - *ramptr++ = ADVANCE_HOLD | ((firstPort & 0x07) << 3) | i; - dvx[card].numChan++; - if (dvxDebug) - printf("board %d, port %d\n", i, firstPort); - } - } - if (dvxDebug) - printf("Total channels read in %d\n", dvx[card].numChan); - -#if 1 /* This causes an extra sample to be taken at the end of the scan */ - *ramptr++ = 0; /* mark the end of the sequence program */ - *ramptr++ = 0; -#else /* This was supposed to get rid of the extra one, but does not work */ - *(ramptr-1) &= 0xff3f; - *ramptr = *(ramptr-1); -#endif - - /* set scan rate and run it once */ - dvx[card].pdvx2502->samp_rate = DVX_DRATE; - dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_START; - taskDelay(sysClkRateGet()); /* let scan run */ - dvx[card].pdvx2502->csr = dvx[card].csr_shadow; /* restore csr */ -} - -/* - * dvx_driver - * - * interface to analog input buffer - * - */ -int dvx_driver( -int card, -int chan, -short *pval -) -{ - short ival; - - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) /* make sure hardware exists */ - return -1; - else if (dvx[card].pdvx2502 == NULL) - return -2; - else if (chan > dvx[card].dmaSize) - return -2; - - *pval = dvx[card].inbuf->data[chan]; - return 0; -} - -/* - * dvxReadWf - * - * Allows a waveform record to read all samples from the dvx buffer as a - * waveform. - */ -int dvxReadWf(int card, int start, int num, short *pwf, unsigned long *numRead) -{ - int dataIndex; - - if(dvxDebug) - printf("dvxReadWf(%d, %d, %d, 0x%08.8X, 0x%08.8X)\n", card, start, num, pwf, numRead); - - *numRead = 0; /* in case we have an error condition */ - - /* make sure hardware exists */ - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) - return(-1); - else if ((dvx[card].pdvx2502 == NULL)||(start > dvx[card].dmaSize)|| - (start < 0)||(num < 1)) - return(-2); - - /* if user asked for too many, chop off the length to that available */ - if (start+num > dvx[card].dmaSize) - num -= (start+num) - dvx[card].dmaSize; - - dataIndex = start+num; - *numRead = num; - - if (dvxDebug) - printf("dvxReadWf(): Actual elements read: %d\n", num); - - while(num) - { - num--; - dataIndex--; - pwf[num] = dvx[card].inbuf->data[dataIndex]; - } - return(0); -} - - -/* - * dvx_dread - * - * stand alone interface to dvx_driver - * - */ -int dvx_dread(int card,int chan) -{ - short stat; - short unsigned data; - float volts; - - stat = dvx_driver(card,chan,(short *)&data); - volts = data * 10./32767. - 10; - printf("channel # %d\tdata = %x\tvolts = %f\n" - ,chan,data,volts); -} - - -/* - * dvx_dump - * - * dump RAM buffer - * - */ -int dvx_dump(int card,int firstchan,int lastchan) -{ - int i, port, ix, printing, tmp; - short unsigned data; - unsigned long mask; - float volts; - - printf("Entering dvx_dump with card = %d,firstchan = %d,lastchan = %d\n",card,firstchan, - lastchan); - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) - return -1; - else if (dvx[card].pdvx2502 == 0) - return -2; - printf("buffer address = %x word count = %d interrupt count = %d\n", - dvx[card].inbuf,dvx[card].inbuf->wordcnt,dvx[card].intcnt); - if (dvx[card].pdvx2502->csr & 0x2) - printf("fifo status = not empty,"); - else - printf("fifo status = empty,"); - printf(" current input channel = %x\n", - (dvx[card].pdvx2502->csr & 0x3fc0)>>6); - - ix = 0; - printing= 1; - while ((ix < dvx[card].dmaSize) && (ix < lastchan) && printing) - { - printing = 0; - for (i=0; i<8; i++) - { - mask = 1; - port = 0; - while(port < 32) - { - if (mask & dvx[card].pgmMask[i]) - { - if (ix >= firstchan) - { - tmp = dvx[card].inbuf->data[ix]; - tmp &= 0x0000ffff; - - volts = tmp * 10./32767.; - printf("signal %2d, board %d, port %2d, data 0x%04.4X, voltage %f\n", ix, i, port, tmp, volts); - } - - ix++; - printing = 1; - } - mask <<= 1; - port++; - } - } - } - - printf("end of list\n"); - - return 0; -} - -dvx_getioscanpvt(int card, IOSCANPVT *scanpvt) -{ - if ((card >= ai_num_cards[DVX2502]) || (card < 0))return(0); - if (dvx[card].pdvx2502 == 0) return(0); - *scanpvt = *(dvx[card].pioscanpvt); - return(0); -} - -/* - * - * dvx_io_report - * - * -*/ -long dvx_io_report(int level) -{ - short int i; - unsigned short card_id; - - for (i = 0; i < ai_num_cards[DVX2502]; i++){ - if (!dvx[i].pdvx2502) - continue; - - /* If detected card is a 2502 print out its number. */ - printf("AI: DVX2505:\tcard %d\n",i); - - if(level > 0 ){ - int firstchan; - int lastchan; - - printf("Enter number of the first channel you wish to read:\n"); - scanf("%d",&firstchan); - printf("First channel is %d\n",firstchan); - printf("Enter number of the last channel you wish to read:\n"); - scanf("%d",&lastchan); - printf("Last channel is %d\n",lastchan); - dvx_dump(i,firstchan,lastchan); - } - } - - return OK; -} - - - -/* - * dvx_fempty - * - * empty fifo - * - */ -LOCAL int dvx_fempty(int card) -{ - int i, junk; - - if ((card>= ai_num_cards[DVX2502]) || (card < 0)) - return -1; - else if (dvx[card].pdvx2502 == 0) - return -2; - for (i = 0; dvx[card].pdvx2502->csr & 0x2; i++) - junk = dvx[card].pdvx2502->fifo; - printf("%d words read from fifo\n",i); - return 0; -} - - -LOCAL dvx_dma_reset(struct dvx_2502 *dev) -{ - dev->dma_point = DMA_CSR; - dev->dma_data = CMR_RESET; /* reset the thing */ - return(0); -} - -/* - * dvx_dma_init - * - * am9516 DMA controller initialization - * - * local to A24 bus addr conversions below are necessary on processors - * that dont place the local base for A24 on an even 16 MB boundary - */ -LOCAL dvx_dma_init(struct dvx_rec *ptr) -{ - int i, j; - int status; - short *cptr, *cptra, *cptr0, *pext; - short *BusPtr; - struct dvx_2502 *dev; - struct dvx_inbuf *bpnt; - - dev = ptr->pdvx2502; /* point to hardware */ - - dvx_dma_reset(dev); /* reset the DMA chip */ - - /* build chain table, needs to come from A24 mappable memory */ -#if 0 - if ((cptr = cptr0 = (short *)malloc(DVX_CTBL)) == NULL) -#else - if ((cptr = cptr0 = (short *)devLibA24Malloc(DVX_CTBL)) == NULL) -#endif - return -1; - dev->dma_point = DMA_MMR; /* enable chip */ - dev->dma_data = MMR_ENABLE; - - /* - * The 2502 uses A24 priv data VME addr mods - * for its DMAchain operations - */ - status = sysLocalToBusAdrs( - VME_AM_STD_SUP_DATA, - cptr, - &BusPtr); - if(status < 0){ - logMsg( "%s:Local chain addr 0x%X does not map to A24 bus addr\n", - __FILE__, - cptr); - return -1; - } - dev->dma_point = DMA_CARH; /* load init chain address */ - dev->dma_data = (int) BusPtr>>8 & 0xff00; - dev->dma_point = DMA_CARL; - dev->dma_data = (int) BusPtr & 0xffff; - - for ( i = 0, bpnt = ptr->inbuf->link; - i < DVX_NBUF; - i++, cptr = cptra, bpnt = bpnt->link) - { /* create chain for each input buffer */ - if ((i + 1) == DVX_NBUF) - cptra = cptr0; /* close list */ - else - /* needs to come from A24 mapped memory */ -#if 0 - if ((cptra = (short *)malloc(DVX_CTBL)) == NULL) -#else - if ((cptra = (short *)devLibA24Malloc(DVX_CTBL)) == NULL) -#endif - return -1; /* allocate next chain */ - - /* Set the reload word */ - *cptr++ = R_CAA | R_CAB | R_COC | R_CMR | R_CAR; /* load mask */ - - /* - * - * source options: - * 1) data (not chain) operation - * 2) hold (dont auto incr or decr) the src address - * - * The src addr here is ignored by the dvx2502 hardware - * and is therefore set to zero. The source is always - * the dvx 2502 fifo. - */ - *cptr++ = 0xd0; - *cptr++ = 0; /* address reg A (src) */ - - /* - * The 2502 uses A24 non-priv data VME addr mods - * for its DMA data transfers - */ - status = sysLocalToBusAdrs( - VME_AM_STD_USR_DATA, - bpnt->data, - &BusPtr); - if(status < 0){ - logMsg( "%s: Local dest addr 0x%X does not map to A24 addr\n", - __FILE__, - bpnt->data); - return -1; - } - *cptr++ = (((int)BusPtr>>8) & 0xff00) | 0xc0; - *cptr++ = (int) BusPtr & 0xffff; /* address reg B (dest) */ - - *cptr++ = ptr->dmaSize; /* operation count */ - *cptr++ = 0x4; - *cptr++ = 0x0252; /* dma mode control */ - - /* - * The 2502 uses A24 priv data VME addr mods - * for its DMA chain operations - */ - status = sysLocalToBusAdrs( - VME_AM_STD_SUP_DATA, - cptra, - &BusPtr); - if(status < 0){ - logMsg( "%s:Local addr 0x%X does not map to A24 addr\n", - __FILE__, - cptra); - return -1; - } - *cptr++ = (int)BusPtr>>8 & 0xff00; - *cptr = (int)BusPtr& 0xffff; /* next chain address */ - } - /* enable DMA opeations */ - dev->dma_point = DMA_CSR; - dev->dma_data = CMR_SC | M_CIE | M_CH2; /* enable int channel #2 */ - dev->dma_data = CMR_START | M_CH2; /* start channel #2 */ - return 0; -} - - -/* - * dvx_dma_stat - * - * reads status of dma channel - * - */ -int dvx_dma_stat(int card, int chan) -{ - struct dvx_2502 *ptr; - short unsigned temp; - - if ((card < 0) || (card > ai_num_cards[DVX2502])) - return -1; - else if (dvx[card].pdvx2502 == 0) - return -2; - else - { - ptr = dvx[card].pdvx2502; - temp = (chan & 0x1)<<1; - ptr->dma_point = DMA_CSR | temp; - printf("dma status = %X\n",ptr->dma_data); - ptr->dma_point = DMA_MMR; - printf("master mode register = %X\n",ptr->dma_data); - ptr->dma_point = DMA_CARH | temp; - printf("chain address = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_CARL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_CARAH | temp; - printf("current address register A = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_CARAL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_CARBH | temp; - printf("current address register B = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_CARBL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_BARAH | temp; - printf("base address register A = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_BARAL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_BARBH | temp; - printf("base address register B = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_BARBL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_COC | temp; - printf("current operation count = %4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_BOC | temp; - printf("base operation count = %4.4X\n",ptr->dma_data); - } - return 0; -} - - - -/* - * - * dvx_reset - * joh 072591 - * - */ -#if 0 /* This is hideous... should reset only those we started! */ -LOCAL void -dvx_reset(void) -{ - struct dvx_2502 *pDvxA16; - unsigned short card_id; - int i; - int status; - int card_found = FALSE; - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - ai_addrs[DVX2502], - &pDvxA16); - if (status != OK){ - logMsg( "%s: A16 base addr problems DVX 2502\n", - __FILE__); - return; - } - - /* - * search for cards - */ - for (i = 0; i < ai_num_cards[DVX2502]; i++, pDvxA16++){ - status = vxMemProbe ( - &pDvxA16->dev_id, - READ, - sizeof(card_id), - &card_id); - if (status != OK) - continue; - /* - * see if detected card is a 2502 - * and reset if so - */ - if (card_id == DVX_ID){ - /* reset the DMA controller */ - dvx_dma_reset(pDvxA16); - - pDvxA16->csr = CSR_RESET; - card_found = TRUE; - } - } - - /* - * wait long enough for the current DMA to end - * - * 1 sec - */ - if(card_found){ - printf("Waiting for DVX 2502 DMA to complete..."); - taskDelay(sysClkRateGet()); - printf("done\n"); - } -} -#else -LOCAL void -dvx_reset(void) -{ - int i; - int CardFound = 0; - - /* - * search for cards - */ - for (i = 0; i < ai_num_cards[DVX2502]; i++) - { - if (dvx[i].pdvx2502 != NULL) - { - dvx_dma_reset(dvx[i].pdvx2502); - dvx[i].pdvx2502->csr = CSR_RESET; - CardFound = 1; - } - } - /* - * wait long enough for the current DMA to end - * - * 1 sec - */ - if(CardFound) - { - printf("Waiting for DVX 2502 DMA to complete..."); - taskDelay(sysClkRateGet()); - printf("done\n"); - } -} -#endif diff --git a/src/drv/drvEpvxi.c b/src/drv/drvEpvxi.c deleted file mode 100644 index ed7c8d100..000000000 --- a/src/drv/drvEpvxi.c +++ /dev/null @@ -1,4448 +0,0 @@ -/* - * drvEpvxi.c - * - * base/src/drv $Id$ - * Routines for the VXI device support and resource management. - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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 joh 02-14-90 formal release - * .02 joh 04-04-90 as requested KLUDGED dynamic address so they - * dont have to specify model number in DCT - * .03 joh 04-04-90 as requested KLUDGED dynamic address so they - * dont have to specify model number in DCT - * .04 joh 07-26-90 changed from ttl trig 7 to ecl trig 0 - * .05 joh 07-27-90 added support for multiple slot0 cards - * .06 joh 08-08-91 delinting - * .07 joh 09-05-91 converted to v5 vxWorks - * .08 joh 12-05-91 split vxi_driver.c into vxi_driver.c and - * vxi_resman.c - * .09 joh 01-29-91 added MXI support & removed KLUDGE - * .10 joh 07-06-92 added A24 & A32 address config - * .11 joh 07-07-92 added routine to return A24 or A32 base - * .12 joh 07-13-92 merged in model hash support written by - * Richard Baker (summer intern) - * .13 joh 07-21-92 Now stores extender info in a hierarchical - * linked list - * .14 joh 07-29-92 vxi record topology needed check for - * device present - * .15 joh 07-29-92 added sccs id - * .16 joh 08-19-92 make name registration - * .17 joh 08-21-92 cleaned up A24/A32 MXI setup - * .18 joh 08-26-92 dont return error if a make or model - * has already been registered - * .19 joh 09-03-92 Use the correct routine in NIVXI - * for CPU030 trigger routing - * .20 joh 09-30-92 split epvxiOpen() into epvxiOpen() and - * epvxiDeviceVerify() - * .21 joh 10-30-92 NI CPU030 trigger routing was failing - * due to no entry for the 030 in the resman - * tables - it cant see itself in A16. - * A work around was installed. - * .22 joh 05-24-93 Fixed over-zealous parameter checks in - * TTL trigger route - * .23 joh 06-03-93 Fixed incorrect MXI BP TTL trigger enable - * .24 joh 07-12-93 Record the task id when opening a device - * .25 joh 07-21-93 Improved DC device allocation in MXI - * environment - * .26 joh 11-10-93 Now configures multiple DC devices per slot. - * Blocked address devices are preallocated - * where possible. Independently addressed - * multiple devices per slot are allocated on - * demand. - * - * RM unfinished items - * ------------------- - * 1. Assigning the cmdr/serv hierarchy from within a DC res man - * needs to be revisited - * 2. Should this module prevent two triggers from driving - * the same front panel connector at once? - * - * - * NOTES - * ----- - * - * - */ - -/* - * Code Portions - * - * local - * vxi_find_slot given a VXI modules addr find its slot - * vxi_init_ignore_list init list of interrupt handlers to ignore - * vxi_vec_inuse check to see if vector is in use - * vxi_configure_hierarchies setup commander servant hierarchies - * vxi_self_test test for dev self test passed - * open_slot0_device open slot zero devices - * nicpu030_init NI CPU030 controller setup - * nivxi_cpu030_set_modid set modid on the NICPU030 - * nivxi_cpu030_clr_all_modid clear all modid lines on the NICPU030 - * set_reg_modid set modid on a reg based slot0 device - * clr_all_reg_modid clr all modid on a reg based slot0 dev - * vxi_find_sc_devices find all SC devices and open them - * vxi_find_dc_devices find all DC devices and open them - * vxi_count_dc_devices determine the number of DC devices in - * this extender - * vxi_init_ignore_list find addresses of default int handlers - * vxi_vec_inuse test for int vector in use - * mxi_map mat the addresses on a MXI bus extender - * vxi_find_mxi_devices search for and open mxi bus repeaters - * map_mxi_inward map from a VXI crate towards the RM - * vxi_address_config setup A24 and A32 offsets - * open_vxi_device log VXI device info - * vxi_record_topology find slots and extenders for each device - * - * for use by IOC core - * epvxiResman entry for a VXI resource manager which - * also sets up the MXI bus - * epvxiIOReport call io device specific report routines - * for all registered devices and print - * information about device's configuration - * epvxiDeviceList print info useful when debugging drivers - * vxi_init backwards compatibility - * vxi_io_report backwards compatibility - * - * for use by vxi drivers - * epvxiLookupLA find LA given search pattern - * epvxiUniqueDriverID obtain a unique id each call - * epvxiOpen register a drivers use of a device - * epvxiClose disconnect from a device - * epvxiPConfig fetch a driver config block given a LA - * epvxiRouteTriggerECL route ECL trig to/from front panel - * epvxiRouteTriggerTTL route TTL trig to/from front panel - * - */ - -static char *sccsId = "$Id$\t$Date$"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if 0 -#include -#endif - -#include -#define SRCepvxiLib /* allocate externals here */ -#include -#include - -#define NICPU030 - -/* - * EPICS driver entry point table - */ -typedef long (*DRVSUPFUN) (); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvVxi={ - 2, - epvxiIOReport, - epvxiResman}; - - -/* - * so setting ECL triggers does not mess with the - * RM's address windows - */ -#define MXI_CONTROL_CONSTANT 0x4000 -#define INTX_INT_OUT_ENABLE 0x7f00 -#define INTX_INT_IN_ENABLE 0x7f7f - -#define abort(A) taskSuspend(0) - -#define VXIMSGINTLEVEL 1 - -#define BELL 7 - -#define UKN_LA (-1) -#define UKN_SLOT (-1) -#define UKN_CRATE (-1) - -#define DEFAULT_VXI_A24_BASE 0x90000 -#define DEFAULT_VXI_A24_SIZE 0x10000 -#define DEFAULT_VXI_A32_BASE 0x90000000 -#define DEFAULT_VXI_A32_SIZE 0x10000000 - -/* - * laPassLast and laPassFirst must be last/first respectively - * and have no purpose outside of being delimiters - */ -enum laPass { - laPassSC, - laPassAnchoredDC, - laPassFloatingDC, - laPassSetWindows}; - - -LOCAL char niCpu030Initialized; -LOCAL VXIE root_extender; -LOCAL ELLLIST crateList; - -LOCAL char *ignore_list[] = {"_excStub","_excIntStub"}; -LOCAL void *ignore_addr_list[NELEMENTS(ignore_list)]; -LOCAL unsigned char last_la; -LOCAL unsigned char first_la; - -#define SETMODID(PVXISZ, SLOT) \ -(*(PVXISZ)->set_modid)((PVXISZ), SLOT) - -#define CLRMODID(PVXISZ) \ -(*(PVXISZ)->clear_modid)(PVXISZ); - -LOCAL -SYMTAB *epvxiSymbolTable; -LOCAL -char epvxiSymbolTableDeviceIdString[] = "%03x:%03x"; -LOCAL -char epvxiSymbolTableMakeIdString[] = "%03x"; - -/* - * for the VXI symbol table - * just contains model names for now - */ -#define EPVXI_MODEL_NAME_SYMBOL 1 -#define EPVXI_MAKE_NAME_SYMBOL 2 -#define EPVXI_MAX_SYMBOLS_LOG2 8 -#define EPVXI_MAX_SYMBOLS (1<la_mapped){ - break; - } - vxi_find_dc_devices(pvxie); - break; - - - /* - * allocate DC devices - */ - case laPassAnchoredDC: - /* - * wait until laPassFloatingDC if - * nothing is mapped - */ - if(!pvxie->la_mapped){ - break; - } - vxi_find_dc_devices(pvxie); - break; - - default: - break; - } - - /* - * - * find any MXI bus repeaters - * - */ - vxi_find_mxi_devices( - pvxie, - pass); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_unmap_mxi_devices() - * - * close any MXI devices which have open windows but - * have not been encountered by this execution - * of the resource manager. - * - * This makes the MXI/VXI configure correctly after - * a control x (soft) reboot. - */ -LOCAL void vxi_unmap_mxi_devices(void) -{ - struct vxi_csr *pmxi; - EPVXISTAT status; - int16_t id; - unsigned addr; - - for(addr=first_la; addr<=last_la; addr++){ - /* - * only configure devices not seen before - */ - if(epvxiLibDeviceList[addr]){ - continue; - } - - pmxi = VXIBASE(addr); - - status = vxMemProbe( (char *)pmxi, - READ, - sizeof(id), - (char *)&id); - if(status<0){ - continue; - } - - if(!VXIMXI(pmxi)){ - continue; - } - - /* - * force all of these back to the hard reset state - */ - pmxi->dir.w.dd.mxi.la_window = 0; - pmxi->dir.w.dd.mxi.a16_window_low = 0; - pmxi->dir.w.dd.mxi.a16_window_high = 0; - pmxi->dir.w.dd.mxi.a24_window_low = 0; - pmxi->dir.w.dd.mxi.a24_window_high = 0; - pmxi->dir.w.dd.mxi.a32_window_low = 0; - pmxi->dir.w.dd.mxi.a32_window_high = 0; - } -} - - - -/* - * - * vxi_find_mxi_devices() - * - */ -LOCAL void vxi_find_mxi_devices( -VXIE *pvxie, -enum laPass pass -) -{ - struct vxi_csr *pmxi; - unsigned addr; - VXIDI *pvxidi; - VXIE *pnewvxie; - - for( addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - - /* - * only configure devices seen before - */ - if(!pvxidi){ - continue; - } - - /* - * skip MXI devices which are not - * in this extender - */ - if(pvxidi->pvxie != pvxie){ - continue; - } - - pmxi = VXIBASE(addr); - - pnewvxie = open_mxi_device( - addr, - pvxie, - ext_import_mxi_into_vxi); - if(!pnewvxie){ - continue; - } - - /* - * open the LA window outward over the entire LA range - */ - pmxi->dir.w.dd.mxi.control = - MXI_UPPER_LOWER_BOUNDS; - pmxi->dir.w.dd.mxi.la_window = - VXIADDRMASK | (VXIADDRMASK<la_mapped){ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, pnewvxie->la_low); - pvxie->la_high = max(pvxie->la_high, pnewvxie->la_high); - } - - /* - * disable the window until the last pass - */ - if(pass != laPassSetWindows){ - pmxi->dir.w.dd.mxi.la_window = - 0 | (0<la_mapped){ -# ifdef DEBUG - printf( "VXI resman: VXI to MXI(%x) %x-%x\n", - addr, - pnewvxie->la_low, - pnewvxie->la_high); -# endif - pmxi->dir.w.dd.mxi.la_window = - (pnewvxie->la_low<la_high+1); - - /* - * if INTX is installed gate the interrupts off of - * INTX - */ - if(MXIINTX(pmxi)){ - pmxi->dir.w.dd.mxi.INTX_interrupt = - INTX_INT_IN_ENABLE; - } - } - else{ - printf( "VXI resman: VXI to MXI LA=0x%X is empty\n", - addr); - pmxi->dir.w.dd.mxi.la_window = - 0 | (0<pvxieSelf){ - return pvxidi->pvxieSelf; - } - - pnewvxie = (VXIE *) calloc(1, sizeof(*pnewvxie)); - if(!pnewvxie){ - errMessage(S_epvxi_noMemory, "MXI device ignored"); - return NULL; - } - - pnewvxie->type = type; - pnewvxie->la = la; - pnewvxie->la_low = last_la; - pnewvxie->la_high = first_la; - pnewvxie->pParent = pvxie; - - pvxidi->pvxieSelf = pnewvxie; - - /* - * make sure PARENT window includes the MXI - * bus extender - */ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, la); - pvxie->la_high = max(pvxie->la_high, la); - ellAdd(&pvxie->extenders, &pnewvxie->node); - - epvxiRegisterModelName( - VXIMAKE(pmxi), - VXIMODEL(pmxi), - "MXI bus extender"); - - return pnewvxie; -} - - -/* - * MAP_MXI_INWARD - * - * for each MXI found that we have not seen before - * open the la window inward for all devices - * - */ -LOCAL EPVXISTAT map_mxi_inward( -VXIE *pvxie, -enum laPass pass -) -{ - VXIDI *pvxidi; - struct vxi_csr *pmxi_new; - unsigned addr; - EPVXISTAT status; - VXIE *pnewvxie; - - /* - * open all new MXI devices now - * so that we dont confuse them with - * SC devices when a MXI's window is - * completely open. - * - * If we attempt to communicate with a - * MXI device while another MXI device - * at the same level has its window open - * all the way we see VME bus conflicts. - */ - for(addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - if(!pvxidi){ - /* - * if it has not been seen before we know - * its a MXI device - */ - status = open_vxi_device(pvxie, addr); - if(status==VXI_SUCCESS){ - open_mxi_device( - addr, - pvxie, - ext_export_vxi_onto_mxi); - } - } - } - - /* - * now step through and open up all MXI devices found - */ - for(addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - - if(!pvxidi){ - continue; - } - - pnewvxie = pvxidi->pvxieSelf; - - /* - * dont bother with - * devices that are - * not extenders - * here - */ - if(!pnewvxie){ - continue; - } - - /* - * if it is an extender dont - * configure it unless - * it is a child of the - * current parent - */ - if(pvxidi->pvxie != pvxie){ - continue; - } - - pmxi_new = VXIBASE(addr); - - /* - * open the address window inward for all device - */ - pmxi_new->dir.w.dd.mxi.control = - MXI_UPPER_LOWER_BOUNDS; - pmxi_new->dir.w.dd.mxi.la_window = - 1 | (1<la_mapped){ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, pnewvxie->la_low); - pvxie->la_high = max(pvxie->la_high, pnewvxie->la_high); - } - - /* - * temporarily close the windows so that we can discover - * iproperly located SC devices - */ - if(pass != laPassSetWindows){ - pmxi_new->dir.w.dd.mxi.la_window = - 0 | (0<la_mapped){ -# ifdef DEBUG - printf( "VXI resman: MXI to VXI LA=%x %x-%x\n", - addr, - pnewvxie->la_low, - pnewvxie->la_high); -# endif - pmxi_new->dir.w.dd.mxi.la_window = - pnewvxie->la_low | - ((pnewvxie->la_high+1)<dir.w.dd.mxi.INTX_interrupt = - INTX_INT_OUT_ENABLE; - } - } - else{ - - printf( "VXI resman: MXI to VXI LA=0x%X is empty\n", - addr); - pmxi_new->dir.w.dd.mxi.la_window = - 0 | (0<node.next; - if(pvxisz->la == pnewvxie->la || - pvxisz->pvxie == pnewvxie){ - ellDelete(&crateList, &pvxisz->node); - } - pvxisz = next; - } -# endif /*REMOVE_UNUSED_SLOT_ZERO_DEVICES*/ - } - } - return VXI_SUCCESS; -} - - -/* - * - * open_vxi_device - * - * - */ -LOCAL EPVXISTAT open_vxi_device( -VXIE *pvxie, -unsigned la -) -{ - struct vxi_csr *pdevice; - VXIDI *plac; - int16_t id; - EPVXISTAT status; - - /* - * just return if this device is known about - */ - if(epvxiLibDeviceList[la]){ - return VXI_SUCCESS; - } - - pdevice = VXIBASE(la); - - status = vxMemProbe( (char *)pdevice, - READ, - sizeof(id), - (char *)&id); - if(status<0){ - return S_dev_noDevice; - } - - status = verify_valid_window(pvxie, la); - if(status){ - errMessage( - status, - "VXI resman: no access to SC device"); - errMessage( - status, - "VXI resman: without MXI LA window overlap."); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: SC device LA=0X%X", - la); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: extender LA=0X%X", - pvxie->la); - errMessage( - status, - "VXI resman: SC device ignored"); - return status; - } - - plac = (VXIDI *) calloc(1, sizeof(**epvxiLibDeviceList)); - if(!plac){ - errMessage(S_epvxi_noMemory,"... continuing"); - return S_epvxi_noMemory; - } - - plac->make = VXIMAKE(pdevice); - plac->model = VXIMODEL(pdevice); - plac->class = VXICLASS(pdevice); - plac->pvxie = pvxie; - epvxiLibDeviceList[la] = plac; - - pvxie->la_low = min(pvxie->la_low, la); - pvxie->la_high = max(pvxie->la_high, la); - pvxie->la_mapped = TRUE; - - if(vxi_vec_inuse(la)){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "SC VXI device at allocated int vec=0x%X", - la); - epvxiSetDeviceOffline(la); - } - else{ - if(VXISLOT0MODELTEST(plac->model)){ - plac->slot0_dev = TRUE; - open_slot0_device(pvxie, la); - } - } - -# ifdef DEBUG - printf("Found LA=0X%X extender LA=0X%X\n", la, pvxie->la); -# endif - - return VXI_SUCCESS; -} - - -/* - * - * verify_valid_window() - * - * determine if this la is within one - * of the other extenders at the same level - * - */ -LOCAL EPVXISTAT verify_valid_window( -VXIE *pvxie, -unsigned la -) -{ - VXIE *pChild; - - /* - * If its the root extender we dont care - */ - if(!pvxie->pParent){ - return VXI_SUCCESS; - } - - for( pChild = (VXIE *) pvxie->pParent->extenders.node.next; - pChild; - pChild = (VXIE *) pChild->node.next){ - - /* - * of course its ok to be in the - * current extender - */ - if(pChild == pvxie){ - continue; - } - - /* - * its not ok to overlap other extenders - * window - */ - if(pChild->la_mapped){ - if(la >= pChild->la_low && - la <= pChild->la_high){ - - return S_epvxi_badConfig; - } - } - } - - /* - * traverse the hierarchy - */ - return verify_valid_window(pvxie->pParent, la); -} - - -/* - * - * - * VXI_FIND_SC_DEVICES - * - */ -LOCAL void vxi_find_sc_devices( -VXIE *pvxie -) -{ - unsigned addr; - - /* - * Locate the slots of all SC devices - */ - for(addr=first_la; addr<=last_la; addr++){ - - /* - * dont configure devices seen before - */ - if(epvxiLibDeviceList[addr]){ - continue; - } - - (void) open_vxi_device(pvxie, addr); - } -} - - -/* - * - * vxi_record_topology() - * - * Record topological information after all MXIs - * and slot zero cards have been located since - * MXIs can appear in the address space prior - * to their slot zero cards ( so their slots - * cant be found initially ). - * - */ -LOCAL void vxi_record_topology(void) -{ - VXIDI **pplac; - struct vxi_csr *pdevice; - VXISZ *pvxisz; - unsigned la; - unsigned slot; - EPVXISTAT status; - - for( la=first_la, pplac = epvxiLibDeviceList; - la<=last_la; - la++, pplac++){ - - if(!*pplac){ - continue; - } - - pdevice = VXIBASE(la); - status = vxi_find_slot(pdevice, &slot, &pvxisz); - if(status==VXI_SUCCESS){ - (*pplac)->slot = slot; - (*pplac)->slot_zero_la = pvxisz->la; - (*pplac)->extender_la = pvxisz->pvxie->la; - - if(VXISLOT0MODEL(pdevice)){ - if((*pplac)->slot!=0){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI slot 0 found in slot %d? LA=0x%X", - (*pplac)->slot, - la); - } - } - } - else{ - errPrintf( - status, - __FILE__, - __LINE__, - "LA=0X%X", - la); - (*pplac)->slot = UKN_SLOT; - (*pplac)->slot_zero_la = UKN_LA; - (*pplac)->extender_la = UKN_LA; - } - } -} - - -/* - * - * - * VXI_FIND_DC_DEVICES - * - */ -LOCAL void vxi_find_dc_devices( -VXIE *pvxie -) -{ - int prealloc; - int16_t id; - EPVXISTAT status; - unsigned offset; - struct vxi_csr *pcsr; - VXISZ *pvxisz; - unsigned nDC; - int slot; - - /* - * dont move DC devices if SC device at address 0xff - */ - if(epvxiLibDeviceList[VXIDYNAMICADDR]){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI SC device recorded at dynamic address 0x%X", - VXIDYNAMICADDR); - errMessage( - S_epvxi_badConfig, - "VXI DC devices ignored"); - return; - } - - pcsr = VXIBASE(VXIDYNAMICADDR); - status = vxMemProbe( (char *)pcsr, - READ, - sizeof(id), - (char *)&id); - if(status == OK){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI SC device at dynamic address 0x%X", - VXIDYNAMICADDR); - errMessage( - S_epvxi_badConfig, - "VXI DC devices ignored"); - return; - } - - /* - * if unanchored force them to all be in one - * contiguous block - */ - prealloc = FALSE; - if(!pvxie->la_mapped){ - status = vxi_count_dc_devices(pvxie, &nDC); - if(status){ - return; - } - if(nDC < 1){ - return; - } - status = vxi_alloc_la( - pvxie, - nDC, - &offset); - if(status){ - errMessage( - status, - "VXI resman: unanchored DC VXI device block doesnt fit"); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: %d DC VXI devices in extender LA=0X%X ignored", - nDC, - pvxie->la); - return; - } - prealloc = TRUE; - } - - /* - * find all DC devices - */ - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - /* - * We wish to selectively configure DC devices - * accessed through the current extender. - * - * If the slot zero card is the extender then - * the LAs of the extender and the slot zero will - * match. Otherwise the slotzero card was found - * by opening up the window in the extender - * and the slot zeros extender will be the - * current extender. - */ - if(pvxisz->pvxie == pvxie || pvxisz->la == pvxie->la){ - for(slot=0;slotnode.next; - } -} - - -/* - * vxi_assign_dc_addresses() - */ -LOCAL EPVXISTAT vxi_assign_dc_addresses( -VXIE *pvxie, -struct vxi_csr *pcsr, -int prealloc, -unsigned *pOffset, -VXISZ *pvxisz, -int slot -) -{ - unsigned offset; - unsigned count; - EPVXISTAT status; - int16_t id; - - status = vxMemProbe( - (char *)pcsr, - READ, - sizeof(id), - (char *)&id); - if(status<0){ - return S_epvxi_noDevice; - } - - count = slot_la_count(pcsr); - - if(prealloc){ - offset = *pOffset; - } - else{ - status = vxi_alloc_la( - pvxie, - count, - &offset); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI: %d DC VXI device(s) do(es) not fit", - count); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI: DC VXI device(s) at slot %d in extender LA=0X%X ignored", - slot, - pvxie->la); - return S_epvxi_noMemory; - } - } - - /* - * blocked addr devices recv their - * addr assignements in unison - */ - pcsr->dir.w.addr = offset; - - while(count){ - count--; - status = open_vxi_device( - pvxie, - offset); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: DC dev assign to LA=0X%X failed", - offset); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: Slot Zero LA=0X%X", - pvxisz->la); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: DC VXI device ignored"); - } - offset++; - } - - if(prealloc){ - *pOffset = offset; - } - - return status; -} - - -/* - * - * - * VXI_COUNT_DC_DEVICES - * - */ -LOCAL EPVXISTAT vxi_count_dc_devices( -VXIE *pvxie, -unsigned *pCount -) -{ - int16_t id; - EPVXISTAT status; - struct vxi_csr *pcsr; - VXISZ *pvxisz; - int slot; - unsigned nDC; - - /* - * dont count DC devices if SC device at address 0xff - */ - if(epvxiLibDeviceList[VXIDYNAMICADDR]){ - status = S_epvxi_badConfig; - errMessage(status, "SC device at DC address"); - return status; - } - - pcsr = VXIBASE(VXIDYNAMICADDR); - status = vxMemProbe( (char *)pcsr, - READ, - sizeof(id), - (char *)&id); - if(status == OK){ - status = S_epvxi_badConfig; - errMessage(status, "SC device at DC address"); - return status; - } - - /* - * find all dynamic modules - */ - nDC=0; - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - /* - * We wish to selectively configure DC devices - * accessed through the current extender. - * - * If the slot zero card is the extender then - * the LAs of the extender and the slot zero will - * match. Otherwise the slotzero card was found - * by opening up the window in the extender - * and the slot zeros extender will be the - * current extender. - * - * Counts multiple blocked addr device per slot here. - * Does not try to count multiple independently - * addressed devices per slot here. Space is - * allocated for these DC devices on demand due to - * difficulties counting them ahead of time. - */ - if(pvxisz->pvxie == pvxie || - pvxisz->la == pvxie->la){ - - for(slot=0; slot=0){ - nDC += slot_la_count(pcsr); - } - } - CLRMODID(pvxisz); - } - - pvxisz = (VXISZ *) pvxisz->node.next; - } - *pCount = nDC; - return VXI_SUCCESS; -} - - -/* - * - * slot_la_count() - * - */ -LOCAL unsigned slot_la_count(struct vxi_csr *pcsr) -{ - unsigned blockedAddrCount; - - /* - * Rule F.2.6 - */ - blockedAddrCount = VXINDCDEVICES(pcsr); - if(blockedAddrCount==0 || blockedAddrCount==0xff){ - blockedAddrCount = 1; - } - return blockedAddrCount; -} - - -/* - * - * open slot 0 device - * - * - */ -LOCAL void open_slot0_device( -VXIE *pvxie, -unsigned la -) -{ - struct vxi_csr *pcsr; - EPVXISTAT status; - VXISZ *pvxisz; - - pcsr = VXIBASE(la); - - /* - * MXI's are device class extended - */ - if(VXICLASS(pcsr) != VXI_REGISTER_DEVICE){ - if(!VXIMXI(pcsr)){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, -"Only register based slot 0 devices currently supported LA=0x%X", - la); - return; - } - } - - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - if(pvxisz->pcsr == pcsr){ - return; - } - pvxisz = (VXISZ *) pvxisz->node.next; - } - - pvxisz = (VXISZ *) calloc(1, sizeof(*pvxisz)); - if(!pvxisz){ - errMessage( - S_epvxi_noMemory, - "continuing..."); - return; - } - pvxisz->reg = TRUE; - pvxisz->pcsr = pcsr; - pvxisz->set_modid = set_reg_modid; - pvxisz->clear_modid = clr_all_reg_modid; - pvxisz->pvxie = pvxie; - pvxisz->la = la; - - ellAdd(&crateList, &pvxisz->node); - - /* - * force the slot zero device into a known state - */ - CLRMODID(pvxisz); - - if(!epvxiLibDeviceList[la]){ - status = open_vxi_device(pvxie, la); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "attempted slot zero device open la=0X%X", - la); - return; - } - } -} - - - - - -/* - * - * NICPU030_INIT() - * check to see if this code is running on a - * national instruments cpu030 installed in - * slot zero. - * - */ -#ifdef NICPU030 -LOCAL EPVXISTAT nicpu030_init( -VXIE *pvxie -) -{ - int i; - EPVXISTAT status = S_epvxi_internal; - int16_t model; - UINT8 type; - UINT8 la; - - /* - * If we are running this code on the NI 030 - * we are the resource manager and the NI 030 will - * be the first slot zero card found. - */ - if(niCpu030Initialized){ - return VXI_SUCCESS; - } - - for(i=0; inicpu030 = TRUE; - pvxisz->set_modid = nivxi_cpu030_set_modid; - pvxisz->clear_modid = nivxi_cpu030_clr_all_modid; - pvxisz->la = la; - pvxisz->pvxie = pvxie; - - ellAdd(&crateList, &pvxisz->node); - } - return VXI_SUCCESS; -} -#endif - - - -/* - * - * vxi_alloc_la() - * - */ -LOCAL EPVXISTAT vxi_alloc_la( -VXIE *pvxie, -unsigned count, -unsigned *poffset -) -{ - EPVXISTAT status; - unsigned hla; - VXIDI *pvxidi; - unsigned peak = 0; - unsigned la; - - if(count<1){ - status = S_epvxi_internal; - errMessage(status,NULL); - return status; - } - - /* - * look inside the range thats mapped first - */ - if(pvxie->la_mapped){ - for(la=pvxie->la_low; la<=last_la; la++){ - - pvxidi = epvxiLibDeviceList[la]; - - /* - * skip all devices seen before - */ - if(pvxidi){ - /* - * LA window cant cross extender boundaries - * so just quit - */ - if(pvxidi->pvxie != pvxie){ - break; - } - peak= 0; - continue; - } - - if(vxi_la_occupied(la)){ - peak= 0; - continue; - } - - peak++; - - if(peak >= count){ - *poffset = ((int)la)-(count-1); - return VXI_SUCCESS; - } - } - - hla = pvxie->la_low; - } - else{ - hla = last_la; - } - - /* - * unachored DC device allocations go from high - * to low so that we avoid mc680xx reserved - * interrupt vectors - * - * stop before unsigned la=0 is decremented - * (shouldnt allocate the resource manager's LA anyways) - */ - peak=0; - for(la=hla; la>=max(VXI_RESMAN_LA+1,first_la); la--){ - - pvxidi = epvxiLibDeviceList[la]; - - /* - * skip all devices seen before - */ - if(pvxidi){ - /* - * LA window cant cross extender boundaries - * (if something is mapped already) so just quit - */ - if(pvxie->la_mapped){ - if(pvxidi->pvxie != pvxie){ - break; - } - } - - peak= 0; - continue; - } - - if(vxi_la_occupied(la)){ - peak= 0; - continue; - } - - peak++; - - if(peak >= count){ - *poffset = la; - return VXI_SUCCESS; - } - } - - return S_epvxi_internal; -} - - -/* - * - * vxi_la_occupied() - * - */ -LOCAL EPVXISTAT vxi_la_occupied(unsigned la) -{ - struct vxi_csr *pcsr; - int16_t *pi16; - int16_t i16; - EPVXISTAT s; - - /* - * dont allocate the resource manager's LA - */ - if(la == VXI_RESMAN_LA){ - return TRUE; - } - - /* - * Check to see if this LA belongs to - * the NI 030 CPU (that does not show - * in A16 when it is a VME BM) - */ - if(niCpu030Initialized){ - if(la == (*pnivxi_func[(unsigned)e_GetMyLA])()){ - return TRUE; - } - } - - /* - * Probe the entire LA space - */ - pcsr = VXIBASE(la); - for( pi16 = (int16_t *) &pcsr->dir.r.make; - pi16 <= (int16_t *) &pcsr->dir.r.dd.reg.ddx2e; - pi16++){ - - s = vxMemProbe( (char *)pi16, - READ, - sizeof(i16), - (char *)&i16); - if(s == OK){ - return TRUE; - } - } - - /* - * dont allow vxi int vec to overlap - * VME vectors in use - */ - if(vxi_vec_inuse(la)){ - return TRUE; - } - - return FALSE; -} - - - -/* - * - * VXI_FIND_SLOT - * given a VXI module's addr find its slot - * - */ -LOCAL EPVXISTAT vxi_find_slot( -struct vxi_csr *pcsr, -unsigned *pslot, -VXISZ **ppvxisz -) -{ - VXISZ *pvxisz; - EPVXISTAT status; - unsigned char slot; - - status = S_epvxi_slotNotFound; - - /* - * RULE C.2.7 - */ - if(VXIMODIDSTATUS(pcsr->dir.r.status)){ - errMessage(status, "device's MODID status is active & no MODID?"); - return status; - } - - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - - /* - * if it is a slot zero card - * then dont bother searching - */ - if(pvxisz->pcsr == pcsr){ - *pslot = 0; - *ppvxisz = pvxisz; - status = VXI_SUCCESS; - break; - } - - for(slot=0;slotdir.r.status)){ - *pslot = slot; - *ppvxisz = pvxisz; - status = VXI_SUCCESS; - break; - } - } - CLRMODID(pvxisz); - - if(status == VXI_SUCCESS) - break; - - pvxisz = (VXISZ *) pvxisz->node.next; - } - - return status; -} - - -/* - * - * VXI_RESET_DC - * force all dynamic devices back to address 0xff - * (In case this is a ctrl X restart) - * - * not tested with at5vxi modules - */ -#ifdef JUNKYARD -LOCAL EPVXISTAT vxi_reset_dc(void) -{ - register unsigned addr; - unsigned slot; - unsigned crate; - int16_t id; - EPVXISTAT status; - struct vxi_csr_w *pcr; - struct vxi_csr_r *psr; - - for(addr=first_la; addr<=last_la; addr++){ - - psr = (struct vxi_csr_r *) VXIBASE(addr); - pcr = (struct vxi_csr_w *) psr; - - status = vxMemProbe( psr, - READ, - sizeof(id), - &id); - if(status == ERROR) - continue; - - status = vxi_find_slot(psr, &slot, &crate); - if(status){ - return status; - } - - SETMODID(slot, crate); - - - pcr->addr = VXIDYNAMICADDR; - } - - return VXI_SUCCESS; -} -#endif - - -/* - * - * VXI_DC_TEST - * determine if a VXI module in the static address range is dynamic - * - */ -#ifdef JUNKYARD -LOCAL EPVXISTAT vxi_dc_test( -unsigned current_addr -) -{ - register unsigned addr; - unsigned slot; - unsigned crate; - int16_t id; - EPVXISTAT status; - struct vxi_csr_w *pcr; - struct vxi_csr_r *psr; - - static unsigned open_addr; - unsigned dynamic; - - for(addr=first_la; addr<=last_la; addr++){ - - status = vxMemProbe( VXIBASE(addr), - READ, - sizeof(id), - &id); - if(status == ERROR){ - open_addr = addr; - break; - } - } - - psr = (struct vxi_csr_r *) VXIBASE(current_addr); - pcr = (struct vxi_csr_w *) psr; - - status = vxi_find_slot(psr, &slot, &crate); - if(status){ - errMessage(status,NULL); - return status; - } - - SETMODID(slot, crate); - pcr->addr = open_addr; - - psr = (struct vxi_csr_r *) VXIBASE(open_addr); - pcr = (struct vxi_csr_w *) psr; - - status = vxMemProbe( psr, - READ, - sizeof(id), - &id); - - if(status==OK){ - dynamic = TRUE; - pcr->addr = current_addr; - } - else - dynamic = FALSE; - - status = vxMemProbe( VXIBASE(current_addr), - READ, - sizeof(id), - &id); - if(status == ERROR) - return S_epvxi_internal; - - - return dynamic; -} -#endif - - -/* - * - * VXI_CONFIGURE_HIERARCHIES - * - */ -LOCAL void vxi_configure_hierarchies( -unsigned commander_la, -unsigned servant_area -) -{ - EPVXISTAT status; - struct vxi_csr *pcsr; - unsigned long response; - VXIDI **ppvxidi; - VXIDI *pvxidi; - unsigned sla; - unsigned last_sla; - unsigned area; - - last_sla = servant_area+commander_la; - - if(last_sla >= NELEMENTS(epvxiLibDeviceList)){ - errPrintf( - S_epvxi_internal, - __FILE__, - __LINE__, - "VXI resman: Clipping servant area (LA=0x%X)", - commander_la); - last_sla = NELEMENTS(epvxiLibDeviceList)-1; - } - - sla = commander_la+1; - ppvxidi = &epvxiLibDeviceList[sla]; - for( ; - sla<=last_sla; - sla += area+1, ppvxidi += area+1){ - - pvxidi = *ppvxidi; - area = 0; - - if(!pvxidi){ - continue; - } - - pvxidi->commander_la = commander_la; - - if(!pvxidi->st_passed){ - continue; - } - - pcsr = VXIBASE(sla); - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - if(commander_la != VXI_RESMAN_LA){ - status = epvxiCmdQuery( - commander_la, - (unsigned long)MBC_GRANT_DEVICE | sla, - &response); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: GD failed (LA=0x%X)", - sla); - } - else{ - printf( - "VXI resman: gd resp %x\n", - response); - } - } - if(VXICMDR(pcsr)){ - status = epvxiCmdQuery( - sla, - (unsigned long)MBC_READ_SERVANT_AREA, - &response); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: RSA failed (LA=0x%X)", - sla); - } - else{ - area = response & MBR_READ_SERVANT_AREA_MASK; - - printf( "The servant area was %d (LA=0x%X)\n", - area, - sla); - - vxi_configure_hierarchies( - sla, - area); - } - } - } -} - - -/* - * - * VXI_BEGIN_NORMAL_OPERATION - * - */ -LOCAL void vxi_begin_normal_operation(void) -{ - EPVXISTAT status; - unsigned la; - VXIDI **ppvxidi; - VXIDI *pvxidi; - struct vxi_csr *pcsr; - - for( la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - unsigned cmdr; - unsigned long cmd; - unsigned long resp; - - pvxidi = *ppvxidi; - - if(!pvxidi){ - continue; - } - - pcsr = VXIBASE(la); - - if(!pvxidi->st_passed){ - continue; - } - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - cmdr = VXICMDR(pcsr); - - cmd = MBC_BEGIN_NORMAL_OPERATION; -/* - * this will send the begin nml op command to servants which - * have a commander - * - * more work needs to be done here if this situation occurs - * see below - */ - if(cmdr){ - cmd |= MBC_TOP_LEVEL_CMDR; - } - status = epvxiCmdQuery(la, cmd, &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: Device rejected BEGIN_NORMAL_OPERATION LA=0x%X (reason=%d)", - la, - status); - } - else if( - MBR_STATUS(resp)!=MBR_STATUS_SUCCESS || - MBR_BNO_STATE(resp)!=MBR_BNO_STATE_NO){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "VXI resman: Device rejected BEGIN_NORMAL_OPERATION LA=0x%X (status=%x) (state=%x)", - la, - MBR_STATUS(resp), - MBR_BNO_STATE(resp)); - } - else{ - pvxidi->msg_dev_online = TRUE; - } - - /* - * Dont send begin normal operation cmd - * to servants who have a commander - */ -/* - * apparently this is not a good enough test - * for CMDR since some devices are rejecting this cmd - */ -#if 0 - if(cmdr){ - unsigned long sa=0; - - printf("Found a msg based cmdr\n"); - - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_SERVANT_AREA, - &sa); - if(status){ - errMessage( - status, - "vxi resman: rsa failed"); - } - else{ - sa = sa & MBR_READ_SERVANT_AREA_MASK; - printf( - "The servant area was %d\n", - sa); - la += sa; - } - } -#endif - } -} - - -/* - * - * VXI_SELF_TEST - * check self test bits and place in safe state if failed - * print message about failed devices - * - */ -LOCAL EPVXISTAT vxi_self_test(void) -{ - unsigned la; - uint16_t wd; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - - - for( la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - if(!*ppvxidi){ - continue; - } - - pcsr = VXIBASE(la); - - wd = pcsr->dir.r.status; - - if(VXIPASSEDSTATUS(wd)){ - (*ppvxidi)->st_passed = TRUE; - } - else{ - errMessage( - S_epvxi_selfTestFailed, - "VXI resman: device self test failed"); - epvxiSetDeviceOffline(la); - } - } - - return VXI_SUCCESS; -} - - -/* - * - * - * epvxiSetDeviceOffline() - * - */ -LOCAL EPVXISTAT epvxiSetDeviceOffline( -unsigned la -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "WARNING: VXI device placed off line %c(LA=0x%X)", - BELL, - la); - - pcsr->dir.w.control = VXISAFECONTROL; - - return VXI_SUCCESS; -} - - -/* - * - * VXI_ADDRESS_CONFIG - * - */ -LOCAL void vxi_address_config(void) -{ - char *pBase; - EPVXISTAT status; - - /* - * fetch the EPICS address ranges from the global - * symbol table if they are available - */ - status = symbol_value_fetch( - "_EPICS_VXI_A24_BASE", - &root_extender.A24_base, - sizeof(root_extender.A24_base)); - if(status){ - root_extender.A24_base = DEFAULT_VXI_A24_BASE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A24_SIZE", - &root_extender.A24_size, - sizeof(root_extender.A24_size)); - if(status){ - root_extender.A24_size = DEFAULT_VXI_A24_SIZE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A32_BASE", - &root_extender.A32_base, - sizeof(root_extender.A32_base)); - if(status){ - root_extender.A32_base = DEFAULT_VXI_A32_BASE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A32_SIZE", - &root_extender.A32_size, - sizeof(root_extender.A32_size)); - if(status){ - root_extender.A32_size = DEFAULT_VXI_A32_SIZE; - } - - /* - * find A24 and A32 on this processor - */ - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - (char *)root_extender.A24_base, - &pBase); - if(status == OK){ - root_extender.A24_base = (long) pBase; - root_extender.A24_ok = TRUE; - } - else{ - root_extender.A24_ok = FALSE; - errMessage( - S_epvxi_badConfig, - "A24 VXI Base Addr problems"); - } - status = sysBusToLocalAdrs( - VME_AM_EXT_SUP_DATA, - (char *)root_extender.A32_base, - &pBase); - if(status == OK){ - root_extender.A32_base = (long) pBase; - root_extender.A32_ok = TRUE; - } - else{ - root_extender.A32_ok = FALSE; - errMessage( - S_epvxi_badConfig, - "A32 VXI Base Addr problems"); - } - - vxi_allocate_address_block(&root_extender); -} - - -/* - * - * VXI_ALLOCATE_ADDRESS_BLOCK - * - */ -LOCAL void vxi_allocate_address_block( -VXIE *pvxie -) -{ - unsigned la; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - VXIE *psubvxie; - unsigned long A24_base; - unsigned long A24_size; - unsigned long A32_base; - unsigned long A32_size; - - if(!pvxie->la_mapped){ - return; - } - - switch(pvxie->type){ - case ext_export_vxi_onto_mxi: - case ext_import_mxi_into_vxi: - pvxie->A24_base = MXIA24ALIGN(pvxie->A24_base); - pvxie->A32_base = MXIA32ALIGN(pvxie->A32_base); - pvxie->A24_size &= ~MXIA24MASK; - pvxie->A32_size &= ~MXIA32MASK; - break; - case ext_local_cpu: - default: - break; - } - - A24_base = pvxie->A24_base; - A24_size = pvxie->A24_size; - A32_base = pvxie->A32_base; - A32_size = pvxie->A32_size; - - psubvxie = (VXIE *) &pvxie->extenders.node; - while(psubvxie = (VXIE *) ellNext((ELLNODE *)psubvxie)){ - - psubvxie->A24_base = A24_base; - psubvxie->A24_size = A24_size; - psubvxie->A32_base = A32_base; - psubvxie->A32_size = A32_size; - psubvxie->A24_ok = pvxie->A24_ok; - psubvxie->A32_ok = pvxie->A32_ok; - - vxi_allocate_address_block(psubvxie); - - if(psubvxie->A24_mapped){ - A24_base = psubvxie->A24_base + psubvxie->A24_size; - A24_size -= psubvxie->A24_size; - pvxie->A24_mapped = TRUE; - } - - if(psubvxie->A32_mapped){ - A32_base = psubvxie->A32_base + psubvxie->A32_size; - A32_size -= psubvxie->A32_size; - pvxie->A32_mapped = TRUE; - } - } - - for( la=pvxie->la_low, ppvxidi = &epvxiLibDeviceList[la]; - ppvxidi <= &epvxiLibDeviceList[pvxie->la_high]; - ppvxidi++, la++){ - - unsigned long m; - unsigned long size; - unsigned long mask; - - if(!*ppvxidi){ - continue; - } - - /* - * dont configure devices lower in the hierarchy - */ - if((*ppvxidi)->A24_mapped || (*ppvxidi)->A32_mapped){ - continue; - } - - pcsr = VXIBASE(la); - - m = VXIREQMEM(pcsr); - - switch(VXIADDRSPACE(pcsr)){ - case VXI_ADDR_EXT_A24: - if(!pvxie->A24_ok){ - break; - } - - /* - * perform any needed alignment - */ - size = VXIA24MEMSIZE(m); - if(size>A24_size){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI A24 device does not fit Request=%d Avail=%d LA=0X%X", - size, - A24_size, - la); - epvxiSetDeviceOffline(la); - break; - } - mask = size-1; - A24_base = ((A24_base)+mask)&(~mask); - pcsr->dir.w.offset = A24_base>>8; - pcsr->dir.w.control = VXIMEMENBLCONTROL; - (*ppvxidi)->pFatAddrBase = (void *) A24_base; - (*ppvxidi)->A24_mapped = TRUE; - pvxie->A24_mapped = TRUE; - A24_base += size; - A24_size -= size; - break; - - case VXI_ADDR_EXT_A32: - if(!pvxie->A32_ok){ - break; - } - - /* - * perform any needed alignment - */ - size = VXIA32MEMSIZE(m); - if(size>A32_size){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI A32 device does not fit Request=%d Avail=%d LA=0X%X", - size, - A32_size, - la); - epvxiSetDeviceOffline(la); - break; - } - mask = size-1; - A32_base = (A32_base+mask)&(~mask); - pcsr->dir.w.offset = A32_base>>16; - pcsr->dir.w.control = VXIMEMENBLCONTROL; - (*ppvxidi)->pFatAddrBase = (void *) A32_base; - (*ppvxidi)->A32_mapped = TRUE; - pvxie->A32_mapped = TRUE; - A32_base += size; - A32_size -= size; - break; - - default: - /* - * do nothing - */ - break; - } - } - - pcsr = VXIBASE(pvxie->la); - - if(pvxie->A24_mapped){ - pvxie->A24_size = pvxie->A24_size - A24_size; - pvxie->A24_size = MXIA24ALIGN(pvxie->A24_size); - } - - if(pvxie->A32_mapped){ - pvxie->A32_size = pvxie->A32_size - A32_size; - pvxie->A32_size = MXIA32ALIGN(pvxie->A32_size); - } - - switch(pvxie->type){ - case ext_export_vxi_onto_mxi: - if(pvxie->A24_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a24_window_high = - (pvxie->A24_base+pvxie->A24_size) - >> MXIA24MASKSIZE; - pcsr->dir.w.dd.mxi.a24_window_low = - pvxie->A24_base - >> MXIA24MASKSIZE; - } - if(pvxie->A32_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a32_window_high = - (pvxie->A32_base+pvxie->A32_size) - >> MXIA32MASKSIZE; - pcsr->dir.w.dd.mxi.a32_window_low = - pvxie->A32_base - >> MXIA32MASKSIZE; - } - break; - - case ext_import_mxi_into_vxi: - if(pvxie->A24_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a24_window_high = - pvxie->A24_base - >> MXIA24MASKSIZE; - pcsr->dir.w.dd.mxi.a24_window_low = - (pvxie->A24_base+pvxie->A24_size) - >> MXIA24MASKSIZE; - } - if(pvxie->A32_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a32_window_high = - pvxie->A32_base - >> MXIA32MASKSIZE; - pcsr->dir.w.dd.mxi.a32_window_low = - (pvxie->A32_base+pvxie->A32_size) - >> MXIA32MASKSIZE; - } - break; - - case ext_local_cpu: - default: - break; - } -} - - -/* - * - * symbol_value_fetch - * - */ -LOCAL EPVXISTAT symbol_value_fetch( -char *pname, -void *pdest, -unsigned dest_size -) -{ - EPVXISTAT status; - UINT8 type; - char *pvalue; - - status = symFindByName( - sysSymTbl, - pname, - &pvalue, - &type); - if(status == OK){ - bcopy(pvalue, pdest, dest_size); - return VXI_SUCCESS; - } - else{ - return S_epvxi_internal; - } -} - - -/* - * - * VXI_INIT_IGNORE_LIST - * init list of interrupt handlers to ignore - * - */ -LOCAL EPVXISTAT vxi_init_ignore_list(void) -{ - int i; - UINT8 type; - EPVXISTAT status; - - for(i=0; ireg)){ - errMessage( - S_epvxi_internal, - "bad crate for set_reg_modid"); - return; - } - VXI_SET_REG_MODID(pvxisz->pcsr, slot); -} - -/* - * - * CLR_ALL_REG_MODID - * - */ -LOCAL void clr_all_reg_modid( -VXISZ *pvxisz -) -{ - if(!(pvxisz->reg)){ - errMessage( - S_epvxi_internal, - "bad crate for clr_all_reg_modid"); - return; - } - VXI_CLR_ALL_REG_MODID(pvxisz->pcsr); -} - - - -/* - * - * NIVXI_CPU030_SET_MODID - * - */ -#ifdef NICPU030 -LOCAL void nivxi_cpu030_set_modid( -VXISZ *pvxisz, -unsigned slot -) -{ - EPVXISTAT status; - - if(niCpu030Initialized){ - status = (*pnivxi_func[(unsigned)e_SetMODID])(TRUE,1<slot, - pmxidi->pvxisz->la, - pmxidi->class); - printf("\t"); - if(pmxidi->pvxieSelf){ - printf("extender, "); - } - if(pmxidi->msg_dev_online){ - printf("msg online, "); - } - printf("driver ID %d, ", pmxidi->driverID); - if(taskIdVerify(pmxidi->taskID)>=0){ - printf( "opened by task %s, ", - taskName(pmxidi->taskID)); - } - printf("cmdr la=0x%X, ", pmxidi->commander_la); - printf("extdr la=0x%X, ", pmxidi->extender_la); - printf("slot-zero la=0x%X, ", pmxidi->slot_zero_la); - printf("make 0X%X, ", (unsigned) pmxidi->make); - printf("model 0x%X, ", pmxidi->model); - printf( "pio_report_func %x, ", - (unsigned) pmxidi->pio_report_func); - printf("\n"); - } - i++; - ppmxidi++; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiCrateList() - * - */ -EPVXISTAT epvxiCrateList(void) -{ - VXISZ *pvxisz; - - printf("VXI crate list\n"); - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - - printf("LA=0X%X", pvxisz->la); - printf( ", extender LA=0X%X", - pvxisz->pvxie->la); - if(pvxisz->reg){ - printf(", register device"); - } - if(pvxisz->msg){ - printf(", message device"); - } - if(pvxisz->nicpu030){ - printf(", NI030"); - } - printf("\n"); - pvxisz = (VXISZ *) pvxisz->node.next; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiUniqueDriverID() - * - * return a non zero unique id for a VXI driver - */ -long epvxiUniqueDriverID(void) -{ - if(epvxiNextDriverIDdriverID == vxiDriverID){ - return S_epvxi_deviceOpen; - } - else if(pvxidi->driverID != NO_DRIVER_ATTACHED_ID){ - return S_epvxi_notOwner; - } - - if(driverConfigSize){ - pconfig = (void *)calloc(1,driverConfigSize); - if(!pconfig){ - return S_epvxi_noMemory; - } - pvxidi->pDriverConfig = pconfig; - } - else{ - pvxidi->pDriverConfig = NULL; - } - - pvxidi->pio_report_func = pio_report_func; - - pvxidi->taskID = taskIdSelf(); - pvxidi->driverID = vxiDriverID; - - return VXI_SUCCESS; -} - - -/* - * - * epvxiDeviceVerify() - * - * - */ -EPVXISTAT epvxiDeviceVerify(unsigned la) -{ - EPVXISTAT status; - VXICSR *pcsr; - VXIDI *pvxidi; - uint16_t device_status; - - if(la > NELEMENTS(epvxiLibDeviceList)){ - return S_epvxi_badLA; - } - - pvxidi = epvxiLibDeviceList[la]; - if(!pvxidi){ - return S_epvxi_uknDevice; - } - - /* - * verify that the device exists - * and check the self test in memory - * since this may run before - * the self tests are verified. - */ - pcsr = VXIBASE(la); - status = vxMemProbe( (char *)&pcsr->dir.r.status, - READ, - sizeof(pcsr->dir.r.status), - (char *)&device_status); - if(status != OK){ - return S_epvxi_uknDevice; - } - if(!VXIPASSEDSTATUS(device_status)){ - return S_epvxi_selfTestFailed; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiClose() - * - * 1) Unregister a driver's ownership of a device - * 2) Free driver's configuration block if one is allocated - */ -EPVXISTAT epvxiClose( -unsigned la, -int vxiDriverID -) -{ - VXIDI *pvxidi; - - if(la > NELEMENTS(epvxiLibDeviceList)){ - return S_epvxi_badLA; - } - - pvxidi = epvxiLibDeviceList[la]; - - if(pvxidi){ - if(pvxidi->driverID == vxiDriverID){ - pvxidi->driverID = NO_DRIVER_ATTACHED_ID; - if(pvxidi->pDriverConfig){ - free(pvxidi->pDriverConfig); - pvxidi->pDriverConfig = NULL; - } - return VXI_SUCCESS; - } - return S_epvxi_notOwner; - } - - return S_epvxi_notOwner; -} - - -/* - * - * epvxiLookupLA() - * - */ -EPVXISTAT epvxiLookupLA( -epvxiDeviceSearchPattern *pdsp, -void (*pfunc)(), -void *parg -) -{ - VXIDI *plac; - unsigned i; - - for(i=first_la; i<=last_la; i++){ - long flags; - - flags = pdsp->flags; - plac = epvxiLibDeviceList[i]; - - /* - * skip devices not present - */ - if(!plac){ - continue; - } - - if(flags & VXI_DSP_make){ - if(plac->make != pdsp->make){ - continue; - } - } - - if(flags & VXI_DSP_model){ - if(plac->model != pdsp->model){ - continue; - } - } - - if(flags & VXI_DSP_class){ - if(plac->class != pdsp->class){ - continue; - } - } - - if(flags & VXI_DSP_slot){ - if(plac->slot != pdsp->slot){ - continue; - } - } - - if(flags & VXI_DSP_slot_zero_la){ - if(plac->slot_zero_la != pdsp->slot_zero_la){ - continue; - } - } - - if(flags & VXI_DSP_commander_la){ - if(plac->commander_la != pdsp->commander_la){ - continue; - } - } - - if(flags & VXI_DSP_extender_la){ - if(plac->extender_la != pdsp->extender_la){ - continue; - } - } - - (*pfunc)(i, parg); - - } - - return VXI_SUCCESS; -} - - -/* - * epvxiRouteTriggerECL() - */ -EPVXISTAT epvxiRouteTriggerECL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - VXIDI *plac; - struct vxi_csr *pcsr; - char mask; - EPVXISTAT status; - int i; - - mask = (1<> 1, - io_map = io_map >> 1, - i++){ - - int (*pfunc)(); - int src; - int dest; - - if(!(enable_map&1)){ - continue; - } - - if(io_map&1){ - src = TRIG_LINE_FPOUT; - dest = TRIG_LINE_ECL_BASE + i; - } - else{ - src = TRIG_LINE_FPIN; - dest = TRIG_LINE_ECL_BASE + i; - } - - pfunc = pnivxi_func[(unsigned)e_MapTrigToTrig]; - status = (*pfunc)( - la, - src, - dest, - 0); - if(status < 0){ - status = S_epvxi_badTrigIO; - errPrintf( - status, - __FILE__, - __LINE__, - "NI CPU030 ECL trig map fail LA=0X%X", - la); - return status; - } - - } - return VXI_SUCCESS; - } - } - - plac = epvxiLibDeviceList[la]; - if(plac){ - if(!plac->st_passed){ - return S_epvxi_selfTestFailed; - } - } - else{ - return S_epvxi_noDevice; - } - - pcsr = VXIBASE(la); - - if(VXIMXI(pcsr)){ - int ctrl = MXI_CONTROL_CONSTANT; - - if(enable_map & (1<<0)){ - ctrl |= MXI_ECL0_ENABLE; - } - if(io_map & (1<<0)){ - ctrl |= MXI_ECL0_BP_TO_FP; - } - else{ - ctrl |= MXI_ECL0_FP_TO_BP; - } - - - if(enable_map & (1<<1)){ - ctrl |= MXI_ECL1_ENABLE; - } - if(io_map & (1<<1)){ - ctrl |= MXI_ECL1_BP_TO_FP; - } - else{ - ctrl |= MXI_ECL1_FP_TO_BP; - } - - pcsr->dir.w.dd.mxi.control = ctrl; - - return VXI_SUCCESS; - } - - /* - * HP MODEL E1404 trigger routing - */ - if(VXIMAKE(pcsr)==VXI_MAKE_HP){ - if( VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG || - VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG_SLOT0){ - return hpE1404RouteTriggerECL( - la, - enable_map, - io_map); - } - } - - status = S_epvxi_uknDevice; - errPrintf( - status, - __FILE__, - __LINE__, - "failed to map ECL trigger for (la=0x%X)", - la); - return status; -} - - -/* - * epvxiRouteTriggerTTL() - * - */ -EPVXISTAT epvxiRouteTriggerTTL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - VXIDI *plac; - struct vxi_csr *pcsr; - unsigned mask; - EPVXISTAT status; - int i; - - mask = (1<> 1, - io_map = io_map >> 1, - i++){ - - int (*pfunc)(); - int src; - int dest; - - if(!(enable_map&1)){ - continue; - } - - if(io_map&1){ - src = TRIG_LINE_FPOUT; - dest = TRIG_LINE_TTL_BASE + i; - } - else{ - src = TRIG_LINE_FPIN; - dest = TRIG_LINE_TTL_BASE + i; - } - - pfunc = pnivxi_func[(unsigned)e_MapTrigToTrig]; - status = (*pfunc)( - la, - src, - dest, - 0); - if(status < 0){ - status = S_epvxi_badTrigIO; - errPrintf( - status, - __FILE__, - __LINE__, - "NI030 TTL trig map fail LA=0X%X", - la); - return status; - } - - } - return VXI_SUCCESS; - } - } - - plac = epvxiLibDeviceList[la]; - if(plac){ - if(!plac->st_passed){ - return S_epvxi_selfTestFailed; - } - } - else{ - return S_epvxi_noDevice; - } - - - pcsr = VXIBASE(la); - - if(VXIMXI(pcsr)){ - int16_t tmp; - - tmp = ~io_map & enable_map; - tmp = (enable_map<<8) | tmp; - pcsr->dir.w.dd.mxi.trigger_config = tmp; - - return VXI_SUCCESS; - } - - /* - * HP MODEL E1404 trigger routing - */ - if(VXIMAKE(pcsr)==VXI_MAKE_HP){ - if( VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG || - VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG_SLOT0){ - return hpE1404RouteTriggerTTL( - la, - enable_map, - io_map); - } - } - - status = S_epvxi_uknDevice; - errPrintf( - status, - __FILE__, - __LINE__, - "Failed to map TTL trigger for (LA=%x%X)", - la); - return status; -} - - -/* - * vxi_io_report() - */ -EPVXISTAT vxi_io_report( -unsigned level -) -{ - return epvxiIOReport(level); -} - - -/* - * - * epvxiIOReport - * - * call io report routines for all registered devices - * - */ -EPVXISTAT epvxiIOReport( -unsigned level -) -{ - unsigned la; - unsigned resmanLA; - EPVXISTAT status; - - /* Get local address from VME address. */ - /* in case the resource manager has not been called */ - if(!epvxi_local_base){ - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - (char *)VXIBASEADDR, - (char **)&epvxi_local_base); - if(status != OK){ - status = S_epvxi_badConfig; - errMessage( - status, - "A16 base map failed"); - return status; - } - } - - /* - * special support for the niCPU030 - * since it does not see itself - */ - nicpu030_init(&root_extender); - - if(niCpu030Initialized){ - if(pnivxi_func[(unsigned)e_GetMyLA]){ - resmanLA = (*pnivxi_func[(unsigned)e_GetMyLA])(); - printf("VXI LA 0x%02X ", resmanLA); - } - } - else{ - printf("VXI LA "); - } - - printf("%s resident resource manager\n", - sysModel()); - - for(la=first_la; la<=last_la; la++){ - report_one_device(la, level); - } - - return VXI_SUCCESS; -} - - -/* - * - * report_one_device() - * - */ -LOCAL EPVXISTAT report_one_device( -unsigned la, -int level -) -{ - VXIDI *plac; - VXISZ *pvxisz; - unsigned slot; - EPVXISTAT status; - int make; - int model; - struct vxi_csr *pcsr; - int16_t id; - - pcsr = VXIBASE(la); - status = vxMemProbe( (char *)pcsr, - READ, - sizeof(id), - (char *)&id); - if(status != OK){ - return S_epvxi_internal; - } - - status = vxi_find_slot(pcsr, &slot, &pvxisz); - if(status){ - pvxisz = NULL; - slot = UKN_SLOT; - } - - - /* - * the logical address - */ - printf("VXI LA 0x%02X ", la); - - /* - * crate and slot - */ - if(pvxisz){ - printf( "slot zero LA=0X%02X slot %2d ", - pvxisz->la, - slot); - } - else{ - printf( "slot zero LA=?? slot=?? ", - UKN_LA, - UKN_LA); - } - - - /* - * make - */ - make = VXIMAKE(pcsr); - { - char buf[32]; - unsigned nactual; - - status = epuxiLookupMakeName( - make, - buf, - sizeof(buf)-1, - &nactual); - if(status==VXI_SUCCESS){ - buf[sizeof(buf)-1] = NULL; - printf("%s ", buf); - } - else{ - printf("make 0x%03X ", make); - } - } - - /* - * model - */ - model = VXIMODEL(pcsr); - { - char model_name[32]; - unsigned int nread; - - status = epuxiLookupModelName( - make, - model, - model_name, - sizeof(model_name)-1, - &nread); - if(status){ - printf( "model 0x%03X ", model); - } - else{ - model_name[sizeof(model_name)]=NULL; - printf( "%s ", model_name); - } - } - - printf("\n"); - - if(!VXIPASSEDSTATUS(pcsr->dir.r.status)){ - printf("\t---- Self Test Failed ----\n"); - return VXI_SUCCESS; - } - - /* - * call their io report routine if they supply one - */ - plac = epvxiLibDeviceList[la]; - if(plac){ - if(plac->pio_report_func){ - (*plac->pio_report_func)(la, level); - } - } - - if(level == 0){ - return VXI_SUCCESS; - } - - /* - * print out physical addresses of the cards - */ - printf("\tA16=0x%X ", (int) VXIBASE(la)); - if(VXIMEMENBL(pcsr)){ - long VMEmod = NULL; - char *VMEaddr = NULL; - char *pname = NULL; - char *pbase; - - switch(VXIADDRSPACE(pcsr)){ - case VXI_ADDR_EXT_A24: - VMEmod = VME_AM_STD_SUP_DATA; - VMEaddr = (char *) (pcsr->dir.w.offset<<8); - pname = "A24"; - break; - case VXI_ADDR_EXT_A32: - VMEmod = VME_AM_EXT_SUP_DATA; - VMEaddr = (char *) (pcsr->dir.w.offset<<16); - pname = "A32"; - break; - } - if(pname){ - status = sysBusToLocalAdrs( - VMEmod, - VMEaddr, - &pbase); - if(status>=0){ - printf( "%s=0x%X", - pname, - (unsigned)pbase); - } - else{ - printf( "failure mapping %s=%x", - pname, - (unsigned)VMEaddr); - } - } - } - printf("\n"); - - if(VXISLOT0MODEL(pcsr)){ - printf("\tSlot Zero Device\n"); - } - - printf( "\t%s device", - vxi_device_class_names[VXICLASS(pcsr)]); - switch(VXICLASS(pcsr)){ - case VXI_MEMORY_DEVICE: - break; - - case VXI_EXTENDED_DEVICE: - if(VXIMXI(pcsr)){ - mxi_io_report(pcsr, level); - } - break; - - case VXI_MESSAGE_DEVICE: - { - unsigned long resp; - - if(VXICMDR(pcsr)){ - printf(", cmdr"); - } - if(VXIFHS(pcsr)){ - printf(", fh"); - } - if(VXISHM(pcsr)){ - printf(", shm"); - } - if(VXIMBINT(pcsr)){ - printf(", interrupter"); - } - if(VXIVMEBM(pcsr)){ - printf(", VME bus master"); - } - if(VXISIGREG(pcsr)){ - printf(", has signal reg"); - } - printf("\n"); - /* - * all message based devices are required to - * implement this command query - */ - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL, - &resp); - if(status==VXI_SUCCESS){ - printf("\tprotocols("); - if(MBR_REV_12(resp)){ - printf("Rev 1.2 device, "); - } - if(MBR_RP_LW(resp)){ - printf("long word serial, "); - } - if(MBR_RP_ELW(resp)){ - printf("extended long word serial, "); - } - if(MBR_RP_I(resp)){ - printf("VXI instr, "); - } - if(MBR_RP_I4(resp)){ - printf("488 instr, "); - } - if(MBR_RP_TRG(resp)){ - printf("sft trig, "); - } - if(MBR_RP_PH(resp)){ - printf("prog int hdlr, "); - } - if(MBR_RP_PI(resp)){ - printf("prog interrupter, "); - } - if(MBR_RP_EG(resp)){ - printf("event gen, "); - } - if(MBR_RP_RG(resp)){ - printf("resp gen, "); - } - printf(")"); - } - break; - } - case VXI_REGISTER_DEVICE: - break; - - } - printf("\n"); - - return VXI_SUCCESS; -} - - -/* - * - * mxi_io_report() - * - * - */ -LOCAL void mxi_io_report( -struct vxi_csr *pmxi, -int level -) -{ - unsigned la; - unsigned ha; - unsigned a; - unsigned b; - char *msg; - - printf(", MXI sub class\n\t"); - - if(pmxi->dir.w.dd.mxi.control & MXI_UPPER_LOWER_BOUNDS){ - la = VXIADDRMASK & - pmxi->dir.w.dd.mxi.la_window; - ha = VXIADDRMASK & - (pmxi->dir.w.dd.mxi.la_window>>NVXIADDRBITS); - if(la 0 since la < ha - */ - ha--; - } - else if(la>ha){ - msg = "MXI LA's seen by this crate"; - /* - * la > 0 since la > ha - */ - la--; - } - else if(la == 0){ - msg = "LA window disabled"; - la = 0; - ha = 0; - } - else if(la >= 0x80){ - msg = "MXI LA's seen by this crate"; - la = 0; - ha = 0xff; - } - else{ - msg = "local VXI LA's seen by MXI"; - la = 0; - ha = 0xff; - } - - printf(", %s 0x%X-0x%X\n\t", - msg, - la, - ha); - - a = pmxi->dir.w.dd.mxi.a24_window_low; - b = pmxi->dir.w.dd.mxi.a24_window_high; - printf(", A24 window 0x%X-0x%X", - a, - b); - - a = pmxi->dir.w.dd.mxi.a32_window_low; - b = pmxi->dir.w.dd.mxi.a32_window_high; - printf(", A32 window 0x%X-0x%X", - a, - b); - } -# ifdef BASE_PLUS_SIZE_MXI_SUPPORT - else{ - la = VXIADDRMASK & - pmxi->dir.w.dd.mxi.la_window; - ha = la + (MXI_LA_WINDOW_SIZE_MASK & - (pmxi->dir.w.dd.mxi.la_window>>NVXIADDRBITS)); - - printf(", LA window 0x%X-0x%X", - la, - ha); - } -# endif -} - - -/* - * - * vxi_allocate_int_lines() - * - * - */ -LOCAL void vxi_allocate_int_lines(void) -{ - EPVXISTAT status; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - VXIDI *pvxidi; - unsigned la; - unsigned long resp; - unsigned long cmd; - unsigned line_count; - - for( la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - pvxidi = *ppvxidi; - - if(!pvxidi){ - continue; - } - - pcsr = VXIBASE(la); - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - /* - * find out if this is a programmable interrupter - */ - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected READ_PROTOCOL (LA=0x%X)", - la); - continue; - } - if(!MBR_RP_PI(resp)){ - continue; - } - - printf("Programming interrupter (LA=0x%X)\n", la); - - cmd = MBC_READ_INTERRUPTERS; - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected READ_INTERRUPTERS (LA=0x%X)", - la); - continue; - } - line_count = resp&MBR_READ_INTERRUPTERS_MASK; - while(line_count--){ - cmd = MBC_ASSIGN_INTERRUPTER_LINE | - ((line_count+1)<<4) | - VXIMSGINTLEVEL; - sysIntEnable(VXIMSGINTLEVEL); - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected ASSIGN_INT(LA=0x%X)", - la); - continue; - } - if(MBR_STATUS(resp) != MBR_STATUS_SUCCESS){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "ASSIGN_INT failed (LA=0x%X)", - la); - continue; - } - } - } -} - - - - -/* - * - * epvxiSymbolTableInit() - * (written by Richard Baker LANL summer intern) - * - */ -LOCAL EPVXISTAT epvxiSymbolTableInit(void) -{ - - epvxiSymbolTable = symTblCreate( - EPVXI_MAX_SYMBOLS_LOG2, - FALSE, - memSysPartId); - if(!epvxiSymbolTable){ - return S_epvxi_noMemory; - } - - return VXI_SUCCESS; -} - - -/* - * - * epuxiRegisterModelName() - * (written by Richard Baker LANL summer intern) - * - * - */ -EPVXISTAT epvxiRegisterModelName( -unsigned int make, -unsigned int model, -char *pmodel_name -) -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pcopy; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableDeviceIdString, make,model); - pcopy = (char *) malloc(strlen(pmodel_name)+1); - if(pcopy == NULL){ - return S_epvxi_noMemory; - } - - strcpy(pcopy, pmodel_name); - - status = symAdd( - epvxiSymbolTable, - name, - pcopy, - EPVXI_MODEL_NAME_SYMBOL, - NULL); - if(status < 0){ - char *pold_model_name; - UINT8 type; - - free(pcopy); - - status = symFindByNameAndType( - epvxiSymbolTable, - name, - &pold_model_name, - &type, - EPVXI_MODEL_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMemory; - } - else if(strcmp(pmodel_name, pold_model_name)){ - return S_epvxi_nameMismatch; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiRegisterMakeName() - * - * - */ -EPVXISTAT epvxiRegisterMakeName( -unsigned int make, -char *pmake_name -) -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pcopy; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableMakeIdString, make); - pcopy = (char *) malloc(strlen(pmake_name)+1); - if(pcopy == NULL){ - return S_epvxi_noMemory; - } - - strcpy(pcopy, pmake_name); - - status = symAdd( - epvxiSymbolTable, - name, - pcopy, - EPVXI_MAKE_NAME_SYMBOL, - NULL); - if(status<0){ - char *pold_make_name; - UINT8 type; - - free(pcopy); - - status = symFindByNameAndType( - epvxiSymbolTable, - name, - &pold_make_name, - &type, - EPVXI_MAKE_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMemory; - } - else if(strcmp(pmake_name, pold_make_name)){ - return S_epvxi_nameMismatch; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * epuxiLookupMakeName() - * (written by Richard Baker LANL summer intern) - * - */ -EPVXISTAT epuxiLookupMakeName( -unsigned int make, /* VXI manuf. */ -char *pbuffer, /* model name return */ -unsigned int bufsize, /* size of supplied buf */ -unsigned int *preadcount) /* n bytes written */ -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pmake_name; - UINT8 type; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableMakeIdString, make); - status = symFindByNameAndType( - epvxiSymbolTable, - name, - &pmake_name, - &type, - EPVXI_MAKE_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMatch; - } - if(type != EPVXI_MAKE_NAME_SYMBOL){ - abort(0); - } - *preadcount = min(strlen(pmake_name)+1, bufsize); - strncpy(pbuffer, pmake_name, bufsize); - - return VXI_SUCCESS; -} - - -/* - * - * epuxiLookupModelName() - * (written by Richard Baker LANL summer intern) - * - */ -EPVXISTAT epuxiLookupModelName( -unsigned int make, /* VXI manuf. */ -unsigned int model, /* VXI model code */ -char *pbuffer, /* model name return */ -unsigned int bufsize, /* size of supplied buf */ -unsigned int *preadcount) /* n bytes written */ -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pmodel_name; - UINT8 type; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableDeviceIdString, make, model); - status = symFindByNameAndType( - epvxiSymbolTable, - name, - &pmodel_name, - &type, - EPVXI_MODEL_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMatch; - } - if(type != EPVXI_MODEL_NAME_SYMBOL){ - abort(0); - } - *preadcount = min(strlen(pmodel_name)+1, bufsize); - strncpy(pbuffer, pmodel_name, bufsize); - - return VXI_SUCCESS; -} - - -/* - * - * epvxiExtenderList() - * - * list any bus extenders - */ -EPVXISTAT epvxiExtenderList(void) -{ - epvxiExtenderPrint(&root_extender); - - return VXI_SUCCESS; -} - - - -/* - * - * epvxiExtenderPrint - * - * - */ -LOCAL void epvxiExtenderPrint(VXIE *pvxie) -{ - VXIE *psubvxie; - - - printf( "%s Extender LA=0x%02X\n", - ext_type_name[pvxie->type], - pvxie->la); - - if(pvxie->la_mapped){ - printf("\tLA window 0x%02X - 0x%02X\n", - pvxie->la_low, - pvxie->la_high); - } - - if(pvxie->A24_mapped){ - printf("\tA24 window base=0x%08X size=0x%08X\n", - pvxie->A24_base, - pvxie->A24_size); - } - - if(pvxie->A32_mapped){ - printf("\tA32 window base=0x%08X size=0x%08X\n", - pvxie->A32_base, - pvxie->A32_size); - } - - psubvxie = (VXIE *) &pvxie->extenders.node; - while(psubvxie = (VXIE *) ellNext((ELLNODE *)psubvxie)){ - epvxiExtenderPrint(psubvxie); - } -} - - -/* - * - * register some common manufacturer names - * for consistency - * - */ -LOCAL void epvxiRegisterCommonMakeNames(void) -{ - int i; - EPVXISTAT status; - - for(i=0; i -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -enum msgDeviceSyncType { - syncInt, - syncSignal, - syncPoll -}; - -typedef -struct epvxiMessageDeviceInfo{ - unsigned err:1; /* error pending */ - unsigned trace:1; /* debug trace on */ - unsigned long timeout; /* in ticks */ - enum msgDeviceSyncType syncType; - SEM_ID syncSem; - FAST_LOCK lck; -}VXIMDI; - -#define VXIMSGSYNCDELAY 1 - -#define DEFAULTMSGTMO (sysClkRateGet()*10) /* 10 sec */ -#define MAXIMUMTMO (0xffffff) - -/* - * set to a valid LA when the LA of the - * commander is located - */ -LOCAL -int msgCommanderLA = (-1); - - -#define abort(A) taskSuspend(0) - -#define epvxiPMsgConfig(LA)\ -((VXIMDI *)(epvxiLibDeviceList[LA]?epvxiLibDeviceList[LA]->pMsgConfig:0)) - -/* - * local functions - */ -LOCAL void set_la( - unsigned la, - unsigned *pla -); - -LOCAL void vxiMsgInt( - unsigned la -); - -LOCAL void signalHandler( - int16_t signal -); - -LOCAL EPVXISTAT epvxiReadSlowHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -); - -#ifdef FASTHANDSHAKE -LOCAL EPVXISTAT epvxiReadFastHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -); -#endif - -LOCAL EPVXISTAT vxiMsgClose( - unsigned la -); - -LOCAL EPVXISTAT vxiMsgOpen( - unsigned la -); - -LOCAL void vxiMsgSignalSetup( - void -); - -LOCAL void vxiCPU030MsgSignalSetup( - void -); - -LOCAL void vxiHP1404MsgSignalSetup( - void -); - -LOCAL EPVXISTAT vxiAttemptAsyncModeControl( - unsigned la, - unsigned long cmd -); - -LOCAL EPVXISTAT vxiMsgSync( - unsigned la, - unsigned resp_mask, - unsigned resp_state, - int override_err -); - -LOCAL EPVXISTAT fetch_protocol_error( - unsigned la -); - - -/* - * should be in a header - */ -EPVXISTAT vxi_msg_test( - unsigned la -); - -EPVXISTAT vxi_msg_print_id( - unsigned la -); - -EPVXISTAT vxi_msg_test_protocol_error( - unsigned la -); - - -/* - * - * vxi_msg_test() - * - */ -EPVXISTAT vxi_msg_test( - unsigned la -) -{ - char buf[512]; - unsigned long count; - EPVXISTAT status; - - status = epvxiWrite(la, "*IDN?", 5, &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = NULL; - printf("%s %d\n", buf,count); - - status = epvxiWrite(la, "*TST?", 5, &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = NULL; - printf("%s %d\n", buf, count); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_msg_print_id - * - */ -EPVXISTAT vxi_msg_print_id( - unsigned la -) -{ - char buf[32]; - unsigned long count; - char *pcmd = "*IDN?"; - EPVXISTAT status; - - status = epvxiWrite(la, pcmd, strlen(pcmd), &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = NULL; - printf(" %s ", buf); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_msg_test_protocol_error - * - */ -EPVXISTAT vxi_msg_test_protocol_error( - unsigned la -) -{ - int i; - EPVXISTAT status; - - for(i=0;i<1000;i++){ - status = epvxiCmd(la, MBC_READ_PROTOCOL); - if(status){ - return status; - } - } - return VXI_SUCCESS; -} - - -/* - * epvxiCmd() - * - * deliver a command to a msg based device - * - */ -EPVXISTAT epvxiCmd( -unsigned la, -unsigned long cmd -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - EPVXISTAT status; - -# ifdef DEBUG - printf("cmd to be sent %4x (la=%d)\n", cmd, la); -# endif - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - - /* - * RULE C.3.3 - * A commander shall not send any command requiring a servant to - * place data in in its data registers until the commander has read - * (from the data registers) all data generated by previous commands - * (and the read ready bit is set to zero). - */ - status = vxiMsgSync( - la, - VXIWRITEREADYMASK|VXIREADREADYMASK, - VXIWRITEREADYMASK, - cmd == MBC_CLEAR); - if(status>=0){ - pcsr->dir.w.dd.msg.dlow = cmd; - } - else{ - /* - * RULE C.3.2 - */ - if(pcsr->dir.r.dd.msg.response&VXIREADREADYMASK){ - status = S_epvxi_unreadData; - } - } - - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Cmd -> %x\n", - la, - cmd); - } - - return status; -} - - - -/* - * epvxiQuery() - * - * query the response to a command - * - */ -EPVXISTAT epvxiQuery( -unsigned la, -unsigned long *presp -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - - status = vxiMsgSync( - la, - VXIREADREADYMASK, - VXIREADREADYMASK, - FALSE); - if(status==VXI_SUCCESS){ - *presp = pcsr->dir.r.dd.msg.dlow; - } - - FASTUNLOCK(&pvximdi->lck); - -# ifdef DEBUG - printf("resp returned %4x (la=%d)\n", *presp, la); -# endif - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Query -> %x\n", - la, - *presp); - } - - return status; -} - - -/* - * epvxiCmdQuery() - */ -EPVXISTAT epvxiCmdQuery( -unsigned la, -unsigned long cmd, -unsigned long *presp -) -{ - EPVXISTAT status; - - status = epvxiCmd(la, cmd); - if(status){ - return status; - } - status = epvxiQuery(la, presp); - return status; -} - - -/* - * epvxiRead() - * - * Read a string using fast handshake mode - * or call a routine to do a slow handshake - * if that is all that is supported. - */ -EPVXISTAT epvxiRead( -unsigned la, -char *pbuf, -unsigned long count, -unsigned long *pread_count, -unsigned long option -) -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - /* - * does the device support fast handshake - */ -# ifdef FASTHANDSHAKE - if(VXIFHS(pcsr)){ - status = epvxiReadFastHandshake( - la, - pbuf, - count, - pread_count, - option); - } - else{ -# endif - status = epvxiReadSlowHandshake( - la, - pbuf, - count, - pread_count, - option); -# ifdef FASTHANDSHAKE - } -# endif - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Read -> %*s\n", - la, - (int)count, - pbuf); - } - - return status; -} - - -#ifdef FASTHANDSHAKE -@@@@ needs to tell them if their buffer is full - and the EOM bit wasnt se @@@@ -/* - * epvxiReadFastHandshake() - * - * Read a string using fast handshake mode - * or call a routine to do a slow handshake - * if that is all that is supported. - * - * This function will be tested and installed - * if a card with fast handshake s found to exist - * - */ -LOCAL EPVXISTAT epvxiReadFastHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - short resp; - int fhm; - short cmd; - EPVXISTAT status; - int i; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - fhm = FALSE; - /* - * always leave room to write a NULL termination - */ - for(i=0; i<(count-1); i++){ - - while(TRUE){ - /* - * wait for fast handshake mode - */ - if(!fhm){ - status = vxiMsgSync( - la, - VXIFHSMMASK, - 0, - FALSE); - if(status){ - *pread_count = i; - goto exit; - } - fhm = TRUE; - } - - cmd = MBC_BR; - status = vxMemProbe( - &pcsr->dir.r.dd.msg.dlow, - WRITE, - sizeof(pcsr->dir.r.dd.msg.dlow), - &cmd); - if(status == OK){ - break; - } - fhm = FALSE; - } - - while(TRUE){ - /* - * wait for fast handshake mode - */ - if(!fhm){ - status = vxiMsgSync( - la, - VXIFHSMMASK, - 0, - FALSE); - if(status){ - *pread_count = i; - goto exit; - } - fhm = TRUE; - } - - status = vxMemProbe( - &pcsr->dir.r.dd.msg.dlow, - READ, - sizeof(pcsr->dir.r.dd.msg.dlow), - &resp); - if(status == OK){ - break; - } - fhm = FALSE; - } - - *pbuf = resp; - pbuf++; - if(resp & MBC_END){ - *pread_count = i+1; - break; - } - } - status = VXI_SUCCESS; -exit: - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - *pbuf = NULL; - - return status; -} -#endif - - -/* - * epvxiReadSlowHandshake() - */ -LOCAL -EPVXISTAT epvxiReadSlowHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - short resp; - EPVXISTAT status; - int function_status; - int i; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - /* - * always leave room to write a NULL termination - */ - if(count<1){ - return S_epvxi_bufferFull; - } - - FASTLOCK(&pvximdi->lck); - - /* - * always leave room to write a NULL termination - */ - function_status = S_epvxi_bufferFull; - for(i=0; i<(count-1); i++){ - - /* - * wait for handshake - * - * RULE C.3.3 specifies that there shouldnt be - * any unread data present at this point . - */ - status = vxiMsgSync( - la, - VXIWRITEREADYMASK|VXIDORMASK|VXIREADREADYMASK, - VXIWRITEREADYMASK|VXIDORMASK, - FALSE); - if(status){ - if(pcsr->dir.r.dd.msg.response&VXIREADREADYMASK){ - function_status = S_epvxi_unreadData; - } - else{ - function_status = status; - } - break; - } - - pcsr->dir.w.dd.msg.dlow = MBC_BR; - - /* - * wait for handshake - */ - status = vxiMsgSync( - la, - VXIREADREADYMASK, - VXIREADREADYMASK, - FALSE); - if(status){ - function_status = status; - break; - } - - resp = pcsr->dir.r.dd.msg.dlow; - - *pbuf = resp; - pbuf++; - if(resp & MBC_END){ - - /* - * so the read count will be correct below - */ - i++; - function_status = VXI_SUCCESS; - break; - } - } - FASTUNLOCK(&pvximdi->lck); - - *pread_count = i; - - /* - * append the NULL - */ - *pbuf = NULL; - - if(function_status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - return function_status; -} - - -/* - * epvxiWrite() - * (set the end bit on the last byte sent) - */ -EPVXISTAT epvxiWrite( -unsigned la, -char *pbuf, -unsigned long count, -unsigned long *pwrite_count, -unsigned long option -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - int i; - short cmd; - short extra; - EPVXISTAT status; - char *pstr; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - pstr = pbuf; - if(option&epvxiWriteOptPartialMsg){ - extra = 0; - } - else{ - extra = MBC_END; - } - for(i=0; idir.r.dd.msg.dlow = cmd; - pstr++; - } - *pwrite_count = i; - status = VXI_SUCCESS; -exit: - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Write -> %*s\n", - la, - (int)count, - pbuf); - } - - return status; -} - - -/* - * - * epvxiSetTimeout() - * - * change the message based transfer timeout - * (timeout is in milli sec) - * - */ -EPVXISTAT epvxiSetTimeout( -unsigned la, -unsigned long timeout -) -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - /* - * order of operations significant here - */ - if(timeout > MAXIMUMTMO){ - return S_epvxi_timeoutToLarge; - } - - pvximdi->timeout = (timeout * sysClkRateGet())/1000; - - return VXI_SUCCESS; -} - - -/* - * - * epvxiSetTraceEnable() - * - * turn trace mode on or off - * - */ -EPVXISTAT epvxiSetTraceEnable(la, enable) -unsigned la; -int enable; -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pvximdi->trace = enable?TRUE:FALSE; - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgClose() - * - * - */ -LOCAL -EPVXISTAT vxiMsgClose( -unsigned la -) -{ - EPVXISTAT status; - VXIMDI *pvximdi; - - pvximdi = epvxiPMsgConfig(la); - if(!pvximdi){ - return S_epvxi_notOpen; - } - - status = semDelete(pvximdi->syncSem); - if(status){ - errMessage( - S_epvxi_internal, - "vxiMsgClose(): bad sem id"); - } - FASTLOCKFREE(&pvximdi->lck); - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgOpen() - * - * - */ -LOCAL -EPVXISTAT vxiMsgOpen( - unsigned la -) -{ - EPVXISTAT status; - VXIDI *pvxidi; - VXIMDI *pvximdi; - unsigned long resp; - unsigned long read_proto_resp; - unsigned long cmd; - struct vxi_csr *pcsr; - int signalSync = FALSE; - int intSync = FALSE; - - - /* - * return quickly if we have been here before - */ - pvxidi = epvxiLibDeviceList[la]; - if(pvxidi){ - if(pvxidi->pMsgConfig){ - return VXI_SUCCESS; - } - } - - /* - * standard verification of unknown LA - */ - status = epvxiDeviceVerify(la); - if(status){ - return status; - } - - pcsr = VXIBASE(la); - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - return S_epvxi_notMsgDevice; - } - - pvximdi = (VXIMDI *) calloc(1, sizeof(*pvximdi)); - if(!pvximdi){ - return S_epvxi_noMemory; - } - - pvxidi->pMsgConfig = (void *) pvximdi; - - vxiMsgSignalSetup(); - - pvximdi->syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - if(!pvximdi->syncSem){ - return S_epvxi_noMemory; - } - - /* - * - * assume the worst for the transfers below - * - */ - pvximdi->timeout = DEFAULTMSGTMO; - pvximdi->syncType = syncPoll; - FASTLOCKINIT(&pvximdi->lck); - - /* - * if it is not an interrupter or a signal - * generator then we poll - */ - if(!VXIMBINT(pcsr) && !VXIVMEBM(pcsr)){ - return VXI_SUCCESS; - } - - /* - * if it is not a response generator then we poll - */ - status = epvxiCmdQuery( - la, - (unsigned long) MBC_READ_PROTOCOL, - &read_proto_resp); - if(status){ - /* - * All devices are required by the VXI standard - * to accept this command while in the - * configure state or in the normal operation - * state. Some dont. - * - */ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected MBC_READ_PROTOCOL (la=0X%X)", - la); - return VXI_SUCCESS; - } - -return VXI_SUCCESS; - - if(!MBR_RP_RG(read_proto_resp)){ - return VXI_SUCCESS; - } - -printf("mb device has response gen\n"); - - /* - * try to setup interrupt synchronization first - * (this works even if we dont have a signal register) - */ - if(VXIMBINT(pcsr)){ - cmd = MBC_ASYNC_MODE_CONTROL | - MBC_AMC_RESP_ENABLE | - MBC_AMC_RESP_INT_ENABLE; - status = vxiAttemptAsyncModeControl(la, cmd); - if(status>=0){ - printf( "%s: mb device has int sync!\n", - __FILE__); - intSync = TRUE; - } - } - - /* - * hopefully a signal register is available if we get to here - */ - if(VXIVMEBM(pcsr) && !intSync && msgCommanderLA>=0){ - cmd = MBC_ASYNC_MODE_CONTROL | - MBC_AMC_RESP_ENABLE | - MBC_AMC_EVENT_ENABLE | - MBC_AMC_RESP_SIGNAL_ENABLE | - MBC_AMC_EVENT_SIGNAL_ENABLE; - status = vxiAttemptAsyncModeControl(la, cmd); - if(status>=0){ - printf( "%s: mb device has signal sync!\n", - __FILE__); - signalSync = TRUE; - } - } - - if(!intSync && !signalSync){ - errMessage( - S_epvxi_msgDeviceFailure, - "mb responder failed to configure"); - return VXI_SUCCESS; - } - - cmd = MBC_CONTROL_RESPONSE; - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errMessage( - status, - "Control response rejected by responder"); - vxiMsgClose(la); - return status; - } - if( MBR_STATUS(resp) != MBR_STATUS_SUCCESS || - (resp^cmd)&MBR_CR_CONFIRM_MASK){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "Control Response Failed %x", - resp); - return VXI_SUCCESS; - } -printf("sent ctrl resp (la=%d) (cmd=%x)\n", la, cmd); - -printf("synchronized msg based device is ready!\n"); - - if(intSync){ - pvximdi->syncType = syncInt; - } - if(signalSync){ - pvximdi->syncType = syncSignal; - } - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgSignalSetup - * - * - */ -LOCAL -void vxiMsgSignalSetup( - void -) -{ - static char vxiMsgSignalInit; - - if(vxiMsgSignalInit){ - return; - } - - vxiMsgSignalInit = TRUE; - - vxiHP1404MsgSignalSetup(); - - if(msgCommanderLA<0){ - vxiCPU030MsgSignalSetup(); - } - - if(msgCommanderLA<0){ - errMessage( - S_epvxi_noCmdr, - NULL); - } -} - - -/* - * - * vxiCPU030MsgSignalSetup - * - * - */ -LOCAL void vxiCPU030MsgSignalSetup( - void -) -{ - int niMsgLA; - EPVXISTAT status; - - if( !pnivxi_func[(unsigned)e_EnableSignalInt] || - !pnivxi_func[(unsigned)e_SetSignalHandler] || - !pnivxi_func[(unsigned)e_RouteSignal] || - !pnivxi_func[(unsigned)e_GetMyLA]){ - return; - } - - niMsgLA = (*pnivxi_func[(unsigned)e_GetMyLA])(); - -# define ANY_DEVICE (-1) -# define MSG_RESP_ENABLE (0x3f) - status = (*pnivxi_func[(unsigned)e_RouteSignal])( - ANY_DEVICE, - ~0); /* enable every thing */ - if(status){ - return; - } - -# define UKN_DEVICE (-2) - status = (*pnivxi_func[(unsigned)e_SetSignalHandler])( - UKN_DEVICE, - signalHandler); - if(status){ - return; - } - - status = (*pnivxi_func[(unsigned)e_EnableSignalInt])(); - if(status){ - return; - } - - msgCommanderLA = niMsgLA; - - return; -} - - -/* - * - * vxiHP1404MsgSignalSetup - * - * - */ -LOCAL -void vxiHP1404MsgSignalSetup( - void -) -{ - epvxiDeviceSearchPattern dsp; - int hpMsgLA = -1; - int hpRegLA = -1; - EPVXISTAT status; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_MSG; - status = epvxiLookupLA(&dsp, set_la, (void *)&hpMsgLA); - if(status){ - return; - } - if(hpMsgLA<0){ - return; - } - dsp.flags = VXI_DSP_make | VXI_DSP_slot; - dsp.make = VXI_MAKE_HP; - dsp.slot = epvxiLibDeviceList[hpMsgLA]->slot; - status = epvxiLookupLA(&dsp, set_la, (void *)&hpRegLA); - if(status){ - return; - } - - if(hpRegLA<0){ - return; - } - - msgCommanderLA = hpMsgLA; - status = hpE1404SignalConnect(hpRegLA, signalHandler); - if(status){ - errMessage(status, NULL); - } - - return; -} - - -/* - * - * set_la - * - * - */ -LOCAL void set_la( -unsigned la, -unsigned *pla -) -{ - *pla = la; -} - - -/* - * - * vxiAttemptAsyncModeControl - * - * - */ -LOCAL EPVXISTAT vxiAttemptAsyncModeControl( - unsigned la, - unsigned long cmd -) -{ - EPVXISTAT status; - unsigned long resp; - unsigned long tmpcmd; - - if(msgCommanderLA<0 && cmd&MBC_AMC_RESP_SIGNAL_ENABLE){ - return S_epvxi_badConfig; - } - - /* - * this step tells the device what la to signal at - */ - if(cmd & MBC_AMC_RESP_SIGNAL_ENABLE){ - tmpcmd = MBC_IDENTIFY_COMMANDER | msgCommanderLA; - status = epvxiCmd( - la, - tmpcmd); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "IDENTIFY_COMMANDER rejected (la=0X%X)", - la); - return status; - } -printf("sent id cmdr (la=0X%X) (cmd=%x)\n", la, tmpcmd); - } - - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Async mode control rejected (la=0X%X)", - la); - return status; - } - if( MBR_STATUS(resp) != MBR_STATUS_SUCCESS || - (resp^cmd)&MBR_AMC_CONFIRM_MASK){ - status = S_epvxi_msgDeviceFailure; - errPrintf( - status, - __FILE__, - __LINE__, - "async mode ctrl failure (la=0X%X,cmd=%x,resp=%x)", - la, - cmd, - resp); - return status; - } -printf("sent asynch mode control (la=%d) (cmd=%x)\n",la,cmd); - - - if(cmd & MBC_AMC_RESP_INT_ENABLE){ - intConnect( - INUM_TO_IVEC(la), - vxiMsgInt, - la); -printf("connected to interrupt (la=%d)\n", la); - } - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgSync() - * - * - */ -LOCAL EPVXISTAT vxiMsgSync( - unsigned la, - unsigned resp_mask, - unsigned resp_state, - int override_err -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - EPVXISTAT status; - long timeout; - unsigned short resp; - int pollcnt = 100; - - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - -# ifdef DEBUG - printf( "Syncing to resp mask %4x, request %4x (la=%d)\n", - resp_mask, - resp_state, - la); -# endif - - timeout = pvximdi->timeout; - do{ - int sync; - - resp = pcsr->dir.r.dd.msg.response; - - sync = !((resp^resp_state)&resp_mask); - - if(!(resp & VXIERRNOTMASK)){ - if(!override_err && !pvximdi->err){ - pvximdi->err = TRUE; - return S_epvxi_protocolError; - } - } - - if(sync){ - return VXI_SUCCESS; - } - - /* - * this improves VXI throughput at the - * expense of sucking CPU - */ - if(pollcnt>0){ - pollcnt--; - } - else{ - status = semTake( - pvximdi->syncSem, - VXIMSGSYNCDELAY); - if(status){ - timeout -= VXIMSGSYNCDELAY; - } - } - } - while(timeout>0); - - /* - * sync timed out if we got here - */ - status = S_epvxi_deviceTMO; - errPrintf( - status, - __FILE__, - __LINE__, - "msg dev timed out after %d sec", - (pvximdi->timeout-timeout) / sysClkRateGet()); - errPrintf( - status, - __FILE__, - __LINE__, - "resp mask %4x, request %4x, actual %4x", - resp_mask, - resp_state, - resp); - return status; -} - - -/* - * - * fetch_protocol_error - * - */ -LOCAL EPVXISTAT fetch_protocol_error( - unsigned la -) -{ - VXIMDI *pvximdi; - unsigned long error; - struct vxi_csr *pcsr; - unsigned short resp; - EPVXISTAT status; - - pvximdi = epvxiPMsgConfig(la); - if(!pvximdi){ - return S_epvxi_errFetchFailed; - } - - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL_ERROR, - &error); - if(status){ - errMessage(status, "serial protocol error fetch"); - return S_epvxi_errFetchFailed; - } - - pcsr = VXIBASE(la); - resp = pcsr->dir.r.dd.msg.response; - - if(resp & VXIERRNOTMASK){ - pvximdi->err = FALSE; - } - else{ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "Device failed to clear its ERR bit (la=0X%X)", - la); - } - - switch(error){ - case MBE_MULTIPLE_QUERIES: - status = S_epvxi_multipleQueries; - break; - case MBE_UNSUPPORTED_CMD: - status = S_epvxi_unsupportedCmd; - break; - case MBE_DIR_VIOLATION: - status = S_epvxi_dirViolation; - break; - case MBE_DOR_VIOLATION: - status = S_epvxi_dorViolation; - break; - case MBE_RR_VIOLATION: - status = S_epvxi_rrViolation; - break; - case MBE_WR_VIOLATION: - status = S_epvxi_wrViolation; - break; - case MBE_NO_ERROR: - default: - status = S_epvxi_errFetchFailed; - break; - } - - errMessage(status, "serial protocol error"); - return status; -} - - -/* - * - * vxiMsgInt - * - * - */ -LOCAL -void vxiMsgInt( - unsigned la -) -{ - VXIMDI *pvximdi; - - /* - * verify that this device is open for business - */ - pvximdi = epvxiPMsgConfig(la); - if(pvximdi){ - - /* - * - * wakeup pending tasks - * - */ - semGive(pvximdi->syncSem); - } - else{ - logMsg( - "%s: vxiMsgInt(): msg int to ukn or closed dev\n", - (int)__FILE__, - NULL, - NULL, - NULL, - NULL, - NULL); - } -} - - - -/* - * signalHandler - */ -LOCAL -void signalHandler( -int16_t signal -) -{ - unsigned signal_la; - - signal_la = signal & VXIADDRMASK; - - if(MBE_EVENT_TEST(signal)){ - logMsg( "%s: VXI event was ignored %x\n", - (int)__FILE__, - signal, - NULL, - NULL, - NULL, - NULL); - } - else{ - vxiMsgInt(signal_la); - } -} diff --git a/src/drv/drvExampleVxi.c b/src/drv/drvExampleVxi.c deleted file mode 100644 index c88cd9900..000000000 --- a/src/drv/drvExampleVxi.c +++ /dev/null @@ -1,237 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 09-09-92 - * - * Skeleton VXI driver module. - * - * 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 09-09-92 jrw written - * .02 08-24-93 joh updated for EPICS format return codes - * .03 08-24-93 joh converted to ANSI C - * .04 08-24-93 joh ran through -Wall - * - */ -#include -#include -#include - -#include -#include -#include - -typedef long exVxiStat; - -exVxiStat vti(int make, int model); - -LOCAL exVxiStat example_init(void); -LOCAL void example_stat(unsigned card, int level); -LOCAL void example_init_card(unsigned addr); -LOCAL int example_shutdown(void); -LOCAL void example_shutdown_card(unsigned la); - - -struct drvet drvExample={ - 2, - NULL, /* VXI I/O report takes care of this */ - example_init -}; - -static unsigned long exampleDriverID; /* ID used to identify this driver */ - -struct examplePrivate { - int j; - -/* - * Define all per-card private variables here. - */ -}; -#define PRIVATE_SIZE sizeof(struct examplePrivate) - -int vxi_make_example = 0x100; /* Set to proper make of the card */ -int vxi_model_example = 0x100; /* Set to proper model of the card */ - -/* - * This is a test entry point that allows a user to do a pseudo-init of - * a make and model of VXI cards. - */ -exVxiStat vti(int make, int model) -{ - vxi_make_example = make; - vxi_model_example = model; - - example_init(); - printf("Driver ID is 0x%08X\n", exampleDriverID); - return(VXI_SUCCESS); -} - -/****************************************************************************** - * - * Initialize all cards controlled by the example driver. - * - ******************************************************************************/ -LOCAL exVxiStat example_init(void) -{ - exVxiStat s; - epvxiDeviceSearchPattern dsp; - - /* - * do nothing on crates without VXI - */ - if(!epvxiResourceMangerOK) - return VXI_SUCCESS; - - if (rebootHookAdd(example_shutdown) < 0){ - s = S_dev_internal; - errMessage(s, "rebootHookAdd failed"); - return(s); - } - - exampleDriverID = epvxiUniqueDriverID(); - - dsp.flags = VXI_DSP_make; - dsp.make = vxi_make_example; - - s = epvxiLookupLA(&dsp, example_init_card, (void *)NULL); - return s; - -} - -/****************************************************************************** - * - * initialize single example card - * - ******************************************************************************/ -LOCAL void example_init_card(unsigned addr) -{ - exVxiStat s; - struct examplePrivate *ep; /* Per-card private variable area */ - struct exampleCard *ec; /* Physical address of the card */ - - /* Tell the VXI sub-system that this driver is in charge of this card */ - s = epvxiOpen(addr, exampleDriverID, PRIVATE_SIZE, example_stat); - if (s) - { - errPrintf(s, __FILE__, __LINE__, "LA=0X%X", addr); - return; - } - - printf("example_init_card entered for card at LA 0x%02X, make 0x%02X, model 0x%02X\n", addr, vxi_make_example, vxi_model_example); - - /* Allocate a private variable area for the card */ - s = epvxiFetchPConfig(addr, exampleDriverID, ep); - if(s){ - errMessage(s, NULL); - epvxiClose(addr, exampleDriverID); - return; - } - - /* Get physical base address of the card */ - ec = (struct exampleCard *) VXIBASE(addr); - - - /*********************************************** - * - * Perform card-specific initialization in here. - * - ***********************************************/ - - /* Register the card's model and make names for reporting purposes */ - s = epvxiRegisterModelName( - vxi_make_example, - vxi_model_example, - "Example Model Name"); - if(s){ - errMessage(s, NULL); - } - s = epvxiRegisterMakeName( - vxi_make_example, - "Example Make Name"); - if(s){ - errMessage(s, NULL); - } - - return; -} - - -/****************************************************************************** - * - * Shut the cards down beacuse a soft-boot will be taking place soon. - * - ******************************************************************************/ -LOCAL int example_shutdown(void) -{ - exVxiStat s; - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make; - dsp.make = vxi_make_example; - s = epvxiLookupLA(&dsp, example_shutdown_card, (void *)NULL); - if(s){ - errMessage(s, NULL); - } - - return OK; -} - -LOCAL void example_shutdown_card(unsigned la) -{ - - /* - * Perform proper operations here to disable the VXI card from - * generating interrupts and/or other backplane bus activity that - * could cause the CPUs and controllers problems during a soft-boot. - */ - - return; -} - -/****************************************************************************** - * - * Print status for a single card. - * - ******************************************************************************/ -LOCAL void example_stat( -unsigned card, -int level -) -{ - - /* - * Perform proper operations to evaluate the current operating mode - * of the card and print a summary. - */ - - - return; -} - - -/****************************************************************************** - * - * Place any user-required functions here. - * - ******************************************************************************/ diff --git a/src/drv/drvFp.c b/src/drv/drvFp.c deleted file mode 100644 index bb3215754..000000000 --- a/src/drv/drvFp.c +++ /dev/null @@ -1,526 +0,0 @@ -/* drvFp.c */ -/* base/src/drv $Id$ - * routines which are used to test and interface with the - * FP10S fast protect module - * - * Author: Matthew Stettler - * Date: 6-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 joh 070992 integrated into GTACS & added std header - * .02 joh 070992 merged in include file fp.h - * .03 joh 070992 converted some symbols to LOCAL so they stay out - * of the vxWorks global symbol table - * .04 joh 070992 took out sysSetBCL() and substituted - * sysIntEnable() so this will not be hkv2f - * specific. - * .05 joh 070992 added INUM_TO_IVEC so this will be less - * 68k dependence (added include of iv.h) - * .06 joh 070992 FP_ILEV passed to call sysIntEnable() so that the - * interrupt level can be easily changed - * .07 joh 070992 changed some printf() calls to logMsg() - * so that driver diagnostics will show up in - * the log - * .08 joh 071092 now fetches base addr from module_types.h - * .09 joh 071092 added io_report routine - * .10 joh 071092 added scan task wakeup from ISR - * .11 joh 071092 moved ivec allocation to module_types.h - * .12 joh 072792 added soft reboot int disable - * .13 joh 082792 converted to V5 vxorks - * .14 mrk 090192 support epics I/O event scan, and added DRVET - * .15 mrk 080293 Add call to taskwdInsert - * .16 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals - */ - - - -/* - * - * Routines: - * - * fp_init Finds and initializes fast protect cards - * fp_driver System interface to FP10S modules - * fp_int Interrupt service routine - * fp_en Enables/disables interrupts (toggles) - * fp_mode Sets interrupt reporting mode - * fp_reboot Clean up for soft reboots - * - * Diagnostic Routines: - * - * fp_srd Reads current local inputs and enables - * fp_frd Reads last failure register - * fp_csrd Reads control/status register - * fp_read Command line interface to fp_driver - * fp_dump Prints all fast protect status to console - * fp_monitor Monitor all cards and print failure data to - * console - * - * Routines Return: - * - * -1 No card present - * -2 Interrupt connection error - * -3 Semaphore creation error - * -4 addressing error - * -5 no memory - * 0-8 successfull completion, or # of cards found - * - */ - -static char *sccsId = "@(#)drvFp.c 1.12\t6/4/93"; - -#include "vxWorks.h" -#include "vme.h" -#include "taskLib.h" -#include /* in h/68k if this is compiling for a 68xxx */ - -#include "module_types.h" -#include -#include -#include -#include - -static long report(); -static long init(); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvFp={ - 2, - report, - init}; - -static long report() -{ - fp_io_report(); -} - -static long init() -{ - fp_init(0); - return(0); -} - -/* general constants */ -#define FP_INTLEV 5 /* interrupt level */ -#define FP_BUFSIZ 8 /* input buffer size */ - -/* csr bit definitions */ -#define CSR_RST 0x1 /* reset status */ -#define CSR_CMD1 0x2 /* force local fail */ -#define CSR_IEN 0x4 /* interrupt enable */ -#define CSR_UDEF0 0x8 /* undefined */ -#define CSR_I0 0x10 /* interrupt level bit #1 */ -#define CSR_I1 0x20 /* interrupt level bit #2 */ -#define CSR_I2 0x40 /* interrupt level bit #3 */ -#define CSR_UDEF1 0x80 /* undefined */ -#define CSR_CARM0_L 0x100 /* latched carrier monitor #0 (one shot) */ -#define CSR_CARM1_L 0x200 /* latched carrier monitor #1 (freq mon) */ -#define CSR_OPTIC 0x400 /* optical carrier input enabled */ -#define CSR_CARM 0x800 /* carrier OK */ -#define CSR_LFAIL0 0x1000 /* local fail #0 (pal monitor) */ -#define CSR_LFAIL1 0x2000 /* local fail #1 (fpga monitor) */ -#define CSR_CMON 0x4000 /* clock fail (one shot) */ -#define CSR_CHNG 0x8000 /* enable switch configuration change */ - -/* csr mask definitions */ -#define CSR_STM 0xff00 /* status mask */ -#define CSR_IM 0x70 /* interrupt level mask */ - -/* driver status */ -#define DRV_MOM 0x010000 /* momentary fault */ -#define DRV_LOC 0x020000 /* local fault */ -#define DRV_REM 0x040000 /* remote fault */ -#define DRV_CLR 0x080000 /* fault cleared */ -#define DRV_HWF 0x800000 /* hardware fault */ - -/* operating modes */ -#define FP_NMSG 0 /* no messages to console */ -#define FP_TMSG 1 /* terse messages to console */ -#define FP_FMSG 2 /* full messages to console */ -#define FP_RUN 3 /* normal operating mode */ - -/* register address map for FP10s */ -struct fp1 - { - unsigned short csr; /* control and status register */ - unsigned short srd; /* current status */ - unsigned short frd; /* latched status */ - unsigned short ivec; /* interrupt vector */ - char end_pad[0xff-0x8]; /* pad to 256 byte boundary */ - }; - -/* fast protect control structure */ -struct fp_rec - { - struct fp1 *fptr; /* pointer to device registers */ - unsigned int drvstat; /* fast protect physical inputs */ - unsigned short lastswitch; /* previous enable switch data */ - short type; /* device type */ - short num; /* device number */ - short fp_vector; /* interrupt vector */ - short mode; /* operating mode */ - unsigned int int_num; /* interrupt number */ - IOSCANPVT ioscanpvt; - }; - -static struct fp_rec *fp; /* fast protect control structure */ -static int fp_num; /* # of fast protect cards found -1 */ -static SEM_ID fp_semid; /* semaphore for monitor task */ - -static void fp_reboot(); - -/* - * fp_int - * - * interrupt service routine - * - */ -fp_int(card) -unsigned card; -{ - register struct fp_rec *ptr = &fp[card]; - register struct fp1 *regptr; - unsigned short temp0, temp1, temp2; - - regptr = ptr->fptr; - temp0 = regptr->csr; - temp1 = regptr->frd; - temp2 = regptr->srd; - switch (ptr->mode) - { - case FP_TMSG: - logMsg("fast protect interrupt!\n"); - logMsg("csr status = %x\n",temp0); - break; - case FP_FMSG: - logMsg("fast protect #%d fault! fault input = %x enable switches = %x\n", - ptr->num,temp1 & 0xff,temp2>>8); - logMsg("csr status = %x\n",temp0); - break; - case FP_RUN: - ptr->drvstat = temp2; /* save last switch data */ - ptr->drvstat |= temp1<<16; /* save fault data */ - ptr->drvstat |= (temp0 & 0xff00)<<16; /* csr status bits */ - if ((temp1 ^ (temp2>>8)) || (temp0 & CSR_CHNG)) /* fault or enable change */ - semGive(fp_semid); /* wake up monitor */ - - /* - * wakeup the interrupt driven scanner - */ - scanIoRequest(fp[card].ioscanpvt); - break; - } - ptr->int_num++; /* log interrupt */ - regptr->csr |= CSR_RST; /* clear status and rearm */ - regptr->csr ^= CSR_RST; -} - - -/* - * fp_init - * - * initialization routine for FP10s fast protect modules - * - * - */ -fp_init(addr) -unsigned int addr; -{ - int i; - short junk; - short intvec = AT8FP_IVEC_BASE; - struct fp1 *ptr; - int status; - - fp = (struct fp_rec *) calloc(bi_num_cards[AT8_FP10S_BI], sizeof(*fp)); - if(!fp){ - return -5; - } - - if(!addr){ - addr = bi_addrs[AT8_FP10S_BI]; - } - - status = sysBusToLocalAdrs( VME_AM_SUP_SHORT_IO, addr, &ptr); - if(status<0){ - logMsg("VME shrt IO addr err in the slave fast protect driver\n"); - return(-4); - } - - status = rebootHookAdd(fp_reboot); - if(status<0){ - logMsg("%s: reboot hook add failed\n", __FILE__); - } - - for (i = 0; - (i < bi_num_cards[AT8_FP10S_BI]) && (vxMemProbe(ptr,READ,2,&junk) == OK); - i++,ptr++) { - - /* register initialization */ - ptr->csr = 0x0000; /* disable interface */ - fp[i].fptr = ptr; /* hardware location */ - fp[i].fp_vector = intvec++; /* interrupt vector */ - ptr->ivec = fp[i].fp_vector; /* load vector */ - fp[i].mode = FP_NMSG; /* set default mode (no messages) */ - fp[i].int_num = 0; /* initialize interrupt number */ - fp[i].type = 10; /* board type */ - fp[i].num = i; /* board number */ - - /* initialize input buffer */ - fp[i].drvstat = ptr->srd; /* initialize enable switch data */ - fp[i].drvstat |= ptr->frd<<16; /* initialize fault data */ - fp[i].drvstat |= (ptr->csr & 0xff00)<<16; /* csr status bits */ - - /* set up interrupt handler */ - ptr->csr |= FP_INTLEV<<4; /* level 5 interrupt */ - if (intConnect(INUM_TO_IVEC(fp[i].fp_vector),fp_int,i) != OK) - return(-2); /* abort if can't connect */ - sysIntEnable(FP_INTLEV); - ptr->csr |= 0x0001; - ptr->csr ^= 0x0001; /* clear status bits */ - if (ptr->csr & CSR_OPTIC) - logMsg("fast protect #%d optically coupled\n",i); - else - logMsg("fast protect #%d elecrically coupled\n",i); - - /* start up module */ - fp[i].fptr->csr |= CSR_IEN; /* enable interrupts */ - fp[i].mode = FP_RUN; /* normal run mode */ - scanIoInit(&fp[i].ioscanpvt); - } - fp_num = i - 1; /* record max card # */ - - /* create the semaphore */ - fp_semid = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - if ((int)fp_semid == 0) /* abort if can't create semaphore */ - return(-3); - - return(i); /* return # found */ -} - - -/* - * - * fp_reboot() - * - * turn off interrupts to avoid ctrl X reboot problems - */ -LOCAL -void fp_reboot() -{ - int i; - - if(!fp){ - return; - } - - for (i = 0; i < bi_num_cards[AT8_FP10S_BI]; i++){ - - if(!fp[i].fptr){ - continue; - } - - fp[i].fptr->csr &= ~CSR_IEN; - } -} - - - -/* - * fp_en - * - * interrupt enable/disable - * (toggles the interrupt enable - joh) - * - */ -fp_en(card) -short card; -{ - unsigned short temp; - - if (card < 0 || (card > fp_num)) - return -1; - fp[card].fptr->csr = fp[card].fptr->csr ^ CSR_IEN; - if (fp[card].fptr->csr & CSR_IEN) - printf("fast protect interrupts enabled\n"); - else - printf("fast protect interrupts disabled\n"); - return 0; -} -/* - * fp_mode - * - * set interrupt reporting mode - * - */ -fp_mode(card,mode) - short card, mode; -{ - if (card < 0 || (card > fp_num)) - return -1; - fp[card].mode = mode; - return 0; -} -/* - * fp_srd - * - * read current local inputs and enable switches - * - */ -fp_srd(card,option) - short card; - short option; -{ - if (card > fp_num) return -1; - if (!option) - printf("local inputs = %x enable switches = %x\n",fp[card].fptr->srd & 0xff, - fp[card].fptr->srd>>8); - return fp[card].fptr->srd; -} -/* - * fp_frd - * - * read latched local inputs - * - */ -fp_frd(card) - short card; -{ - if (card < 0 || (card > fp_num)) - return -1; - return fp[card].fptr->frd & 0xff; -} -/* - * fp_csrd - * - * read csr contents - * - */ -fp_csrd(card) - short card; -{ - if (card < 0 || (card > fp_num)) - return -1; - return fp[card].fptr->csr & 0xff77; -} -/* - * fp_driver - * - * epics interface to fast protect - * - */ -fp_driver(card,mask,prval) - register unsigned short card; - unsigned int mask; - register unsigned int *prval; -{ - register unsigned int temp; - - if (card > fp_num) return -1; - temp = fp[card].drvstat & 0xffff0000; /* latched status info */ - temp |= fp[card].fptr->srd; /* current switches & inputs */ - *prval = temp & mask; - return 0; -} -/* - * fp_read - * - * command line interface to fp_driver - * - */ -fp_read(card) - short card; -{ - unsigned int fpval,ret; - - if ((ret = fp_driver(card,0xffffffff,&fpval)) != 0) - return ret; - printf("Card #%d enable switches = %x inputs = %x\n",card,(fpval & 0x0000ff00)>>8, - fpval & 0x000000ff); - printf("csr status = %x last fault = %x\n",fpval>>24,(fpval & 0x00ff0000)>>16); - printf("raw readback = %x\n",fpval); - return 0; -} -/* - * fp_dump - * - * dump fast protect status to console - * - */ -fp_dump() -{ - int i; - - printf("Fast protect status (fault and CSR are latched):\n"); - printf("Card#\tenables\tinputs\tfault\tCSR status\n"); - for(i = 0; i < (fp_num + 1); i++) - printf("%d\t%x\t%x\t%x\t%x\n",i,fp[i].fptr->srd>>8,fp[i].fptr->srd & 0xff, - (fp[i].drvstat & 0x00ff0000)>>16,fp[i].drvstat>>24); - return i; -} -/* - * fp_monitor - * - * monitor fast protect cards and report failures to console - * - */ -fp_mon() -{ - for(semTake(fp_semid,WAIT_FOREVER);fp_dump() != 0;semTake(fp_semid,WAIT_FOREVER)); -} -fp_monitor() -{ - static char *name = "fpmon"; - int tid; - - if ((tid = taskNameToId(name)) != ERROR) { - taskwdRemove(tid); - taskDelete(tid); - } - if((tid = taskSpawn(name,25,VX_SUPERVISOR_MODE|VX_STDIO, - 1000,fp_mon)) == ERROR) return -1; - taskwdInsert(tid,NULL,NULL); - return 0; -} - -fp_io_report(level) -int level; -{ - int i; - - for(i=0; i<=fp_num; i++){ - printf("BI: AT8-FP-S: card %d\n", i); - } -} - -fp_getioscanpvt(card,scanpvt) -short card; -IOSCANPVT *scanpvt; -{ - if ((card >= bi_num_cards[AT8_FP10S_BI])) return(0); - *scanpvt = fp[card].ioscanpvt; - return(0); -} diff --git a/src/drv/drvFpm.c b/src/drv/drvFpm.c deleted file mode 100644 index 0f4105756..000000000 --- a/src/drv/drvFpm.c +++ /dev/null @@ -1,432 +0,0 @@ -/* drvFpm.c */ -/* base/src/drv $Id$ */ - -/* - * control routines for use with the FP10M fast protect master modules - * - * routines which are used to test and interface with the - * FP10S fast protect module - * - * Author: Matthew Stettler - * Date: 6-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 joh 070992 integrated into GTACS & added std header - * .02 joh 070992 merged in include file fpm.h - * .03 joh 070992 converted some symbols to LOCAL so they stay out - * of the vxWorks global symbol table - * .04 joh 070992 took out sysSetBCL() and substituted - * sysIntEnable() so this will not be hkv2f - * specific. - * .05 joh 070992 added INUM_TO_IVEC so this will be less - * 68k dependence (added include of iv.h) - * .06 joh 070992 FP_ILEV passed to call sysIntEnable() so that the - * interrupt level can be easily changed - * .07 joh 071092 now fetches base addr from module_types.h - * .08 joh 071092 added io report routine - * .09 joh 071092 allocate config structure at run time so that - * the users can adjust the number of cards without - * recompilation - * .10 joh 071092 moved ivec allocation to module_types.h - * .11 joh 072792 added soft reboot int disable - * .12 mrk 090292 added DRVET - * .13 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals - * - * - * Routines: - * - * fpm_init Finds and initializes FP10M cards - * fpm_driver System interface to FP10M modules - * fpm_read Carrier control readback - * fpm_reboot clean up before soft reboots - * - * Daignostic Routines - * fpm_en Enables/disables interrupts (diagnostic enable) - * fpm_mode Sets interrupt reporting mode (logs mode - * changes to console) - * fpm_cdis Disables carrier from console - * fpm_fail Sets carrier failure mode - * fpm_srd Reads current carrier status - * fpm_write Command line interface to fpm_driver - * - * Routines return: - * - * -1 Nonexistent card - * -2 Interrupt connection error - * -3 no memory - * -4 VME short IO bus nonexistent - * 0-2 Successfull completion, or # cards found - * - */ - -static char *sccsId = "@(#)drvFpm.c 1.12\t8/4/93"; - -#include "vxWorks.h" -#include "vme.h" -#include /* in h/68k if this is compiling for a 68xxx */ -#include "module_types.h" -#include -#include - -static long report(); -static long init(); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvFpm={ - 2, - report, - init}; - -static long report() -{ - fpm_io_report(); -} - -static long init() -{ - fpm_init(0); - return(0); -} - -/* general constants */ -#define FPM_INTLEV 5 /* interrupt level */ - -/* control register bit definitions */ -#define CR_CDIS 0x1 /* software carrier disable */ -#define CR_FS0 0x2 /* fail select 0 */ -#define CR_FS1 0x4 /* fail select 1 */ -#define CR_FS2 0x8 /* fail select 2 */ -#define CR_I0 0x10 /* interrupt level bit 0 */ -#define CR_I1 0x20 /* interrupt level bit 1 */ -#define CR_I2 0x40 /* interrupt level bit 2 */ -#define CR_IEN 0x80 /* interrupt enable */ - -/* control register mask definitions */ -#define CR_IM 0x70 /* interrupt level mask */ - -/* status register bit definitions */ -#define SR_S0 0x1 /* error sequencer state bit 0 */ -#define SR_S1 0x2 /* error sequencer state bit 1 */ -#define SR_S2 0x3 /* error sequencer state bit 2 */ - -/* status register mask definitions */ -#define SR_EM 0x7 /* error state mask */ - -/* operating modes */ -#define FPM_NMSG 0 /* no messages to console */ -#define FPM_TMSG 1 /* terse messages to console */ -#define FPM_FMSG 2 /* full messages to console */ - -/* register address map for FP10M */ -struct fp10m - { - unsigned short cr; /* control register */ - unsigned short sr; /* status register */ - unsigned short ivec; /* interrupt vector */ - char end_pad[0xff-0x6]; /* pad to 256 byte boundary */ - }; - -/* control structure */ -struct fpm_rec - { - struct fp10m *fmptr; /* pointer to device registers */ - short type; /* device type */ - short num; /* board number */ - short vector; /* interrupt vector */ - short mode; /* operating mode */ - unsigned int int_num; /* interrupt number */ - }; - -static struct fpm_rec *fpm; /* fast protect control structure */ - -static int fpm_num; /* # cards found - 1 */ - -static void fpm_reboot(); - -/* - * fpm_int - * - * interrupt service routine - * - */ -fpm_int(ptr) - register struct fpm_rec *ptr; -{ - register struct fp10m *regptr; - - regptr = ptr->fmptr; - switch (ptr->mode) - { - case FPM_TMSG: - logMsg("fast protect master interrupt!\n"); - break; - case FPM_FMSG: - logMsg("fast protect master interrupt!\n"); - logMsg("cr = %x sr = %x\n",regptr->cr,regptr->sr & 0x7); - break; - } - ptr->int_num++; -} -/* - * fpm_init - * - * initialization for fp10m fast protect master modules - * - */ -fpm_init(addr) - unsigned int addr; -{ - int i; - short junk; - short intvec = AT8FPM_IVEC_BASE; - struct fp10m *ptr; - int status; - - fpm = (struct fpm_rec *) calloc( - bo_num_cards[AT8_FP10M_BO], - sizeof(*fpm)); - if(!fpm){ - return -3; - } - - if(!addr){ - addr = bo_addrs[AT8_FP10M_BO]; - } - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - addr, - &ptr); - if(status<0){ - logMsg("VME shrt IO addr err in the master fast protect driver\n"); - return -4; - } - - status = rebootHookAdd(fpm_reboot); - if(status<0){ - logMsg("%s: reboot hook add failed\n", __FILE__); - } - - for (i = 0; (i < bo_num_cards[AT8_FP10M_BO]) && (vxMemProbe(ptr,READ,2,&junk) == OK); - i++,ptr++) - { - /* - register initialization - */ - ptr->cr = 0x00; /* disable interface */ - fpm[i].fmptr = ptr; /* hardware location */ - fpm[i].vector = intvec++; /* interrupt vector */ - ptr->ivec = fpm[i].vector; /* load vector */ - fpm[i].mode = FPM_NMSG; /* set default mode (no messages) */ - fpm[i].int_num = 0; /* initialize interrupt number */ - fpm[i].type = 2; /* board type */ - fpm[i].num = i; /* board number */ - /* - set up interrupt handler - */ - ptr->cr |= FPM_INTLEV<<4; /* set up board for level 5 interrupt */ - if (intConnect(INUM_TO_IVEC(fpm[i].vector),fpm_int,&fpm[i]) != OK) - return -2; /* abort if can't connect */ - sysIntEnable(FPM_INTLEV); - } - fpm_num = i - 1; /* record last card # */ - return i; /* return # cards found */ -} - - -/* - * - * fpm_reboot() - * - * turn off interrupts to avoid ctrl X reboot problems - */ -LOCAL -void fpm_reboot() -{ - int i; - - if(!fpm){ - return; - } - - for (i = 0; i < bo_num_cards[AT8_FP10M_BO]; i++){ - - if(!fpm[i].fmptr){ - continue; - } - - fpm[i].fmptr->cr &= ~CR_IEN; - } -} - -/* - * fpm_en - * - * interrupt enable/disable - * (toggles the int enable state - joh) - * - */ -fpm_en(card) - short card; -{ - if (card < 0 || (card > fpm_num)) - return -1; - fpm[card].fmptr->cr ^= CR_IEN; - if (fpm[card].fmptr->cr & CR_IEN) - printf("fast protect master interrupts enabled\n"); - else - printf("fast protect master interrupts disabled\n"); - return 0; -} -/* - * fpm_mode - * - * set interrupt reporting mode - * - */ -fpm_mode(card,mode) - short card, mode; -{ - if (card < 0 || (card > fpm_num)) - return -1; - fpm[card].mode = mode; - return 0; -} -/* - * fpm_cdis - * - * carrier disable (1), enable (0) - * - */ -fpm_cdis(card,disable) - short card, disable; -{ - unsigned short temp; - - if (card < 0 || (card > fpm_num)) - return -1; - temp = fpm[card].fmptr->cr; - temp &= 0xfe; - temp |= (disable & 0x01); - fpm[card].fmptr->cr = temp; - return 0; -} -/* - * fpm_fail - * - * set failure mode - * - */ -fpm_fail(card,mode) - short card, mode; -{ - unsigned short temp; - - if (card < 0 || (card > fpm_num)) - return -1; - temp = fpm[card].fmptr->cr; - temp &= 0xf1; - temp |= (mode & 0x7)<<1; - fpm[card].fmptr->cr = temp; - return 0; -} -/* - * fpm_srd - * - * read status bits - * - */ -fpm_srd(card) - short card; -{ - if (card < 0 || ( card > fpm_num)) - return -1; - return fpm[card].fmptr->sr & 0x7; -} -/* - * fpm_driver - * - * epics interface to fast protect master - * - */ -fpm_driver(card,mask,prval) -register unsigned short card; -unsigned int mask; -register unsigned int prval; -{ - register unsigned int temp; - - if (card > fpm_num) - return -1; - temp = fpm[card].fmptr->cr; - fpm[card].fmptr->cr = (temp & (~mask | 0xf0)) | ((prval & mask) & 0xf); - return 0; -} -/* - * fpm_write - * - * command line interface to fpm_driver - * - */ -fpm_write(card,val) - short card; - unsigned int val; -{ - return fpm_driver(card,0xffffffff,val); -} -/* - * fpm_read - * - * read the current control register contents (readback) - * - */ -fpm_read(card,mask,pval) -register unsigned short card; -unsigned int mask; -register unsigned int *pval; -{ - if (card > fpm_num) - return -1; - *pval = fpm[card].fmptr->cr & 0x000f; - return 0; -} - - - -/* - * fpm_io_report() - * - */ -fpm_io_report(level) -int level; -{ - int i; - - for(i=0; i<=fpm_num; i++){ - printf("BO: AT8-FP-M: card %d\n", i); - } -} diff --git a/src/drv/drvGpib.c b/src/drv/drvGpib.c deleted file mode 100644 index db4bd7328..000000000 --- a/src/drv/drvGpib.c +++ /dev/null @@ -1,2593 +0,0 @@ -/* drvGpib.c */ -/* share/src/drv/drvGpib.c %W% %G% */ - -/****************************************************************************** - * - * TODO: - * - Autodetect the need to use a bounce buffer (saves time on boards that have - * "malloc"-able A24 space. - * - * - Launch campaign against the use of National Instruments hardware. - * - ****************************************************************************** - * - * Author: John Winans - * Date: 09-10-91 - * GPIB driver for the NI-1014 and NI-1014D VME cards. - * - * 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 09-13-91 jrw Written on Friday the 13th :-( - * Much of the code in physIo() was stolen from - * a gpib driver that came from Los Alamos. It - * referenced little more than National - * Instruments and Bob Daly (from ANL) in its - * credits. - * .02 12-03-91 jrw changed the setup of the ibLink and niLink structs - * .03 01-21-92 jrw moved task parameters into task_params.h - * .04 01-31-92 jrw added ibSrqLock code - * .05 02-26-92 jrw changed pnode references in the link task's - * busy-list checking, was an endless loop - * .06 04-10-92 jrw moved the device configs into module_types.h - * .07 08-02-92 mrk Added call to taskwdInsert - * - ****************************************************************************** - * - * Notes: - * If 1014D cards are used, make sure that the W7 switch is set to LMR. - * The internals of the 1014D are such that the DMAC can NEVER be hard-reset - * unless the SYSRESET* vme line is asserted. The LMR mode allows the - * initGpib() function to reset the DMAC properly. - * - * - * $Log$ - * Revision 1.27 1994/12/14 22:29:14 winans - * Removed DMAC command chaining structure(s) from the ibLink - * structure so they can be malloc'd seperately. This keeps - * the usage of A24 space restricted to ONLY those structures - * that have to be there. - * - * Revision 1.26 1994/12/12 16:03:00 winans - * Rewrote the init code so that it always returns a zero (don't kill the - * startup.cmd file.) It is possible that this could cause some confusion - * to the database, should it decide to then use a link that did not init - * properly. - * - * Revision 1.25 1994/10/28 19:55:30 winans - * Added VME bus violation prevention code/bug fix from LANL. - * - * Revision 1.24 1994/10/04 18:42:46 winans - * Added an extensive debugging facility. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "drvGpib.h" - -#define STATIC /* static */ - -long reportGpib(void); -/*STATIC*/ long initGpib(void); -STATIC int niIrq(); -STATIC int niIrqError(int link); -STATIC int niTmoHandler(); -STATIC int srqIntEnable(); -STATIC int srqIntDisable(); - -STATIC int qGpibReq(); -STATIC int registerSrqCallback(); -STATIC int writeIb(); -STATIC int readIb(); -STATIC int writeIbCmd(); -STATIC int ioctlIb(); - int srqPollInhibit(); - -STATIC int ibLinkInit(); -STATIC int ibLinkStart(); -STATIC int ibLinkTask(); -struct bbIbLink *findBBLink(); - -int ibDebug = 0; /* Turns on debug messages from this driver */ -int bbibDebug = 0; /* Turns on ONLY bitbus related messages */ -int ibSrqDebug = 0; /* Turns on ONLY srq related debug messages */ -int niIrqOneShot = 0; /* Used for a one shot peek at the DMAC */ -int ibSrqLock = 0; /* set to 1 to stop ALL srq checking & polling */ - -#define STD_ADDRESS_MODE D_SUP|D_S24 /* mode to use when DMAC accesses RAM */ - -/* - * The bounce buffer is where the DMA IO operation(s) take place. If it - * is not large enough, it will be reallocated at that time. However, - * It should be made large enough such this need not happen. - */ -#define DEFAULT_BOUNCE_BUFFER_SIZE 10*1024 - -STATIC int defaultTimeout; /* in 60ths, for GPIB timeouts */ - -static char init_called = 0; /* To insure that init is done first */ -STATIC char *short_base; /* Base of short address space */ -#ifdef USE_OLD_XLATION -STATIC char *ram_base; /* Base of the ram on the CPU board */ -#endif - -STATIC int timeoutSquelch = 0; /* Used to quiet timeout msgs during polling */ - -/* DMA timing bus error problem debugging in niPhysIo */ -int ibDmaDebug = 0; /* Turns on DMA debug messages from this driver */ -int ibDmaTimingError = 0; /* count "bad memProbes"/call of niPhysIo */ -int ibDmaTimingErrorTotal = 0; /* count total "bad memProbes" in niPhysIo */ -int ibDmaMaxError = 0; /* max # bad calls per call of niPhysIo */ -STATIC char testWrite; /* test char to write to 1014 card */ - - -/****************************************************************************** - * - * GPIB driver block. - * - ******************************************************************************/ -struct drvGpibSet drvGpib={ - 9, - reportGpib, - initGpib, - qGpibReq, - registerSrqCallback, - writeIb, - readIb, - writeIbCmd, - ioctlIb, - srqPollInhibit -}; - -/****************************************************************************** - * - * Reference to the bitbus driver block. - * - ******************************************************************************/ -extern struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; - DRVSUPFUN qReq; -} drvBitBus; - -/****************************************************************************** - * - * This structure is used to build array-chained DMA operations. See the - * physIo() function and the National Instruments docs for more info. - * - ******************************************************************************/ -struct cc_ary -{ - void *cc_ccb; - short cc_ONE; - void *cc_n_1addr; - short cc_TWO; -}; - -typedef struct DmaStuffStruct -{ - struct cc_ary cc_array; - char cc_byte; -}DmaStuffStruct; -/****************************************************************************** - * - * This structure is used to hold the hardware-specific information for a - * single GPIB link. There is one for each link constructed in initGpib(). - * - ******************************************************************************/ -struct niLink { - struct ibLink ibLink; - - char tmoFlag; /* timeout has occurred */ - SEM_ID ioSem; /* DMA I/O operation complete or WD timeout */ - WDOG_ID watchDogId; /* watchdog for timeouts */ - struct ibregs *ibregs;/* pointer to board registers */ - - DmaStuffStruct *DmaStuff; - - char r_isr1; - char r_isr2; - int first_read; - - unsigned long cmdSpins; /* total taskDelays while in niGpibCmd() */ - unsigned long maxSpins; /* most taskDelays in one call to niGpibCmd() */ - - char *A24BounceBuffer; /* Where to DMA to */ - unsigned long A24BounceSize; -}; - -STATIC struct niLink *pNiLink[NIGPIB_NUM_LINKS]; /* NULL if link not present */ -STATIC int pollInhibit[NIGPIB_NUM_LINKS][IBAPERLINK]; - /* 0=pollable, 1=user inhibited, 2=no device found */ - -/****************************************************************************** - * - * This structure is used to hold the hardware-specific information for a - * single BitBus GPIB link. They are dynamically allocated (and an ibLinkTask - * started for it) when an IOCTL command requests it. - * - * The IOCTL requests to initiate a BBGPIB_IO link comes from the device support - * init code. When it finds a BBGPIB_IO link it issues an IOCTL for the link & - * bug-node specified in the record. The driver will then initialize the - * required data structures and start a link task for it. It is OK to request - * the initialization of the same link more than 1 time, the driver will ignore - * all but the first request. - * - ******************************************************************************/ -struct bbIbLink { - struct ibLink ibLink; /* associated ibLink structure */ - - SEM_ID syncSem; /* used for syncronous I/O calls */ - struct bbIbLink *next; /* Next BitBus link structure in list */ -}; - -STATIC struct bbIbLink *rootBBLink = NULL; /* Head of bitbus structures */ - -/****************************************************************************** - * - * This function prints a message indicating the status of each possible GPIB - * card found in the system. - * - ******************************************************************************/ -long -reportGpib(void) -{ - int i; - - if (init_called) - { - for (i=0; i< NIGPIB_NUM_LINKS; i++) - { - if (pNiLink[i]) - { - printf("Link %d (address 0x%08.8X) present and initialized.\n", i, pNiLink[i]->ibregs); - printf(" total niGpibCmd() taskDelay() calls = %lu\n", pNiLink[i]->cmdSpins); - printf(" worst case delay in niGpibCmd() = %lu\n", pNiLink[i]->maxSpins); - } - else - { - printf("Link %d not installed.\n", i); - } - } - printf("DMA timing: error = %d, total = %d, max = %d\n", - ibDmaTimingError, ibDmaTimingErrorTotal, ibDmaMaxError); - - } - else - { - printf("Gpib driver has not yet been initialized.\n"); - } - return(OK); -} - -STATIC void rebootFunc(void) -{ - int i; - char probeValue; - char msg[100]; - - for (i=0;iibLink, 0, msg, 1); - probeValue = 0; - vxMemProbe(&(pNiLink[i]->ibregs->ch1.ccr), WRITE, 1, (char *)&probeValue); - vxMemProbe(&(pNiLink[i]->ibregs->ch0.ccr), WRITE, 1, (char *)&probeValue); - taskDelay(1); /* Let it settle */ - - vxMemProbe(&(pNiLink[i]->ibregs->cfg2), WRITE, 1, (char *)&probeValue); - probeValue = D_LMR; - vxMemProbe(&(pNiLink[i]->ibregs->cfg2), WRITE, 1, (char *)&probeValue); - } - } - taskDelay(2); - return; -} -/****************************************************************************** - * - * Called by the iocInit processing. - * initGpib, probes the gpib card addresses and if one is present, it - * is initialized for use. It should only be called one time. - * - * The loops in this function are logically 1 large one. They were seperated - * so that the 1014D cards could be initialized properly. [Both ports must - * have some of their registers set at the same time and then not later - * altered... for example the LMR reset bit.] - * - ******************************************************************************/ -/* BUG -- this should be static */ -/*STATIC*/ long -initGpib(void) -{ - int i; - int j; - int probeValue; - struct ibregs *pibregs; - char s; - - if (init_called) - { - if (ibDebug) - logMsg("initGpib() driver already initialized!\n"); - return(OK); - } - defaultTimeout = sysClkRateGet(); - - /* figure out where the short address space is */ - sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO , 0, &short_base); - -#ifdef USE_OLD_XLATION - /* figure out where the CPU memory is (when viewed from the backplane) */ - sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &ram_base, &ram_base); - ram_base = (char *)((ram_base - (char *)&ram_base) & 0x00FFFFFF); -#endif - - if (ibDebug) - { - logMsg("Gpib NI1014 driver initializing\n"); - logMsg("short_base 0x%08.8X\n", short_base); -#ifdef USE_OLD_XLATION - logMsg("ram_base 0x%08.8X\n", ram_base); -#endif - logMsg("NIGPIB_SHORT_OFF 0x%08.8X\n", NIGPIB_SHORT_OFF); - logMsg("NIGPIB_NUM_LINKS 0x%08.8X\n", NIGPIB_NUM_LINKS); - } - - /* When probing, send out a reset signal to reset the DMAC and the TLC */ - probeValue = D_LMR | D_SFL; - - rebootHookAdd(rebootFunc); - - pibregs = (struct ibregs *)((unsigned int)short_base + NIGPIB_SHORT_OFF); - /* Gotta do all the probing first because the 1014D's LMRs are shared :-( */ - for (i=0; icfg2), WRITE, 1, (char *)&probeValue) < OK) - { /* no GPIB board present here */ - pNiLink[i] = (struct niLink *) NULL; - - if (ibDebug) - logMsg("Probing of address 0x%08.8X failed\n", pibregs); - - } - else - { /* GPIB board found... reserve space for structures & reset the thing */ - if (ibDebug) - logMsg("GPIB card found at address 0x%08.8X\n", pibregs); - - if ((pNiLink[i] = (struct niLink *)malloc(sizeof(struct niLink))) == NULL) - { /* This better never happen! */ - logMsg("initGpib(): Can't malloc memory for NI-link data structures!\n"); - return(ERROR); - } - - /* Allocate and init the sems and linked lists */ - pNiLink[i]->ibLink.linkType = GPIB_IO; /* spec'd in link.h */ - pNiLink[i]->ibLink.linkId = i; /* link number */ - pNiLink[i]->ibLink.bug = -1; /* this is not a bug link */ - - - /* Clear out the bouncer */ - pNiLink[i]->A24BounceBuffer = NULL; - pNiLink[i]->A24BounceSize = 0; - - taskDelay(1); /* Wait at least 10 msec before continuing */ - - ibLinkInit(&(pNiLink[i]->ibLink)); /* allocate the sems etc... */ - - pibregs->cfg2 = D_SFL; /* can't set all bits at same time */ - pibregs->cfg2 = D_SFL | D_SC; /* put board in operating mode */ - - pNiLink[i]->ibregs = pibregs; - pNiLink[i]->ioSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pNiLink[i]->watchDogId = wdCreate(); - pNiLink[i]->tmoFlag = 0; - pNiLink[i]->cmdSpins = 0; - pNiLink[i]->maxSpins = 0; - - if ((pNiLink[i]->DmaStuff = (DmaStuffStruct *)devLibA24Malloc(sizeof(DmaStuffStruct))) == NULL) - { /* This better never happen! */ - logMsg("initGpib(): Can't malloc A24 memory for DMAC control structures!\n"); - return(ERROR); - } - pNiLink[i]->DmaStuff->cc_array.cc_ccb = 0; /* DMAC chaining structure */ - pNiLink[i]->DmaStuff->cc_array.cc_ONE = 1; - pNiLink[i]->DmaStuff->cc_array.cc_n_1addr = 0; - pNiLink[i]->DmaStuff->cc_array.cc_TWO = 2; - - pNiLink[i]->first_read = 1; /* used in physIo() */ - } - pibregs++; /* ready for next board window */ - } - - /* Bring up the cards (has to be done last because the 1014D has to have */ - /* both ports reset before either one is initialized. */ - - for (i=0; iibregs->cptr; - pNiLink[i]->r_isr1 = pNiLink[i]->ibregs->isr1; - pNiLink[i]->r_isr2 = pNiLink[i]->ibregs->isr2; - - /* disable all interrupts from the 7210 */ - pNiLink[i]->ibregs->imr1 = 0; /* DMA and ERROR IRQ mask reg */ - pNiLink[i]->ibregs->imr2 = 0; /* SRQ IRQ mask reg */ - pNiLink[i]->ibregs->spmr = 0; /* serial poll mode register */ - - pNiLink[i]->ibregs->adr = 0; /* device address = 0 */ - pNiLink[i]->ibregs->adr = HR_ARS|HR_DT|HR_DL; /* no secondary addressing */ - pNiLink[i]->ibregs->admr = HR_TRM1|HR_TRM0|HR_ADM0; - pNiLink[i]->ibregs->eosr = 0; /* end of string value */ - pNiLink[i]->ibregs->auxmr = ICR|8; /* internal counter = 8 */ - pNiLink[i]->ibregs->auxmr = PPR|HR_PPU; /* paralell poll unconfigure */ - pNiLink[i]->ibregs->auxmr = AUXRA|0; - pNiLink[i]->ibregs->auxmr = AUXRB|0; - pNiLink[i]->ibregs->auxmr = AUXRE|0; - - /* DMAC setup */ - - pNiLink[i]->ibregs->cfg1 = (NIGPIB_IRQ_LEVEL << 5)|D_BRG3|D_DBM; - pNiLink[i]->ibregs->ch1.niv = NIGPIB_IVEC_BASE + i*2; /* normal IRQ vector */ - pNiLink[i]->ibregs->ch1.eiv = NIGPIB_IVEC_BASE+1+i*2; /* error IRQ vector */ - pNiLink[i]->ibregs->ch0.niv = NIGPIB_IVEC_BASE + i*2; /* normal IRQ vector */ - pNiLink[i]->ibregs->ch0.eiv = NIGPIB_IVEC_BASE+1+i*2; /* error IRQ vector */ - pNiLink[i]->ibregs->ch1.ccr = D_EINT; /* stop operation, allow ints */ - pNiLink[i]->ibregs->ch0.ccr = 0; /* stop all channel operation */ - pNiLink[i]->ibregs->ch0.cpr = 3; /* highest priority */ - pNiLink[i]->ibregs->ch1.cpr = 3; /* highest priority */ - pNiLink[i]->ibregs->ch1.dcr = D_CS|D_IACK|D_IPCL; - pNiLink[i]->ibregs->ch0.dcr = D_CS|D_IACK|D_IPCL; - pNiLink[i]->ibregs->ch1.scr = 0; /* no counting during DMA */ - pNiLink[i]->ibregs->ch0.scr = D_MCU; /* count up during DMA cycles */ - pNiLink[i]->ibregs->ch0.mfc = STD_ADDRESS_MODE; - pNiLink[i]->ibregs->ch1.mfc = STD_ADDRESS_MODE; - pNiLink[i]->ibregs->ch1.bfc = STD_ADDRESS_MODE; - - - /* attach the interrupt handler routines */ - intConnect(INUM_TO_IVEC(NIGPIB_IVEC_BASE+i*2), niIrq, i); - intConnect(INUM_TO_IVEC(NIGPIB_IVEC_BASE+(i*2)+1), niIrqError, i); - } - } - - /* should have interrups running before I do any I/O */ - sysIntEnable(NIGPIB_IRQ_LEVEL); - - /* Fire up the TLCs and nudge all the addresses on the GPIB bus */ - /* by doing a serial poll on all of them. If someone did a */ - /* srqPollInhibit() on a specific link, then skip it and continue. */ - - for (i=0; iibregs->auxmr = AUX_PON; /* release pon state */ - - if (ibLinkStart(&(pNiLink[i]->ibLink)) == ERROR) /* start up the link */ - pNiLink[i] = NULL; /* kill the link to prevent flood of problems */ - } - } - - init_called = 1; /* let reportGpib() know init occurred */ - return(OK); -} - -STATIC int -niDumpDmac(int link) -{ - logMsg("ch0: ccr=%02.2X csr=%02.2X cer=%02.2X mtc=%04.4X mar=%08.8X btc=%04.4X bar=%08.8X\n", - pNiLink[link]->ibregs->ch0.ccr & 0xff, - pNiLink[link]->ibregs->ch0.csr & 0xff, - pNiLink[link]->ibregs->ch0.cer & 0xff, - pNiLink[link]->ibregs->ch0.mtc & 0xffff, - niRdLong(&(pNiLink[link]->ibregs->ch0.mar)), - pNiLink[link]->ibregs->ch0.btc & 0xffff, - niRdLong(&(pNiLink[link]->ibregs->ch0.bar))); - - logMsg("ch1: ccr=%02.2X csr=%02.2X cer=%02.2X mtc=%04.4X mar=%08.8X btc=%04.4X bar=%08.8X\n", - pNiLink[link]->ibregs->ch1.ccr & 0xff, - pNiLink[link]->ibregs->ch1.csr & 0xff, - pNiLink[link]->ibregs->ch1.cer & 0xff, - pNiLink[link]->ibregs->ch1.mtc & 0xffff, - niRdLong(&(pNiLink[link]->ibregs->ch1.mar)), - pNiLink[link]->ibregs->ch1.btc & 0xffff, - niRdLong(&(pNiLink[link]->ibregs->ch1.bar))); - - return(OK); -} -/****************************************************************************** - * - * Interrupt handler for all normal DMAC interrupts. - * - * This is invoked at the termination of a DMA operation or if the TLC - * requests an un-masked interrupt (typically SRQ from the GPIB bus.) - * - * Keep in mind that channel0's interrupts are related to the SRQs and that - * the ints from channel1 are related to the DMA operations completing. - * - * Note: - * The isr2 status should always be read first since reading isr1 can reset - * some of the isr2 status. - * - ******************************************************************************/ -STATIC int -niIrq(link) -int link; -{ - if (ibDebug) - logMsg("GPIB interrupt from link %d\n", link); - - if (NIGPIB_IRQ_LEVEL == 4) /* gotta ack ourselves on HK boards */ - sysBusIntAck(NIGPIB_IRQ_LEVEL); - - if (niIrqOneShot) - { - niDumpDmac(link); - niIrqOneShot--; - } - - /* Check the DMA error status bits first */ - if (pNiLink[link]->ibregs->ch0.csr & D_ERR || pNiLink[link]->ibregs->ch1.csr & D_ERR) - { - logMsg("GPIB error during DMA from link %d\n", link); - - /* read the status regs to clear any int status from the TLC */ - pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2; - pNiLink[link]->r_isr1 |= pNiLink[link]->ibregs->isr1; - - niDumpDmac(link); - - logMsg("r_isr1=%02.2X r_isr2=%02.2X\n", - pNiLink[link]->r_isr1 & 0xff, - pNiLink[link]->r_isr2 & 0xff); - - pNiLink[link]->ibregs->ch0.csr = ~D_PCLT; /* Keep srq int status */ - pNiLink[link]->ibregs->ch1.csr = D_CLEAR; - pNiLink[link]->ibregs->imr1 = 0; - pNiLink[link]->ibregs->imr2 = 0; - - /* No semaphores are given in here because we don't know why we got */ - /* here. It is best to let I/O time out if any was going on. */ - return(ERROR); - } - - /* channel 0 PCL status is the SRQ line for the link */ - - if ((pNiLink[link]->ibregs->ch0.csr) & D_PCLT) - { - pNiLink[link]->ibregs->ch0.csr = D_PCLT; /* Reset srq status */ - pNiLink[link]->ibLink.srqIntFlag = 1; - - if (ibDebug|| ibSrqDebug) - logMsg("GPIB SRQ interrupt on link %d\n", link); - - semGive(pNiLink[link]->ibLink.linkEventSem); - - return(0); - } - -/* BUG -- perhaps set a flag so the WD system knows I proceeded here? */ - - /* if there was a watch-dog timer tie, let the timeout win. */ - if (pNiLink[link]->tmoFlag == FALSE) - { - if (pNiLink[link]->ibregs->ch1.csr & D_PCLT) - { - if (ibDebug) - logMsg("GPIB DMA completion interrupt from link %d\n", link); - /* read the status regs to clear any int status from the TLC */ - /* changed these to = from |= because they never got cleared! */ - pNiLink[link]->r_isr2 = pNiLink[link]->ibregs->isr2; - pNiLink[link]->r_isr1 = pNiLink[link]->ibregs->isr1; - - if (pNiLink[link]->ibregs->ch1.csr & D_COC) - { - /* this should not be set because we ALWAYS ask for 1 too */ - /* many bytes to be transfered. See 1014 docs on ints */ - logMsg("GPIB COC bit set after DMA on channel 1 link %d\n", link); - } - /* DMA complete via sync detect */ - pNiLink[link]->ibregs->imr1 = 0; - pNiLink[link]->ibregs->imr2 = 0; - pNiLink[link]->ibregs->ch1.csr = D_CLEAR; - /* Leave Channel 0's ints alone since it did not generate the interrupt */ - semGive(pNiLink[link]->ioSem); - - return(0); - } - } - else - { - /* The DMAC should get reset by the watch-dog handling code if I get here */ - if (ibDebug) - logMsg("GPIB DMA completion interrupt but wd expired already on link %d\n", link); - } - return(0); -} - -/****************************************************************************** - * - * An interrupt handler that catches the DMAC error interrupts. These should - * never occur. - * - ******************************************************************************/ -STATIC int -niIrqError(int link) -{ - logMsg("GPIB error interrupt generated on link %d\n", link); - - niDumpDmac(link); - - pNiLink[link]->ibregs->ch0.ccr = D_SAB; - pNiLink[link]->ibregs->ch1.ccr = D_SAB; - return(0); -} - -/****************************************************************************** - * - * niGpibCmd() - * - * This function is used to output a command string to the GPIB bus. - * - * The controller is placed in the active state prior to the outputting of - * the first command. - * - * Before calling niGpibCmd() the first time, an niGpibIoctl(IBIFC) call must - * be made to init the bus and enable the interface card. - * - ******************************************************************************/ -#define TOOLONG 100 /* how many times to try to send the same byte */ -#define IDELAY 1000 /* how long to busy wait while sending a byte */ - -STATIC int -niGpibCmd(link, buffer, length) -int link; -char *buffer; -int length; -{ - int iDelay; /* how long to spin before doing a taskWait */ - int tooLong; /* how long should I tolerate waiting */ - int lenCtr; - unsigned spins; /* how many taskDelay() calls made in this function */ - - lenCtr = length; - spins = 0; - - if (ibDebug) - logMsg("niGpibCmd(%d, 0x%08.8X, %d): command string >%s<\n", link, buffer, length, buffer); - - tooLong = TOOLONG; /* limit to wait for ctrlr's command buffer */ - pNiLink[link]->ibregs->auxmr = AUX_TCA; /* take control of the bus */ - - while (lenCtr) - { - pNiLink[link]->r_isr2 &= ~HR_CO; - iDelay = IDELAY; /* wait till the ctlr is ready */ - while (iDelay && (((pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2) & HR_CO) == 0)) - iDelay--; - - if (iDelay) - { - pNiLink[link]->ibregs->cdor = *buffer++; /* output a byte */ - lenCtr--; - tooLong = TOOLONG; /* reset the limit again */ - } - else - { - if (!(tooLong--)) - { - /* errMsg() */ - logMsg("niGpibCmd(%d, 0x%08.8X, %d): Timeout while writing command >%s<\n", link, buffer, length, buffer); - pNiLink[link]->ibregs->auxmr = AUX_GTS; - if (spins > pNiLink[link]->maxSpins) - pNiLink[link]->maxSpins = spins; - return(ERROR); - } - spins++; - pNiLink[link]->cmdSpins++; - taskDelay(1); /* ctlr is taking too long */ - } - } - tooLong = TOOLONG; - while(tooLong--) - { - pNiLink[link]->r_isr2 &= ~HR_CO; - iDelay = IDELAY; /* wait till the ctlr is ready */ - while (iDelay && (((pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2) & HR_CO) == 0)) - iDelay--; - - if(iDelay) - { - pNiLink[link]->ibregs->auxmr = AUX_GTS; - if (spins > pNiLink[link]->maxSpins) - pNiLink[link]->maxSpins = spins; - return(length); - } - else - { - spins++; - pNiLink[link]->cmdSpins++; - taskDelay(1); - } - } - /* errMsg() */ - logMsg("niGpibCmd(%d, 0x%08.8X, %d): Timeout after writing command >%s<\n", link, buffer, length, buffer); - pNiLink[link]->ibregs->auxmr = AUX_GTS; - if (spins > pNiLink[link]->maxSpins) - pNiLink[link]->maxSpins = spins; - return(ERROR); -} - -/****************************************************************************** - * - * Read a buffer via Ni-based link. - * - ******************************************************************************/ -STATIC int -niGpibRead(link, buffer, length, time) -int link; -char *buffer; -int length; -int time; -{ - int err; - - if(ibDebug) - logMsg("niGpibRead(%d, 0x%08.8X, %d, %d)\n",link, buffer, length, time); - - if (niCheckLink(link) == ERROR) - { - /* bad link number */ - return(ERROR); - } - - err = niPhysIo(READ, link, buffer, length, time); - pNiLink[link]->r_isr1 &= ~HR_END; - - return(err ? err : length - niGpibResid(link)); -} - - -/****************************************************************************** - * - * Write a buffer out an Ni-based link. - * - ******************************************************************************/ -STATIC int -niGpibWrite(link, buffer, length, time) -int link; -char *buffer; -int length; -int time; -{ - int err; - - if(ibDebug) - logMsg("niGpibWrite(%d, 0x%08.8X, %d, %d)\n",link, buffer, length, time); - - if (niCheckLink(link) == ERROR) - { - /* bad link number */ - return(ERROR); - } - - err = niPhysIo(WRITE, link, buffer, length, time); - - return(err ? err : length - niGpibResid(link)); -} - -/****************************************************************************** - * - * This function is used to figure out the difference in the transfer-length - * requested in a read or write request, and that actually transfered. - * - ******************************************************************************/ -STATIC int -niGpibResid(link) -int link; -{ - register int cnt; - - cnt = pNiLink[link]->ibregs->ch0.mtc; - if (pNiLink[link]->ibregs->ch1.mtc == 2 || cnt) /* add one if carry-cycle */ - cnt++; /* never started */ - - return(cnt); -} - - -/****************************************************************************** - * - * This function is used to validate all non-BitBus -> GPIB link numbers that - * are passed in from user requests. - * - ******************************************************************************/ -STATIC int -niCheckLink(link) -int link; -{ - if (link<0 || link >= NIGPIB_NUM_LINKS) - { - /* link number out of range */ - return(ERROR); - } - if (pNiLink[link] == NULL) - { - /* link number has no card installed */ - return(ERROR); - } - return(OK); -} - -/****************************************************************************** - * - * This function provides access to the GPIB protocol operations on the NI - * interface board. - * - ******************************************************************************/ -STATIC int -niGpibIoctl(link, cmd, v, p) -int link; -int cmd; -int v; -caddr_t p; -{ - int stat = OK; - - if(ibDebug) - logMsg("niGpibIoctl(%d, %d, %d, %08.8X)\n",link, cmd, v, p); - - if (cmd != IBGENLINK && niCheckLink(link) == ERROR) - { - /* bad link number */ - return(ERROR); - } - - switch (cmd) { - case IBTMO: /* set the timeout value for the next transaction */ - /* pNiLink[link]->tmoLimit = v; */ - logMsg("Old NI driver call entered IBTMO ignored\n"); - break; - case IBIFC: /* fire out an Interface Clear pulse */ - pNiLink[link]->ibregs->auxmr = AUX_SIFC; /* assert the line */ - taskDelay(10); /* wait a little while */ - pNiLink[link]->ibregs->auxmr = AUX_CIFC; /* clear the line */ - taskDelay(10); /* wait a little while */ - break; - case IBREN: /* turn on or off the REN line */ - pNiLink[link]->ibregs->auxmr = (v ? AUX_SREN : AUX_CREN); - break; - case IBGTS: /* go to standby (ATN off etc...) */ - pNiLink[link]->ibregs->auxmr = AUX_GTS; - break; - case IBGTA: /* go to active (ATN on etc...) (IBIFC must also be called */ - pNiLink[link]->ibregs->auxmr = AUX_TCA; - break; - case IBNILNK: /* returns the max number of NI links possible */ - stat = NIGPIB_NUM_LINKS; - break; - case IBGENLINK: /* request the creation of a link */ - break; /* this is automatic for NI based links */ - case IBGETLINK: /* return pointer to ibLink structure */ - *(struct ibLink **)p = &(pNiLink[link]->ibLink); - break; - default: - return(ERROR); - } - return(stat); -} - -/****************************************************************************** - * - * This routine does DMA based I/O with the GPIB bus. It sets up the NI board's - * DMA registers, initiates the transfer and waits for it to complete. It uses - * a watchdog timer in case the transfer dies. It returns OK, or ERROR - * depending on if the transfer succeeds or not. - * - ******************************************************************************/ - -STATIC int -niPhysIo(dir, link, buffer, length, time) -int dir; /* direction (READ or WRITE) */ -int link; /* link number to do the I/O with */ -char *buffer; /* data to transfer */ -int length; /* number of bytes to transfer */ -int time; /* time to wait on the DMA operation */ -{ - int status; - short cnt; - register struct ibregs *b; - char w_imr2; - int temp_addr; - int tmoTmp; - - if (pNiLink[link]->A24BounceBuffer == NULL) - { - if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(DEFAULT_BOUNCE_BUFFER_SIZE)) == NULL) - { - errMessage(S_IB_A24 ,"niPhysIo ran out of A24 memory!"); - return(ERROR); - } - pNiLink[link]->A24BounceSize = DEFAULT_BOUNCE_BUFFER_SIZE; - if(ibDebug > 5) - logMsg("Got a bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer); - } - - if (pNiLink[link]->A24BounceSize < length) - { /* Reallocate a larger bounce buffer */ - - devLibA24Free(pNiLink[link]->A24BounceBuffer); /* Loose the old one */ - - if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(length)) == NULL) - { - errMessage(S_IB_A24 ,"niPhysIo ran out of A24 memory!"); - pNiLink[link]->A24BounceSize = 0; - pNiLink[link]->A24BounceBuffer = NULL; - return(ERROR); - } - pNiLink[link]->A24BounceSize = length; - if(ibDebug > 5) - logMsg("Got a new bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer); - } - - b = pNiLink[link]->ibregs; - cnt = length; - - b->auxmr = AUX_GTS; /* go to standby mode */ - b->ch1.ccr = D_SAB; /* halt channel activity */ - b->ch0.ccr = D_SAB; /* halt channel activity */ - - b->ch1.csr = D_CLEAR; - b->ch0.csr = D_CLEAR & ~D_PCLT; - - b->imr2 = 0; /* set these bits last */ - status = OK; - - if (dir == READ) - { - if (pNiLink[link]->first_read == 0) - b->auxmr = AUX_FH; /* finish handshake */ - else - pNiLink[link]->first_read = 0; - - b->auxmr = AUXRA | HR_HLDE; /* hold off on end */ - - if (cnt != 1) - pNiLink[link]->DmaStuff->cc_byte = AUXRA | HR_HLDA; /* (cc) holdoff on all */ - else - pNiLink[link]->DmaStuff->cc_byte = b->auxmr = AUXRA | HR_HLDA; /* last byte, do now */ - b->ch0.ocr = D_DTM | D_XRQ; - /* make sure I only alter the 1014D port-specific fields here! */ - b->cfg1 = D_ECC | D_IN | (NIGPIB_IRQ_LEVEL << 5) | D_BRG3 | D_DBM; - b->ch1.ocr = D_DTM | D_ACH | D_XRQ; - b->ch1.ocr = D_DTM | D_ACH | D_XRQ; - - /* enable interrupts and dma */ - b->imr1 = HR_ENDIE; - w_imr2 = HR_DMAI; - } - else /* (dir == READ) */ - { - /* We will be writing, copy data into the bounce buffer */ - memcpy(pNiLink[link]->A24BounceBuffer, buffer, length); - - if (cnt != 1) - pNiLink[link]->DmaStuff->cc_byte = AUX_SEOI; /* send EOI with last byte */ - else - b->auxmr = AUX_SEOI; /* last byte, do it now */ - - b->ch0.ocr = D_MTD | D_XRQ; - /* make sure I only alter the 1014D port-specific fields here! */ - b->cfg1 = D_ECC | D_OUT | (NIGPIB_IRQ_LEVEL << 5) | D_BRG3 | D_DBM; - b->ch1.ocr = D_MTD | D_ACH | D_XRQ; - - /* enable interrupts and dma */ - b->imr1 = 0; - w_imr2 = HR_DMAO; - } /* dir == READ) */ - - /* setup channel 1 (carry cycle) */ - - if(ibDebug > 5) - logMsg("PhysIO: readying to xlate cc pointers at %8.8X and %8.8X\n", &(pNiLink[link]->DmaStuff->cc_byte), &pNiLink[link]->A24BounceBuffer[cnt - 1]); - -#ifdef USE_OLD_XLATION - pNiLink[link]->DmaStuff->cc_array.cc_ccb = &(pNiLink[link]->DmaStuff->cc_byte) + (long) ram_base; - pNiLink[link]->DmaStuff->cc_array.cc_n_1addr = &(pNiLink[link]->A24BounceBuffer[cnt - 1]) + (long)ram_base; -#else - - if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->DmaStuff->cc_byte), &(pNiLink[link]->DmaStuff->cc_array.cc_ccb)) == ERROR) - return(ERROR); - - if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->A24BounceBuffer[cnt - 1]), &(pNiLink[link]->DmaStuff->cc_array.cc_n_1addr)) == ERROR) - return(ERROR); - -#endif - if(ibDebug > 5) - logMsg("PhysIO: &cc_byte=%8.8X, &pNiLink[link]->A24BounceBuffer[cnt-1]=%8.8X, ", pNiLink[link]->DmaStuff->cc_array.cc_ccb, pNiLink[link]->DmaStuff->cc_array.cc_n_1addr); - - cnt--; -#ifdef USE_OLD_XLATION - temp_addr = (long) (&(pNiLink[link]->DmaStuff->cc_array)) + (long)ram_base; -#else - if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->DmaStuff->cc_array), &temp_addr) == ERROR) - return(ERROR); -#endif - if(ibDebug > 5) - logMsg("&cc_array=%8.8X, ", temp_addr); - - niWrLong(&b->ch1.bar, temp_addr); - b->ch1.btc = 2; - - /* setup channel 0 (main transfer) */ - b->ch0.mtc = cnt ? cnt : 1; -#ifdef USE_OLD_XLATION - temp_addr = (long) (pNiLink[link]->A24BounceBuffer) + (long) ram_base; -#else - if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, pNiLink[link]->A24BounceBuffer, &temp_addr) == ERROR) - return(ERROR); -#endif - if(ibDebug > 5) - logMsg("pNiLink[link]->A24BounceBuffer=%8.8X\n", temp_addr); - - niWrLong(&b->ch0.mar, temp_addr); - - /* setup GPIB response timeout handler */ - if (time == 0) - time = defaultTimeout; /* 0 = take the default */ - pNiLink[link]->tmoFlag = FALSE; /* assume no timeout */ - wdStart(pNiLink[link]->watchDogId, time, niTmoHandler, link); - - /* start dma (ch1 first) */ - if (cnt) - b->ch1.ccr = D_EINT | D_SRT; /* enable interrupts */ - else - b->ch1.ccr = D_EINT; - -#ifdef INCLUDE_LANL_DMA_TIMING_CHECKER - /************************************************************************* - * DMAC BUS ERROR CATCH - * The following lines are included because of a possible VME protocol - * violation by the NI1014D gpib board. Occasionally, the board is not - * ready to respond to the "b->ch0.ccr = D_SRT;" line (write to interrupt - * mask register 2) and generates a bus error. Since this problem occurred - * initially with the 68020, faster CPUs may run into this problem more - * often. Thus, while the following set of debugging lines actually provide - * enough of a delay that the problem disappears for the 68020, they are left - * in for possible debugging for the faster CPUs. - **************************************************************************/ - ibDmaTimingError = 0; - while (vxMemProbe(&b->ch0.ccr, WRITE, 1, &testWrite) < 0) - ibDmaTimingError++; - ibDmaTimingErrorTotal += ibDmaTimingError; - if (ibDmaTimingError > ibDmaMaxError) - ibDmaMaxError = ibDmaTimingError; - if (ibDmaDebug) - logMsg("DMA timing: error = %d, total = %d, max = %d\n", - ibDmaTimingError, ibDmaTimingErrorTotal, ibDmaMaxError); - /***************************************************************************/ -#endif - - b->ch0.ccr = D_SRT; - -#ifdef INCLUDE_LANL_DMA_TIMING_CHECKER - /**************************** - * DMAC BUS ERROR CATCH - *****************************/ - ibDmaTimingError = 0; - while (vxMemProbe(&b->imr2, WRITE, 1, &testWrite) < 0) - ibDmaTimingError++; - ibDmaTimingErrorTotal += ibDmaTimingError; - if (ibDmaTimingError > ibDmaMaxError) - ibDmaMaxError = ibDmaTimingError; - if (ibDmaDebug) - logMsg("DMA timing: error = %d, total = %d, max = %d\n", - ibDmaTimingError, ibDmaTimingErrorTotal, ibDmaMaxError); - /***************************************************************************/ -#endif - - b->imr2 = w_imr2; /* this must be done last */ - - /* check for error in DMAC initialization */ - if ((b->ch0.csr & D_ERR) || (b->ch1.csr & D_ERR)) - { - /* errMsg() */ - logMsg("DMAC error initialization on link %d.\n", link); - return (ERROR); - } - if (cnt) - { - if (ibDebug == 1) - logMsg("Link %d waiting for DMA int or WD timeout.\n", link); - semTake(pNiLink[link]->ioSem, WAIT_FOREVER); /* timeout or DMA finish */ - } - else - if (b->ch0.mtc) - { - if (ibDebug == 1) - logMsg("wd cnt =0 wait\n"); - tmoTmp = 0; - while (b->ch0.mtc) - { - taskDelay(1); - if (++tmoTmp == time) - { - pNiLink[link]->tmoFlag = TRUE; - break; - } - } - } - if (pNiLink[link]->tmoFlag == TRUE) - { - status = ERROR; - /* reset */ - pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2; - pNiLink[link]->r_isr1 |= pNiLink[link]->ibregs->isr1; - pNiLink[link]->ibregs->imr1 = 0; - pNiLink[link]->ibregs->imr2 = 0; - pNiLink[link]->ibregs->ch1.csr = D_CLEAR; - /* errMsg() */ - if (!timeoutSquelch) - logMsg("TIMEOUT GPIB DEVICE on link %d\n", link); - } - else - { - wdCancel(pNiLink[link]->watchDogId); - status = OK; - if (b->ch0.csr & D_ERR) - { - logMsg("DMAC error on link %d, channel 0 = %x\n", link, b->ch0.cer); - status = ERROR; - } - if (b->ch1.csr & D_ERR) - { - logMsg("DMAC error on link %d, channel 1 = %x\n", link, b->ch1.cer); - status = ERROR; - } - } - /* - * DMA transfer complete. Reset as per instructions in GPIB - * 'Programming Considerations' 5-14 - */ - -/* BUG -- Should halt and spin a while before aborting (NI recommendation) */ - b->ch0.ccr = D_SAB; /* halt channel activity */ - b->ch0.csr = D_CLEAR & ~D_PCLT; - b->ch1.ccr = D_SAB; - b->ch1.csr = D_CLEAR; - - b->imr2 = 0; - /* make sure I only alter the 1014D port-specific fields here! */ - b->cfg1 = (NIGPIB_IRQ_LEVEL << 5) | D_BRG3 | D_DBM; - - if (dir == READ) - { /* Copy data from the bounce buffer to the user's buffer */ - memcpy(buffer, pNiLink[link]->A24BounceBuffer, length); - } - - return (status); -} - -/****************************************************************************** - * - * This function is called by the watch-dog timer if it expires while waiting - * for a GPIB transaction to complete. - * - ******************************************************************************/ -STATIC int -niTmoHandler(link) -int link; -{ - pNiLink[link]->tmoFlag = TRUE; /* indicate that timeout occurred */ - semGive(pNiLink[link]->ioSem); /* wake up the phys I/O routine */ - return(0); -} - -/****************************************************************************** - * - * Mark a given device as non-pollable. - * - ******************************************************************************/ -STATIC int -niSrqPollInhibit(link, gpibAddr) -int link; -int gpibAddr; -{ - if (niCheckLink(link) == ERROR) - { - logMsg("drvGpib: niSrqPollInhibit(%d, %d): invalid link number specified\n", link, gpibAddr); - return(ERROR); - } - pollInhibit[link][gpibAddr] = 1; /* mark it as inhibited */ - return(OK); -} - -/****************************************************************************** - * - * Sometimes we have to make sure that regs on the GPIB board are accessed as - * 16-bit values. This function writes out a 32-bit value in 2 16-bit pieces. - * - ******************************************************************************/ -STATIC int -niWrLong(loc, val) -short *loc; -int val; -{ - register short *ptr = loc; - - *ptr = val >> 16; - *(ptr + 1) = val & 0xffff; -} - int -niRdLong(loc) -unsigned short *loc; -{ - register unsigned short *ptr = loc; - int val; - - val = (unsigned long) (*ptr << 16) + (unsigned long) (*(ptr+1) & 0xffff); - return(val); -} - -/****************************************************************************** - * - * This function is used to enable the generation of VME interupts upon the - * detection of an SRQ status on the GPIB bus. - * - ******************************************************************************/ -STATIC int -niSrqIntEnable(link) -int link; -{ - int lockKey; - - if(ibDebug || ibSrqDebug) - logMsg("niSrqIntEnable(%d): ch0.csr = 0x%02.2X, gsr=0x%02.2X\n", link, pNiLink[link]->ibregs->ch0.csr, pNiLink[link]->ibregs->gsr); - - lockKey = intLock(); /* lock out ints because something likes to glitch */ - - if (!((pNiLink[link]->ibregs->ch0.csr) & D_NSRQ)) - { /* SRQ line is CURRENTLY active, just give the event sem and return */ - pNiLink[link]->ibLink.srqIntFlag = 1; - semGive(pNiLink[link]->ibLink.linkEventSem); - - if(ibDebug || ibSrqDebug) - logMsg("niSrqIntEnable(%d): found SRQ active, setting srqIntFlag\n", link); - - /* Clear the PCLT status if is already set to prevent unneeded int later */ - pNiLink[link]->ibregs->ch0.csr = D_PCLT; - } - else - pNiLink[link]->ibregs->ch0.ccr = D_EINT; /* Allow SRQ ints */ - - intUnlock(lockKey); - return(OK); -} - - -/****************************************************************************** - * - * This function is used to disable the generation of VME interupts associated - * with the detection of an SRQ status on the GPIB bus. - * - ******************************************************************************/ -STATIC int -niSrqIntDisable(link) -int link; -{ - int lockKey; - - if(ibDebug || ibSrqDebug) - logMsg("niSrqIntDisable(%d): ch0.csr = 0x%02.2X, gsr=0x%02.2X\n", link, pNiLink[link]->ibregs->ch0.csr, pNiLink[link]->ibregs->gsr); - - lockKey = intLock(); /* lock out ints because something likes to glitch */ - pNiLink[link]->ibregs->ch0.ccr = 0; /* Don't allow SRQ ints */ - intUnlock(lockKey); - - return(OK); -} - -/****************************************************************************** - * - * The following section of GPIB driver is written such that it can operate - * in a device independant fashon. It does this by simply not making - * references to any architecture-specific data areas. - * - * When the architecture-specific information is needed, processing - * is sent to the architecture-specific routines. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Routine used to initialize the values of the fields in an ibLink structure. - * - ******************************************************************************/ -STATIC int -ibLinkInit(plink) -struct ibLink *plink; -{ - int j; - - if(ibDebug || bbibDebug) - logMsg("ibLinkInit(%08.8X): entered, type %d, link %d, bug %d\n", plink, plink->linkType, plink->linkId, plink->bug); - -#ifdef GPIB_SUPER_DEBUG - plink->History.Sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - plink->History.Next = 0; - plink->History.Num = 0; -#endif - - plink->srqIntFlag = 0; /* no srq ints set now */ - plink->linkEventSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - ellInit(&(plink->hiPriList)); /* init the list as empty */ - plink->hiPriSem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - - ellInit(&(plink->loPriList)); /* init the list as empty */ - plink->loPriSem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - - plink->srqRing = rngCreate(SRQRINGSIZE * sizeof(struct srqStatus)); - - for (j=0; jsrqHandler[j] = NULL; /* no handler is registered */ - plink->deviceStatus[j] = IDLE; /* assume device is IDLE */ - } - return(OK); -} - -/****************************************************************************** - * - * Init and start an ibLinkTask - * - ******************************************************************************/ -STATIC int -ibLinkStart(plink) -struct ibLink *plink; -{ - int j; - int taskId; - char tName[20]; - - if (ibDebug || bbibDebug) - logMsg("ibLinkStart(%08.8X): entered for linkType %d, link %d\n", plink, plink->linkType, plink->linkId); - - ioctlIb(plink->linkType, plink->linkId, plink->bug, IBIFC, -1, NULL);/* fire out an interface clear */ - ioctlIb(plink->linkType, plink->linkId, plink->bug, IBREN, 1, NULL);/* turn on the REN line */ - -/* BUG -- why not just forget this & only poll registered devices? */ -/* BUG -- the pollinhibit array stuff has to be fixed! */ - - - if ((plink->linkType == GPIB_IO) && (ibSrqLock == 0)) - { - /* poll all available adresses to see if will respond */ - speIb(plink); - for (j=1; j<31; j++) /* poll 1 thru 31 (no 0 or 32) */ - { - if (pollInhibit[plink->linkId][j] != 1);/* if user did not block it out */ - { - if (pollIb(plink, j, 0, POLLTIME) == ERROR) - pollInhibit[plink->linkId][j] = 2; /* address is not pollable */ - } - } - - spdIb(plink); - } - - if (plink->linkType == GPIB_IO) - sprintf(tName, "ib-%2.2d", plink->linkId); - else if (plink->linkType == BBGPIB_IO) - sprintf(tName, "bbib-%2.2d.%2.2d", plink->linkId, plink->bug); - else - strcpy(tName, GPIBLINK_NAME); - - /* Start a task to manage the link */ - if ((taskId = taskSpawn(tName, GPIBLINK_PRI, GPIBLINK_OPT, GPIBLINK_STACK, ibLinkTask, plink)) == ERROR) - { - logMsg("ibLinkStart(): failed to start link task for link %d\n", plink->linkId); - return(ERROR); - } - taskwdInsert(taskId,NULL,NULL); - taskDelay(10); /* give it a chance to start running */ - return(OK); -} - -/***************************************************************************** - * - * At the time this function is started as its own task, the linked list - * structures will have been created and initialized. - * - * This function is spawned as a task for each GPIB bus present in the - * system. That is one for each Ni card port, and one for each Bit Bus - * bug that contains a GPIB port on it. - * - * All global data areas referenced by this task are limited to the non-port - * specific items (no niLink[] references allowed.) so that the same task - * can operate all forms of GPIB busses. - * - *****************************************************************************/ -STATIC int -ibLinkTask(plink) -struct ibLink *plink; /* a reference to the link structures covered */ -{ - struct dpvtGpibHead *pnode; - struct srqStatus ringData; - int pollAddress; - int pollActive; - int working; - - - if (ibDebug) - logMsg("ibLinkTask started for link type %d, link %d\n", plink->linkType, plink->linkId); - - /* send out a UNL and UNT to test-drive the link */ - if (writeIbCmd(plink, "?_", 2) == ERROR) - { - logMsg("ibLinkTask(%08.08X): init failed for link type %d, link %d\n", plink->linkType, plink, plink->linkId); - return(ERROR); - } - - working = 1; /* check queues for work the first time */ - while (1) - { - if (!working) - { - if (ibSrqLock == 0) - { - /* Enable SRQ interrupts while waiting for an event */ - srqIntEnable(plink->linkType, plink->linkId, plink->bug); - } - - /* wait for an event associated with this GPIB link */ - semTake(plink->linkEventSem, WAIT_FOREVER); - - /* Disable SRQ interrupts while processing an event */ - srqIntDisable(plink->linkType, plink->linkId, plink->bug); - - if (ibDebug) - { - logMsg("ibLinkTask(%d, %d): got an event\n", plink->linkType, plink->linkId); - } - } - working = 0; /* Assume will do nothing */ - - /* Check if an SRQ interrupt has occurred recently */ - - /* - * If link is currently doing DMA, this function/task will be performing - * the work. Therfore, it will not be here trying to poll devices, so - * is no need to worry about locking the GPIB link here. - */ - - if ((plink->srqIntFlag) && (ibSrqLock == 0)) - { - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): srqIntFlag set.\n", plink->linkType, plink->linkId); - - plink->srqIntFlag = 0; - pollActive = 0; - - pollAddress = 1; /* skip 0 and 31, poll 1-30 */ - while (pollAddress < 31) - { - if (!(pollInhibit[plink->linkId][pollAddress])) /* zero if allowed */ - { - if (!pollActive) - { /* set the serial poll enable mode if not done so yet */ - pollActive = 1; - speIb(plink); - } - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): poling device %d\n", plink->linkType, plink->linkId, pollAddress); - if ((ringData.status = pollIb(plink, pollAddress, 1, POLLTIME)) & 0x40) - { - ringData.device = pollAddress; - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): device %d srq status = 0x%02.2X\n", plink->linkType, plink->linkId, pollAddress, ringData.status); - if (plink->srqHandler[ringData.device] != NULL) - { /* there is a registered SRQ handler for this device */ - rngBufPut(plink->srqRing, (char *) &ringData, sizeof(ringData)); - } - else - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): got an srq from device %d... ignored\n", plink->linkType, plink->linkId, pollAddress); - } - } - pollAddress++; - } - if (pollActive) - { /* unset serial poll mode if it got set above */ - pollActive = 0; - spdIb(plink); - } - else - { - logMsg("ibLinkTask(%d, %d): got an SRQ, but have no pollable devices!\n", plink->linkType, plink->linkId); - } - /* - * If the SRQ link is again/still active, it will be seen on the next - * call to srqIntEnable above. - */ - } - - /* - * See if there is a need to process an SRQ solicited transaction. - * Do all of them before going on to other transactions. - */ - while (rngBufGet(plink->srqRing, (char *)&ringData, sizeof(ringData))) - { - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): dispatching srq handler for device %d\n", plink->linkType, plink->linkId, ringData.device); - plink->deviceStatus[ringData.device] = (*(plink->srqHandler)[ringData.device])(plink->srqParm[ringData.device], ringData.status); - working=1; - } - - /* - * see if the Hi priority queue has anything in it - */ - semTake(plink->hiPriSem, WAIT_FOREVER); - - if ((pnode = (struct dpvtGpibHead *)ellFirst(&(plink->hiPriList))) != NULL) - { - while (plink->deviceStatus[pnode->device] == BUSY) - if ((pnode = (struct dpvtGpibHead *)ellNext(pnode)) == NULL) - break; - } - if (pnode != NULL) - ellDelete(&(plink->hiPriList), pnode); - - semGive(plink->hiPriSem); - - if (pnode != NULL) - { - if (ibDebug) - logMsg("ibLinkTask(%d, %d): got Hi Pri xact, pnode= 0x%08.8X\n", plink->linkType, plink->linkId, pnode); - - plink->deviceStatus[pnode->device] = (*(pnode->workStart))(pnode); - working=1; - } - else - { - semTake(plink->loPriSem, WAIT_FOREVER); - if ((pnode = (struct dpvtGpibHead *)ellFirst(&(plink->loPriList))) != NULL) - { - while (plink->deviceStatus[pnode->device] == BUSY) - if ((pnode = (struct dpvtGpibHead *)ellNext(pnode)) == NULL) - break; - } - if (pnode != NULL) - ellDelete(&(plink->loPriList), pnode); - - semGive(plink->loPriSem); - - if (pnode != NULL) - { - if(ibDebug) - logMsg("ibLinkTask(%d, %d): got Lo Pri xact, pnode= 0x%08.8X\n", plink->linkType, plink->linkId, pnode); - plink->deviceStatus[pnode->device] = (*(pnode->workStart))(pnode); - working=1; - } - } - } -} - -/****************************************************************************** - * - * The following are functions used to take care of serial polling. They - * are called from the ibLinkTask. - * - ******************************************************************************/ -/****************************************************************************** - * - * Pollib sends out an SRQ poll and returns the poll response. - * If there is an error during polling (timeout), the value -1 is returned. - * - ******************************************************************************/ -STATIC int -pollIb(plink, gpibAddr, verbose, time) -struct ibLink *plink; -int gpibAddr; -int verbose; /* set to 1 if should log any errors */ -int time; -{ - char pollCmd[4]; - int status; - int tsSave; - unsigned char pollResult[3]; - - - if(verbose && (ibDebug || ibSrqDebug)) - logMsg("pollIb(0x%08.8X, %d, %d, %d)\n", plink, gpibAddr, verbose, time); - - tsSave = timeoutSquelch; - timeoutSquelch = !verbose; /* keep the I/O routines quiet if desired */ - - /* raw-read back the response from the instrument */ - if (readIb(plink, gpibAddr, pollResult, sizeof(pollResult), time) == ERROR) - { - if(verbose) - logMsg("pollIb(%d, %d): data read error\n", plink->linkId, gpibAddr); - status = ERROR; - } - else - { - status = pollResult[0]; - if (ibDebug || ibSrqDebug) - { - logMsg("pollIb(%d, %d): poll status = 0x%02.2X\n", plink->linkId, gpibAddr, status); - } - } - - timeoutSquelch = tsSave; /* return I/O error logging to normal */ - return(status); -} - -/****************************************************************************** - * - * speIb is used to send out a Serial Poll Enable command on the GPIB - * bus. - * - ******************************************************************************/ -STATIC int -speIb(plink) -struct ibLink *plink; -{ - /* write out the Serial Poll Enable command */ - writeIbCmd(plink, "\030", 1); - - return(0); -} - - -/****************************************************************************** - * - * spdIb is used to send out a Serial Poll Disable command on the GPIB - * bus. - * - ******************************************************************************/ -STATIC int -spdIb(plink) -struct ibLink *plink; -{ - /* write out the Serial Poll Disable command */ - writeIbCmd(plink, "\031", 1); - - return(0); -} - -/****************************************************************************** - * - * Functions used to enable and disable SRQ interrupts. These only make - * sense on a Ni based link, so they are ignored in the BitBus case. - * (In the BitBus, SRQ status is passed back via query. So there is no - * asynchronous interupt associated with it.) - * - * The interrupts referred to here are the actual VME bus interrupts that are - * generated by the GPIB interface when it sees the SRQ line go high. - * - ******************************************************************************/ -STATIC int -srqIntEnable(int linkType, int link, int bug) -{ - if (linkType == GPIB_IO) - return(niSrqIntEnable(link)); - - if (linkType == BBGPIB_IO) - return(OK); /* Bit Bus does not use interrupts for SRQ handeling */ - - return(ERROR); /* Invalid link type specified on the call */ -} - -STATIC int -srqIntDisable(int linkType, int link, int bug) -{ - if (linkType == GPIB_IO) - return(niSrqIntDisable(link)); - - if (linkType == BBGPIB_IO) - return(0); /* Bit Bus does not use interrupts for SRQ handeling */ - - return(ERROR); /* Invlaid link type specified on the call */ -} - -/****************************************************************************** - * - * Check the link number and bug number (if is a BBGPIB_IO link) to see if they - * are valid. - * - ******************************************************************************/ -STATIC int -checkLink(linkType, link, bug) -int linkType; -int link; -int bug; -{ - if (linkType == GPIB_IO) - return(niCheckLink(link)); - - if (linkType == BBGPIB_IO) - return(bbCheckLink(link, bug)); - - return(ERROR); /* bad link type specefied */ -} - -/**************************************************************************** - * - * The following routines are the user-callable entry points to the GPIB - * driver. - * - ****************************************************************************/ -/****************************************************************************** - * - * A device support module may call this function to request that the GPIB - * driver NEVER poll a given device. - * - * Devices are polled when an SRQ event is present on the GPIB link. Some - * devices are too dumb to deal with being polled. - * - * This is NOT a static function, because it must be invoked from the startup - * script BEFORE iocInit is called. - * - * BUG -- - * This could change if we decide to poll them during the second call to init() - * when epics 3.3 is available. - * - ******************************************************************************/ -/* STATIC */ int -srqPollInhibit(linkType, link, bug, gpibAddr) -int linkType; /* link type (defined in link.h) */ -int link; /* the link number the handler is related to */ -int bug; /* the bug node address if on a bitbus link */ -int gpibAddr; /* the device address the handler is for */ -{ - if (ibDebug || ibSrqDebug) - logMsg("srqPollInhibit(%d, %d, %d, %d): called\n", linkType, link, bug, gpibAddr); - - if (linkType == GPIB_IO) - { - return(niSrqPollInhibit(link, gpibAddr)); - } - - if (linkType == BBGPIB_IO) - { - return(bbSrqPollInhibit(link, bug, gpibAddr)); - } - - logMsg("drvGpib: srqPollInhibit(%d, %d, %d, %d): invalid link type specified\n", linkType, link, bug, gpibAddr); - return(ERROR); -} - -/****************************************************************************** - * - * This allows a device support module to register an SRQ event handler. - * - * It is used to specify a function to call when an SRQ event is detected - * on the specified link and device. When the SRQ handler is called, it is - * passed the requested parm and the poll-status from the gpib device. - * - ******************************************************************************/ -STATIC int -registerSrqCallback(pibLink, device, handler, parm) -struct ibLink *pibLink; -int device; -int (*handler)(); /* handler function to invoke upon SRQ detection */ -caddr_t parm; /* so caller can have a parm passed back */ -{ - if(ibDebug || ibSrqDebug) - logMsg("registerSrqCallback(%08.8X, %d, 0x%08.8X, %08.8X)\n", pibLink, device, handler, parm); - - pibLink->srqHandler[device] = handler; - pibLink->srqParm[device] = parm; - return(OK); -} - -/****************************************************************************** - * - * Allow users to operate the internal functions of the driver. - * - * This can be fatal to the driver... make sure you know what you are doing! - * - ******************************************************************************/ -STATIC int -ioctlIb(linkType, link, bug, cmd, v, p) -int linkType; /* link type (defined in link.h) */ -int link; /* the link number to use */ -int bug; /* node number if is a bitbus -> gpib link */ -int cmd; -int v; -caddr_t p; -{ - int stat; - - if (linkType == GPIB_IO) - return(niGpibIoctl(link, cmd, v, p));/* link checked in niGpibIoctl */ - - if (linkType == BBGPIB_IO) - return(bbGpibIoctl(link, bug, cmd, v, p));/* link checked in bbGpibIoctl */ - - if (ibDebug || bbibDebug) - logMsg("ioctlIb(%d, %d, %d, %d, %08.8X, %08.8X): invalid link type\n", linkType, link, bug, cmd, v, p); - - return(ERROR); -} - -/****************************************************************************** - * - * This function allows a user program to queue a GPIB work request for - * future execution. It is the ONLY way a user function can initiate - * a GPIB message transaction. - * - * A work request represents a function that the ibLinkTask is to call (when - * ready) to allow the user program access to the readIb, writeIb, and - * writeIbCmd functions. The user programs should never call these functions - * at any other times. - * - * Returns OK, or ERROR. - * - ******************************************************************************/ -STATIC int -qGpibReq(pdpvt, prio) -struct dpvtGpibHead *pdpvt; /* pointer to the device private structure */ -int prio; -{ - - if (pdpvt->pibLink == NULL) - { - logMsg("qGpibReq(%08.8X, %d): dpvt->pibLink == NULL!\n", pdpvt, prio); - return(ERROR); - } - - switch (prio) { - case IB_Q_LOW: /* low priority transaction request */ - semTake(pdpvt->pibLink->loPriSem, WAIT_FOREVER); - ellAdd(&(pdpvt->pibLink->loPriList), pdpvt); - semGive(pdpvt->pibLink->loPriSem); - semGive(pdpvt->pibLink->linkEventSem); - break; - case IB_Q_HIGH: /* high priority transaction request */ - semTake(pdpvt->pibLink->hiPriSem, WAIT_FOREVER); - ellAdd(&(pdpvt->pibLink->hiPriList), pdpvt); - semGive(pdpvt->pibLink->hiPriSem); - semGive(pdpvt->pibLink->linkEventSem); - break; - default: /* invalid priority */ - logMsg("invalid priority requested in call to qgpibreq(%08.8X, %d)\n", pdpvt, prio); - return(ERROR); - } - if (ibDebug) - logMsg("qgpibreq(0x%08.8X, %d): transaction queued\n", pdpvt, prio); - return(OK); -} - -/****************************************************************************** - * - * The following functions are defined for use by device support modules. - * They may ONLY be called by the linkTask. - * - ******************************************************************************/ -/****************************************************************************** - * - * A device support callable entry point used to write data to GPIB devices. - * - * This function returns the number of bytes written out. - * - ******************************************************************************/ -STATIC int -writeIb(pibLink, gpibAddr, data, length, time) -struct ibLink *pibLink; -int gpibAddr; /* the device number to write the data to */ -char *data; /* the data buffer to write out */ -int length; /* number of bytes to write out from the data buffer */ -int time; -{ - char attnCmd[5]; - int stat; - - if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO))) - logMsg("writeIb(%08.8X, %d, 0x%08.8X, %d, %d)\n", pibLink, gpibAddr, data, length, time); - - if (pibLink->linkType == GPIB_IO) - { - attnCmd[0] = '?'; /* global unlisten */ - attnCmd[1] = '_'; /* global untalk */ - attnCmd[2] = gpibAddr+LADBASE; /* lad = gpibAddr */ - attnCmd[3] = 0+TADBASE; /* mta = 0 */ - attnCmd[4] = '\0'; /* in case debugging prints it */ - - if (writeIbCmd(pibLink, attnCmd, 4) != 4) - return(ERROR); - stat = niGpibWrite(pibLink->linkId, data, length, time); - - if (writeIbCmd(pibLink, attnCmd, 2) != 2) - return(ERROR); - } - else if (pibLink->linkType == BBGPIB_IO) - { - stat = bbGpibWrite(pibLink, gpibAddr, data, length, time); - } - else - { - return(ERROR); - } - return(stat); -} - -/****************************************************************************** - * - * A device support callable entry point used to read data from GPIB devices. - * - * This function returns the number of bytes read from the device, or ERROR - * if the read operation failed. - * - ******************************************************************************/ -STATIC int -readIb(pibLink, gpibAddr, data, length, time) -struct ibLink *pibLink; -int gpibAddr; /* the device number to read the data from */ -char *data; /* the buffer to place the data into */ -int length; /* max number of bytes to place into the buffer */ -int time; /* max time to allow for read operation */ -{ - char attnCmd[5]; - int stat; - - if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO))) - logMsg("readIb(%08.8X, %d, 0x%08.8X, %d)\n", pibLink, gpibAddr, data, length); - - if (pibLink->linkType == GPIB_IO) - { - attnCmd[0] = '_'; /* global untalk */ - attnCmd[1] = '?'; /* global unlisten */ - attnCmd[2] = gpibAddr+TADBASE; /* tad = gpibAddr */ - attnCmd[3] = 0+LADBASE; /* mta = 0 */ - attnCmd[4] = '\0'; - - if (writeIbCmd(pibLink, attnCmd, 4) != 4) - return(ERROR); - - stat = niGpibRead(pibLink->linkId, data, length, time); - - if (writeIbCmd(pibLink, attnCmd, 2) != 2) - return(ERROR); - } - else if (pibLink->linkType == BBGPIB_IO) - { - stat = bbGpibRead(pibLink, gpibAddr, data, length, time); - } - else - { /* incorrect link type specified! */ - return(ERROR); - } - return(stat); -} - -/****************************************************************************** - * - * A device support callable entry point that is used to write commands - * to GPIB devices. (this is the same as a regular write except that the - * ATN line is held high during the write. - * - * This function returns the number of bytes written out. - * - ******************************************************************************/ -STATIC int -writeIbCmd(pibLink, data, length) -struct ibLink *pibLink; -char *data; /* the data buffer to write out */ -int length; /* number of bytes to write out from the data buffer */ -{ - - if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO))) - logMsg("writeIbCmd(%08.8X, %08.8X, %d)\n", pibLink, data, length); - - if (pibLink->linkType == GPIB_IO) - { - /* raw-write the data */ - return(niGpibCmd(pibLink->linkId, data, length)); - } - if (pibLink->linkType == BBGPIB_IO) - { - /* raw-write the data */ - return(bbGpibCmd(pibLink, data, length)); - } - return(ERROR); -} - -/****************************************************************************** - * - * These are the BitBus architecture specific functions. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Read a GPIB message via the BitBus driver. - * - ******************************************************************************/ -STATIC int -bbGpibRead(pibLink, device, buffer, length, time) -struct ibLink *pibLink; -int device; -char *buffer; -int length; -int time; -{ - /* The bbIbLink structure starts with the ibLink, so this is OK */ - struct bbIbLink *pbbIbLink = (struct bbIbLink *) pibLink; - - struct dpvtBitBusHead bbdpvt; - int bytesRead; - char msg[150]; - - sprintf(msg, "bbGpibRead(%08.8X, %d, %08.8X, %d, %d): entered", pibLink, device, buffer, length, time); - GpibDebug(pibLink, device, msg, 1); - - bytesRead = 0; - - bbdpvt.finishProc = NULL; /* no callback, synchronous I/O mode */ - bbdpvt.psyncSem = &(pbbIbLink->syncSem); - bbdpvt.link = pibLink->linkId; - - bbdpvt.rxMsg.data = (unsigned char *) buffer; - - bbdpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbdpvt.txMsg.node = pibLink->bug; - bbdpvt.txMsg.tasks = BB_GPIB_TASK; - bbdpvt.txMsg.cmd = BB_IBCMD_READ_XACT | device; - bbdpvt.txMsg.length = 7; /* send header only */ - - bbdpvt.rxMsg.cmd = 0; /* init for the while loop */ - bbdpvt.status = BB_OK; - - while (length && (bbdpvt.status == BB_OK) && (!(bbdpvt.rxMsg.cmd & (BB_IBSTAT_EOI|BB_IBSTAT_TMO)))) - { - bbdpvt.rxMaxLen = length > BB_MAX_DAT_LEN ? BB_MAX_DAT_LEN+7 : length+7; - bbdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&bbdpvt, BB_Q_LOW) != OK) - { - bbdpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbdpvt.psyncSem), WAIT_FOREVER); /* wait for response */ - - sprintf(msg, "bbGpibRead(): %02.2X >%.13s< driver status 0x%02.2X", bbdpvt.rxMsg.cmd, bbdpvt.rxMsg.data, bbdpvt.status); - GpibDebug(pibLink, device, msg, 1); - - bbdpvt.txMsg.cmd = BB_IBCMD_READ; /* in case have more reading to do */ - bbdpvt.rxMsg.data += bbdpvt.rxMsg.length - 7; - length -= bbdpvt.rxMsg.length - 7; - bytesRead += bbdpvt.rxMsg.length - 7; - } - if ((bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO) || (bbdpvt.status != BB_OK)) - return(ERROR); - else - return(bytesRead); -} - -/****************************************************************************** - * - * Write a GPIB message by way of the bitbus driver. - * - ******************************************************************************/ -STATIC int -bbGpibWrite(pibLink, device, buffer, length, time) -struct ibLink *pibLink; -int device; -char *buffer; -int length; -int time; -{ - /* The bbIbLink structure starts with the ibLink, so this is OK */ - struct bbIbLink *pbbIbLink = (struct bbIbLink *) pibLink; - - struct dpvtBitBusHead bbdpvt; - unsigned char dbugBuf[BB_MAX_DAT_LEN + 1]; - unsigned char more2GoCommand; - unsigned char lastCommand; - int bytesSent; - char msg[150]; - - sprintf(msg, "bbGpibWrite(%08.8X, %d, %08.8X, %d, %d): entered", pibLink, device, buffer, length, time); - GpibDebug(pibLink, device, msg, 1); - - bytesSent = length; /* we either get an error or send them all */ - - bbdpvt.finishProc = NULL; /* no callback, synchronous I/O mode */ - bbdpvt.psyncSem = &(pbbIbLink->syncSem); - bbdpvt.link = pibLink->linkId; - bbdpvt.rxMaxLen = 7; /* only get the header back */ - - bbdpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbdpvt.txMsg.node = pibLink->bug; - bbdpvt.txMsg.tasks = BB_GPIB_TASK; - - bbdpvt.txMsg.data = (unsigned char *) buffer; - - bbdpvt.rxMsg.cmd = 0; /* Init for error checking */ - bbdpvt.status = BB_OK; - - /* if more than BB_MAX_DAT_LEN bytes */ - more2GoCommand = BB_IBCMD_ADDR_WRITE | device; - - /* if less than BB_MAX_DAT_LEN+1 bytes */ - lastCommand = BB_IBCMD_WRITE_XACT | device; - - while (length && (bbdpvt.status == BB_OK) && (!(bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - { - if (length > BB_MAX_DAT_LEN) - { - bbdpvt.txMsg.length = BB_MAX_DAT_LEN+7; - bbdpvt.txMsg.cmd = more2GoCommand; /* Write to device */ - length -= BB_MAX_DAT_LEN; /* Ready for next chunk */ - - more2GoCommand = BB_IBCMD_WRITE; - lastCommand = BB_IBCMD_WRITE_EOI; - } - else - { - bbdpvt.txMsg.length = length+7; - bbdpvt.txMsg.cmd = lastCommand; - length = 0; /* This is the last one */ - } -#if 0 - if (ibDebug || bbibDebug) - { - bcopy(bbdpvt.txMsg.data, dbugBuf, bbdpvt.txMsg.length-7); - dbugBuf[bbdpvt.txMsg.length-7] = '\0'; - logMsg("bbGpibWrite():sending %02.2X >%s<", bbdpvt.txMsg.cmd, dbugBuf); - } -#else - bcopy(bbdpvt.txMsg.data, dbugBuf, bbdpvt.txMsg.length-7); - dbugBuf[bbdpvt.txMsg.length-7] = '\0'; - sprintf(msg, "bbGpibWrite():sending %02.2X >%s<", bbdpvt.txMsg.cmd, dbugBuf); - GpibDebug(pibLink, device, msg, 1); -#endif - - bbdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&bbdpvt, BB_Q_HIGH) != OK) - { - bbdpvt.status = BB_NONODE; - return(ERROR); - } - - semTake(*(bbdpvt.psyncSem), WAIT_FOREVER); /* wait for response */ - - sprintf(msg, " RAC status = 0x%02.2X driver status = 0x%02.2X", bbdpvt.rxMsg.cmd, bbdpvt.status); - GpibDebug(pibLink, device, msg, 1); - - bbdpvt.txMsg.data += BB_MAX_DAT_LEN; /* in case there is more */ - } - - /* All done, check to see if we died due to an error */ - - if ((bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO) || (bbdpvt.status != BB_OK)) - return(ERROR); - else - return(bytesSent); -} - -/******************************************************************************/ -STATIC int -bbGpibCmd(pibLink, buffer, length) -struct ibLink *pibLink; -char *buffer; -int length; -{ - /* The bbIbLink structure starts with the ibLink, so this is OK */ - struct bbIbLink *pbbIbLink = (struct bbIbLink *) pibLink; - - struct dpvtBitBusHead bbdpvt; - int bytesSent; - char msg[150]; - - sprintf(msg, "bbGpibCmd(%08.8X, %08.8X, %d): entered", pibLink, buffer, length); - GpibDebug(pibLink, 0, msg, 1); - - bytesSent = length; - - bbdpvt.finishProc = NULL; /* no callback, synchronous I/O mode */ - bbdpvt.psyncSem = &(pbbIbLink->syncSem); - bbdpvt.link = pibLink->linkId; - bbdpvt.rxMaxLen = 7; /* only get the header back */ - - bbdpvt.status = BB_OK; /* prime these for the while loop */ - bbdpvt.rxMsg.cmd = 0; - - bbdpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbdpvt.txMsg.node = pibLink->bug; - bbdpvt.txMsg.tasks = BB_GPIB_TASK; - bbdpvt.txMsg.cmd = BB_IBCMD_WRITE_CMD; - bbdpvt.txMsg.data = (unsigned char *) buffer; - - while ((length > BB_MAX_DAT_LEN) && (bbdpvt.status == BB_OK) && (!(bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - { - bbdpvt.txMsg.length = BB_MAX_DAT_LEN+7; /* send a chunk */ - bbdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&bbdpvt, BB_Q_HIGH) != OK) - { - bbdpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbdpvt.psyncSem), WAIT_FOREVER); /* wait for response */ - - length -= BB_MAX_DAT_LEN; /* ready for next chunk */ - bbdpvt.txMsg.data += BB_MAX_DAT_LEN; - } - if ((bbdpvt.status == BB_OK) && (!(bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - { - if (semTake(*(bbdpvt.psyncSem), 0) == OK) - { - sprintf(msg, "bbGpibCmd() able to take the dang sync sem before queueing!"); - GpibDebug(pibLink, 0, msg, 1); - } - bbdpvt.txMsg.length = length+7; /* send the last chunk */ - bbdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&bbdpvt, BB_Q_HIGH) != OK) - { - bbdpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbdpvt.psyncSem), WAIT_FOREVER); /* wait for response */ -/* BUG -- check bitbus response */ - } - return(bytesSent); -} - -/******************************************************************************/ -STATIC int -bbCheckLink(link, bug) -int link; -int bug; -{ - if (findBBLink(link, bug) != NULL) - return(OK); - else - return(ERROR); -} - -/******************************************************************************/ -STATIC int -bbSrqPollInhibit(link, bug, gpibAddr) -int link; -int bug; -int gpibAddr; -{ - logMsg("bbSrqPollInhibit called for link %d, bug %d, device %d\n", link, bug, gpibAddr); - return(ERROR); -} - -/****************************************************************************** - * - * Initialize all required structures and start an ibLinkTask() for use with - * a BBGPIB_IO based link. - * - ******************************************************************************/ -STATIC int -bbGenLink(link, bug) -int link; -int bug; -{ - struct bbIbLink *bbIbLink; - - if (ibDebug || bbibDebug) - logMsg("bbGenLink(%d, %d): entered\n", link, bug); - - /* First check to see if there is already a link set up */ - bbIbLink = findBBLink(link, bug); - - if (bbIbLink != NULL) - { /* Already have initialized the link for this guy... */ - if (bbibDebug || ibDebug) - logMsg("bbGenLink(%d, %d): link already initialized\n", link, bug); - - return(OK); - } - - /* This link is not started yet, initialize all the required stuff */ - - if ((bbIbLink = (struct bbIbLink *) malloc(sizeof(struct bbIbLink))) == NULL) - { - logMsg("bbGenLink(%d, %d): can't malloc memory for link structure\n", link, bug); - return(ERROR); - } - - bbIbLink->ibLink.linkType = BBGPIB_IO; - bbIbLink->ibLink.linkId = link; - bbIbLink->ibLink.bug = bug; - - bbIbLink->syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - ibLinkInit(&(bbIbLink->ibLink)); - - /* BUG -- should have a lock in the rootBBLink list! */ - bbIbLink->next = rootBBLink; - rootBBLink = bbIbLink; /* link the new one into the list */ - - return(ibLinkStart(&(bbIbLink->ibLink))); -/* BUG -- I should free up the stuff if the init failed for some reason */ -} - -/****************************************************************************** - * - * IOCTL control function for BBGPIB_IO based links. - * - ******************************************************************************/ -STATIC int -bbGpibIoctl(int link, int bug, int cmd, int v, caddr_t p) -{ - int stat = ERROR; - struct bbIbLink *pbbIbLink; - struct dpvtBitBusHead bbDpvt; - unsigned char buf[BB_MAX_DAT_LEN]; - - if (ibDebug || bbibDebug) - logMsg("bbGpibIoctl(%d, %d, %d, %08.8X, %08.8X): called\n", link, bug, cmd, v, p); - -/* No checkLink() is done, because findBBLink() is done when needed */ - - switch (cmd) { - case IBTMO: /* set timeout time for next transaction only */ - /* find the ibLink structure for the requested link & bug */ -#if 1 - if ((pbbIbLink = (struct bbIbLink *)&(findBBLink(link, bug)->ibLink)) != NULL) -#else - if ((pbbIbLink = findBBLink(link, bug)) != NULL) -#endif - { - /* build a TMO message to send to the bug */ - bbDpvt.txMsg.length = 7; - bbDpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbDpvt.txMsg.node = bug; - bbDpvt.txMsg.tasks = BB_GPIB_TASK; - bbDpvt.txMsg.cmd = BB_IBCMD_SET_TMO; - bbDpvt.txMsg.data = buf; - - buf[0] = v; - - bbDpvt.rxMsg.route = 0; - bbDpvt.rxMaxLen = 7; /* will only get header back anyway */ - bbDpvt.finishProc = NULL; /* no callback when receive reply */ - bbDpvt.psyncSem = &(pbbIbLink->syncSem); - bbDpvt.link = link; - bbDpvt.ageLimit = 0; - - /* send it to the bug */ - if ((*(drvBitBus.qReq))(&bbDpvt, BB_Q_HIGH) != OK) - { - bbDpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbDpvt.psyncSem), WAIT_FOREVER); /* wait for finish */ - if ((bbDpvt.status == BB_OK) && (!(bbDpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - stat = OK; - else - stat = ERROR; - } - break; - - case IBIFC: /* send an Interface Clear pulse */ - /* find the ibLink structure for the requested link & bug */ -#if 1 - if ((pbbIbLink = (struct bbIbLink *)&(findBBLink(link, bug)->ibLink)) != NULL) -#else - if ((pbbIbLink = findBBLink(link, bug)) != NULL) -#endif - { - /* build an IFC message to send to the bug */ - bbDpvt.txMsg.length = 7; - bbDpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbDpvt.txMsg.node = bug; - bbDpvt.txMsg.tasks = BB_GPIB_TASK; - bbDpvt.txMsg.cmd = BB_IBCMD_IFC; - - bbDpvt.rxMsg.route = 0; - bbDpvt.rxMaxLen = 7; /* will only get header back */ - bbDpvt.finishProc = NULL; /* no callback when get reply */ - bbDpvt.psyncSem = &(pbbIbLink->syncSem); - bbDpvt.priority = 0; - bbDpvt.link = link; - bbDpvt.ageLimit = 0; - - /* send it to the bug */ - if ((*(drvBitBus.qReq))(&bbDpvt, BB_Q_HIGH) != OK) - { - bbDpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbDpvt.psyncSem), WAIT_FOREVER); /* wait for finish */ - if ((bbDpvt.status == BB_OK) && (!(bbDpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - stat = OK; - else - stat = ERROR; - } - break; - case IBREN: /* turn the Remote Enable line on or off */ - case IBGTS: /* go to standby (ATN off etc... ) */ - case IBGTA: /* go to active (ATN on etc... ) */ - stat = OK; - break; - case IBGENLINK: /* request the initialization of a link */ - stat = bbGenLink(link, bug); - break; - case IBGETLINK: /* request the address of the ibLink structure */ - *(struct ibLink **)p = &(findBBLink(link, bug)->ibLink); - break; - default: - logMsg("bbGpibIoctl(%d, %d, %d, %08.8X, %08.8X): invalid command requested\n", link, bug, cmd, v, p); - } - return(stat); -} - -/****************************************************************************** - * - * Find a bbIbLink structure given a link number and a bug number. - * - ******************************************************************************/ -struct bbIbLink * -findBBLink(link, bug) -int link; -int bug; -{ - struct bbIbLink *bbIbLink; - - bbIbLink = rootBBLink; - while (bbIbLink != NULL) - { - if ((bbIbLink->ibLink.linkId == link) && (bbIbLink->ibLink.bug == bug)) - break; - else - bbIbLink = bbIbLink->next; - } - if (ibDebug || bbibDebug) - logMsg("findBBLink(%d, %d): returning %08.8X\n", link, bug, bbIbLink); - - return(bbIbLink); -} - /******************************************************************************/ -STATIC int GpibDebug(struct ibLink *pIbLink, int Address, char *Msg, int DBLevel) -{ -#ifdef GPIB_SUPER_DEBUG - semTake(pIbLink->History.Sem, WAIT_FOREVER); - - pIbLink->History.Hist[pIbLink->History.Next].Time = tickGet(); - pIbLink->History.Hist[pIbLink->History.Next].DevAddr = Address; - strncpy(pIbLink->History.Hist[pIbLink->History.Next].Msg, Msg, GPIB_SUPER_DEBUG_HISTORY_STRLEN); - - if (++pIbLink->History.Next == GPIB_SUPER_DEBUG_HISTORY_SIZ) - pIbLink->History.Next = 0; - - if (pIbLink->History.Num < GPIB_SUPER_DEBUG_HISTORY_SIZ) - ++pIbLink->History.Num; - - semGive(pIbLink->History.Sem); -#endif - - if (ibDebug > DBLevel) - { - if (pIbLink->linkType == GPIB_IO) - logMsg("GPIB-L%d-D%d:%s\n", pIbLink->linkId, Address, Msg); - else if (pIbLink->linkType == BBGPIB_IO) - logMsg("BBIB-L%d-B%d-D%d:%s\n", pIbLink->linkId, pIbLink->bug, Address, Msg); - } - - return(0); -} -#ifdef GPIB_SUPER_DEBUG -IBHistDump(int type, int link, int bug) -{ - struct ibLink *pibLink; - int i; - int count; - - if (type == 0) - { /* NI gpib link */ - logMsg("Only bitbus links supported for history dumps\n"); - return(-1); - } - else - { /* Bitbus link */ - if ((pibLink = &(findBBLink(link, bug)->ibLink)) == NULL) - { - logMsg("Invalid link and/or bug specified\n"); - return(-1); - } - } - semTake(pibLink->History.Sem, WAIT_FOREVER); - /* pibLink now represents the link to dump history on */ - if (pibLink->History.Num < GPIB_SUPER_DEBUG_HISTORY_SIZ) - { - i = 0; - count = pibLink->History.Num; - } - else - { - i = pibLink->History.Next; - count = GPIB_SUPER_DEBUG_HISTORY_SIZ; - } - - while(count) - { - if (pibLink->linkType == GPIB_IO) - { - logMsg("%d GPIB-L%d-D%d: %s\n", pibLink->History.Hist[i].Time, - pibLink->linkId, pibLink->History.Hist[i].DevAddr, - pibLink->History.Hist[i].Msg); - } - else if (pibLink->linkType == BBGPIB_IO) - { - logMsg("%d BBIB-l%d-B%d-D%d: %s\n", pibLink->History.Hist[i].Time, - pibLink->linkId, pibLink->bug, pibLink->History.Hist[i].DevAddr, - pibLink->History.Hist[i].Msg); - } - - if (++i == GPIB_SUPER_DEBUG_HISTORY_SIZ) - i = 0; - --count; - } - - semGive(pibLink->History.Sem); - return(0); -} -#endif - -#if 0 -/* A way to stop the CPU when idle... run from shell at prio 250 */ -cpuStopperThingy() -{ - while (1) - asm(" stop #0x3000"); -} -#endif diff --git a/src/drv/drvGpib.h b/src/drv/drvGpib.h deleted file mode 100644 index cbf4f6290..000000000 --- a/src/drv/drvGpib.h +++ /dev/null @@ -1,315 +0,0 @@ -/* drvGpib.h */ -/* base/src/drv $Id$ */ - -/* - * Origional Author: Unknown, probably National Instruments - * Author: John Winans - * Date: 10-27-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 10-27-91 winans moved into epics area - */ - - -/* GPIB-1014 engineering software package UNIX include file */ - -/* - * The following structure dma_chan defines the memory map of a single - * channel on the Hitachi 68450. - */ - -struct dma_chan { - char csr; /* +0 channel status register */ - char cer; /* +1 channel error register */ - char f0[2]; - char dcr; /* +4 device control register */ - char ocr; /* +5 operation control register */ - char scr; /* +6 sequence control register */ - char ccr; /* +7 channel control register */ - char f1[2]; -unsigned short mtc; /* +10 memory transfer counter */ - long mar; /* +12 memory address register */ - char f2[4]; - long dar; /* +20 device address register */ - char f3[2]; -unsigned short btc; /* +26 base transfer counter */ - long bar; /* +28 base address register */ - char f4[5]; - char niv; /* +37 normal interrupt vector */ - char f5; - char eiv; /* +39 error interrupt vector */ - char f6; - char mfc; /* +41 memory function codes */ - char f7[3]; - char cpr; /* +45 channel priority register */ - char f8[3]; - char dfc; /* +49 device function codes */ - char f9[7]; - char bfc; /* +57 base function codes */ - char fA[6]; -}; - -/* - * The structure ibregs defines the address space of the GPIB-1014. - */ -struct ibregs { - - struct dma_chan ch0; /* +0 dma channel 0 */ - struct dma_chan ch1; /* +64 dma channel 1 */ - struct dma_chan ch2; /* +128 dma channel 2 */ - struct dma_chan ch3; /* +192 dma channel 3 */ -#define gcr ch3.fA[5] /* +255 general control register */ - char fB; - char cfg1; /* +257 config reg 1 */ -#define gsr cfg1 /* +257 GSR */ - char fC[3]; - char cfg2; /* +261 config reg 2 */ - char fD[10]; - char fE, cdor; /* +273 byte out register */ - char fF, imr1; /* +275 interrupt mask register 1 */ - char f10,imr2; /* +277 interrupt mask register 2 */ - char f11,spmr; /* +279 serial poll mode register */ - char f12,admr; /* +281 address mode register */ - char f13,auxmr; /* +283 auxiliary mode register */ - char f14,adr; /* +285 address register 0/1 */ - char f15,eosr; /* +287 end of string register */ - char f16[512-289]; /* +289 filler to rest of window */ -}; -/* -* The structure srqTable defines the srq status of each of 31 possible devices -*/ -struct srqTable { - short active; - char lad; - char tad; - unsigned char status; - SEM_ID pSem; -} ; - -/* 7210 readable registers */ -#define dir cdor -#define isr1 imr1 -#define isr2 imr2 -#define spsr spmr -#define adsr admr -#define cptr auxmr -#define adr0 adr -#define adr1 eosr - -/* GPIB status register */ -#define GSR_EOI 0x80 -#define GSR_ATN 0x40 -#define GSR_SRQ 0x20 -#define GSR_REN 0x10 -#define GSR_IFC 0x08 -#define GSR_NRFD 0x04 -#define GSR_NDAC 0x02 -#define GSR_DAV 0x01 - -/* 68450 DMAC register definitions */ - -/* Device Control Register (dcr) bits */ -#define D_CS 0x80 /* cycle steal mode */ -#define D_CSM 0x80 /* cycle steal mode,with bus Monitor*/ -#define D_CSH 0xC0 /* cycle steal with hold */ -#define D_CSHM 0xC0 /* cycle steal with hold,with bus Monitor */ -#define D_IACK 0x20 /* device with DMAACK, implicitly addressed */ -#define D_P16 0x08 /* 16 bit device port size */ -#define D_IPCL 0x01 /* PCL set to status input with interrupt */ - -/* Operation Control Register (ocr) bits */ -#define D_MTD 0x00 /* direction is from memory to device */ -#define D_DTM 0x80 /* direction is from device to memory */ -#define D_TW 0x10 /* transfer size is word */ -#define D_TL 0x30 /* transfer size is long word */ -#define D_ACH 0x08 /* array chaining */ -#define D_LACH 0x0C /* linked array chaining */ -#define D_ARQ 0x03 /* auto request first transfer, then external*/ -#define D_XRQ 0x02 /* external request mode */ -#define D_ARM 0x01 /* auto request at maximum rate */ - - -/* Sequence Control Register (scr) bits */ -#define D_MCD 0x08 /* memory address counts down */ -#define D_MCU 0x04 /* memory address counts up */ -#define D_DCD 0x02 /* device address counts down */ -#define D_DCU 0x01 /* device address counts up */ - -/* Channel Control Register (ccr) bits */ -#define D_SRT 0x80 /* start channel operation */ -#define D_CON 0x40 /* continue */ -#define D_HLT 0x20 /* halt channel operation */ -#define D_SAB 0x10 /* software abort */ -#define D_EINT 0x08 /* enable channel interrupts */ - -/* Channel Status Register (csr) bits */ -#define D_CLEAR 0xFF /* clear all bits */ -#define D_COC 0x80 /* channel operation complete */ -#define D_BTC 0x40 /* block transfer complete */ -#define D_NDT 0x20 /* normal device termination */ -#define D_ERR 0x10 /* error as coded in cer */ -#define D_ACT 0x08 /* channel active */ -#define D_PCLT 0x02 /* PCL transition occurred */ -#define D_PCLH 0x01 /* PCL line is high */ -#define D_NSRQ 0x01 /* Not SRQ (gpib line) */ - -/* Channel Error Register (cer) bits */ -#define D_ECF 0x01 /* configuration error */ -#define D_ETM 0x02 /* operation timing error */ -#define D_EMA 0x05 /* memory address error */ -#define D_EDA 0x06 /* device address error */ -#define D_EBA 0x07 /* base address error */ -#define D_EBUS 0x08 /* bus error */ -#define D_ECT 0x0C /* transfer count error */ -#define D_EEAB 0x01 /* external abort */ -#define D_ESAB 0x11 /* software abort */ - -/* Channel Priority Register (cpr) bits */ -#define D_PR1 0x01 /* priority 1 */ -#define D_PR2 0x02 /* priority 2 */ -#define D_PR3 0x03 /* priority 3 */ - -/* Function Code Register (fcr) bits */ -#define D_SUP 0x04 /* supervisor access */ -#define D_S24 0x02 /* standard 24 bit addressing */ -#define D_PSA 0x01 /* program space access */ - -/* Configuration Register 1 (cfg1) bits */ -#define D_OUT 0 /* direction memory to GPIB */ -#define D_IN (1<<0) /* direction GPIB to memory */ -#define D_DBM (1<<1) /* disarm Bus Monitor mode */ -#define D_ECC (1<<2) /* arm automatic carry cycle feature */ -#define D_BRG0 (00<<3) /* select bus request/grant line 1 */ -#define D_BRG1 (01<<3) /* select bus request/grant line 1 */ -#define D_BRG2 (02<<3) /* select bus request/grant line 2 */ -#define D_BRG3 (03<<3) /* select bus request/grant line 3 */ - - -/* Configuration Register 2 (cfg2) bits */ -#define D_SC (1<<0) /* set system controller (SC) bit */ -#define D_LMR (1<<1) /* set local master reset bit */ -#define D_SPAC (1<<2) /* set supervisor only access to board */ -#define D_SFL (1<<3) /* clear SYSFAIL line */ - - -/* Control masks for hidden registers (auxmr) */ - -#define ICR 0040 -#define PPR 0140 -#define AUXRA 0200 -#define AUXRB 0240 -#define AUXRE 0300 -#define CNT 0340 /* OR of all of above */ - -/* 7210 bits: POSITION 7210 reg */ - -#define HR_DI (1<<0) /* ISR1 */ -#define HR_DO (1<<1) /* , */ -#define HR_ERR (1<<2) /* , */ -#define HR_DEC (1<<3) /* , */ -#define HR_END (1<<4) /* , */ -#define HR_DET (1<<5) /* , */ -#define HR_APT (1<<6) /* , */ -#define HR_CPT (1<<7) /* , */ -#define HR_DIIE (1<<0) /* IMR1 */ -#define HR_DOIE (1<<1) /* , */ -#define HR_ERRIE (1<<2) /* , */ -#define HR_DECIE (1<<3) /* , */ -#define HR_ENDIE (1<<4) /* , */ -#define HR_DETIE (1<<5) /* , */ -#define HR_ADSC (1<<0) /* ISR2 */ -#define HR_REMC (1<<1) /* , */ -#define HR_LOKC (1<<2) /* , */ -#define HR_CO (1<<3) /* , */ -#define HR_REM (1<<4) /* , */ -#define HR_LOK (1<<5) /* , */ -#define HR_SRQI (1<<6) /* , */ -#define HR_INT (1<<7) /* , */ -#define HR_ACIE (1<<0) /* IMR2 */ -#define HR_REMIE (1<<1) /* , */ -#define HR_LOKIE (1<<2) /* , */ -#define HR_COIE (1<<3) /* , */ -#define HR_DMAI (1<<4) /* , */ -#define HR_DMAO (1<<5) /* , */ -#define HR_SRQIE (1<<6) /* , */ -#define HR_PEND (1<<6) /* SPSR */ -#define HR_RSV (1<<6) /* SPMR */ -#define HR_MJMN (1<<0) /* ADSR */ -#define HR_TA (1<<1) /* , */ -#define HR_LA (1<<2) /* , */ -#define HR_TPAS (1<<3) /* , */ -#define HR_LPAS (1<<4) /* , */ -#define HR_SPMS (1<<5) /* , */ -#define HR_NATN (1<<6) /* , */ -#define HR_CIC (1<<7) /* , */ -#define HR_ADM0 (1<<0) /* ADMR */ -#define HR_ADM1 (1<<1) /* , */ -#define HR_TRM0 (1<<4) /* , */ -#define HR_TRM1 (1<<5) /* , */ -#define HR_LON (1<<6) /* , */ -#define HR_TON (1<<7) /* , */ -#define HR_DL (1<<5) /* ADR */ -#define HR_DT (1<<6) /* , */ -#define HR_ARS (1<<7) /* , */ - -#define HR_HLDA (1<<0) /* auxra */ -#define HR_HLDE (1<<1) /* , */ -#define HR_REOS (1<<2) /* , */ -#define HR_XEOS (1<<3) /* , */ -#define HR_BIN (1<<4) /* , */ -#define HR_CPTE (1<<0) /* auxrb */ -#define HR_SPEOI (1<<1) /* , */ -#define HR_TRI (1<<2) /* , */ -#define HR_INV (1<<3) /* , */ -#define HR_ISS (1<<4) /* , */ -#define HR_PPS (1<<3) /* ppr */ -#define HR_PPU (1<<4) /* , */ - -/* 7210 Auxiliary Commands */ - -#define AUX_PON 000 /* Immediate Execute pon */ -#define AUX_CR 002 /* Chip Reset */ -#define AUX_FH 003 /* Finish Handshake */ -#define AUX_TRIG 004 /* Trigger */ -#define AUX_RTL 005 /* Return to local */ -#define AUX_SEOI 006 /* Send EOI */ -#define AUX_NVAL 007 /* Non-Valid Secondary Command or Address */ -#define AUX_VAL 017 /* Valid Secondary Command or Address */ -#define AUX_CPPF 001 /* Clear Parallel Poll Flag */ -#define AUX_SPPF 011 /* Set Parallel Poll Flag */ -#define AUX_TCA 021 /* Take Control Asynchronously */ -#define AUX_TCS 022 /* Take Control Synchronously */ -#define AUX_TCSE 032 /* Take Control Synchronously on End */ -#define AUX_GTS 020 /* Go To Standby */ -#define AUX_LTN 023 /* Listen */ -#define AUX_LTNC 033 /* Listen in Continuous Mode */ -#define AUX_LUN 034 /* Local Unlisten */ -#define AUX_EPP 035 /* Execute Parallel Poll */ -#define AUX_SIFC 036 /* Set IFC */ -#define AUX_CIFC 026 /* Clear IFC */ -#define AUX_SREN 037 /* Set REN */ -#define AUX_CREN 027 /* Clear REN */ -#define AUX_DSC 024 /* Disable System Control */ - diff --git a/src/drv/drvHp1404a.c b/src/drv/drvHp1404a.c deleted file mode 100644 index 06c51d071..000000000 --- a/src/drv/drvHp1404a.c +++ /dev/null @@ -1,408 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * - * HP E1404A VXI bus slot zero translator - * device dependent routines - * - * share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93 - * - * Author Jeffrey O. Hill - * Date 030692 - * - * 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 joh 073092 Added msg device support & interrupt shutdown for - * soft reboots - * .02 joh 082792 converted to ANSI C - * .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals - * - * - * - */ - -static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93"; - -#include -#include -#include -#include - -#include -#include -#include - -LOCAL unsigned long hpE1404DriverID; - -struct hpE1404_config{ - void (*pSignalCallback)(int16_t signal); -}; - -#define TLTRIG(N) (1<<(N)) -#define ECLTRIG(N) (1<<((N)+8)) - -/* - * enable int when signal register is written - */ -#define HP1404A_INT_ENABLE 0x0008 -#define HP1404A_INT_DISABLE 0x0000 - -/* - * - * tag the device dependent registers - */ -#define IRQ_enable dir.w.dd.reg.ddx1a -#define MSG_status dir.w.dd.reg.ddx1e -#define fp_trig_drive dir.w.dd.reg.ddx2a -#define bp_trig_drive dir.w.dd.reg.ddx22 -#define signal_read dir.r.dd.reg.ddx10 - -#define hpE1404PConfig(LA, PC) \ - epvxiFetchPConfig((LA), hpE1404DriverID, (PC)) - -LOCAL void hpE1404InitLA( - unsigned la -); - -LOCAL int hpE1404ShutDown( - void -); - -LOCAL void hpE1404ShutDownLA( - unsigned la -); - -LOCAL void hpE1404IOReport( -unsigned la, -unsigned level -); - -LOCAL void hpE1404Int( -unsigned la -); - - - -/* - * - * hpE1404Init - * - */ -hpE1404Stat hpE1404Init(void) -{ - hpE1404Stat status; - - status = rebootHookAdd(hpE1404ShutDown); - if(status<0){ - status = S_dev_internal; - errMessage(status, "rebootHookAdd() failed"); - return status; - } - - hpE1404DriverID = epvxiUniqueDriverID(); - - status = epvxiRegisterMakeName( - VXI_MAKE_HP, - "Hewlett-Packard"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_REG_SLOT0, - "Slot Zero Translator (reg)"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_REG, - "Translator (reg)"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_MSG, - "Translator (msg)"); - if(status){ - errMessage(status, NULL); - } - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0; - status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return status; - } - - dsp.model = VXI_HP_MODEL_E1404_REG; - status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return status; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404ShutDown() - * - * - */ -LOCAL int hpE1404ShutDown(void) -{ - hpE1404Stat status; - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0; - status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return ERROR; - } - - dsp.model = VXI_HP_MODEL_E1404_REG; - status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return ERROR; - } - return OK; -} - - -/* - * - * hpE1404ShutDownLA() - * - * - */ -LOCAL -void hpE1404ShutDownLA( - unsigned la -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->IRQ_enable = HP1404A_INT_DISABLE; -} - - -/* - * - * hpE1404InitLA() - * - */ -LOCAL -void hpE1404InitLA( - unsigned la -) -{ - struct hpE1404_config *pc; - struct vxi_csr *pcsr; - hpE1404Stat status; - - status = epvxiOpen( - la, - hpE1404DriverID, - sizeof(*pc), - hpE1404IOReport); - if(status){ - errMessage(status, NULL); - return; - } - - pcsr = VXIBASE(la); - - status = hpE1404PConfig(la, pc); - if(status){ - errMessage(status, NULL); - epvxiClose(la, hpE1404DriverID); - return; - } - - /* - * set the self test status to passed for - * the message based device - */ - pcsr->MSG_status = VXIPASS<<2; - - intConnect( - INUM_TO_IVEC(la), - hpE1404Int, - la); - - /* - * enable int when signal register is written - */ - pcsr->IRQ_enable = HP1404A_INT_ENABLE; - - return; -} - - -/* - * - * hpE1404SignalConnect() - * - */ -hpE1404Stat hpE1404SignalConnect( -unsigned la, -void (*pSignalCallback)(int16_t signal) -) -{ - hpE1404Stat s; - struct hpE1404_config *pc; - - s = hpE1404PConfig(la, pc); - if(s){ - return s; - } - - pc->pSignalCallback = pSignalCallback; - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404Int() - * - */ -LOCAL -void hpE1404Int( - unsigned la -) -{ - hpE1404Stat s; - struct vxi_csr *pcsr; - unsigned short signal; - struct hpE1404_config *pc; - - s = hpE1404PConfig(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - - /* - * vector is only D8 so we cant check the cause of the int - * (signal cause is assumed since that was all that was enabled) - */ - - pcsr = VXIBASE(la); - - signal = pcsr->signal_read; - - if(pc->pSignalCallback){ - (*pc->pSignalCallback)(signal); - } -} - - -/* - * - * hpE1404RouteTriggerECL - * - */ -hpE1404Stat hpE1404RouteTriggerECL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->fp_trig_drive = (io_map&enable_map)<<8; - pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8; - - return VXI_SUCCESS; -} - - -/* - * - * - * hpE1404RouteTriggerTTL - * - * - */ -hpE1404Stat hpE1404RouteTriggerTTL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->fp_trig_drive = io_map&enable_map; - pcsr->bp_trig_drive = (~io_map)&enable_map; - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404IOReport() - * - * - */ -LOCAL -void hpE1404IOReport( - unsigned la, - unsigned level -) -{ - - - - -} diff --git a/src/drv/drvHp1404a.h b/src/drv/drvHp1404a.h deleted file mode 100644 index f6f6d2bfb..000000000 --- a/src/drv/drvHp1404a.h +++ /dev/null @@ -1,74 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * drvHp1404a.h - * - * HP E1404A VXI bus slot zero translator - * device dependent routines header file - * - * share/src/drv/@(#)drvHp1404a.h 1.1 8/27/93 - * - * Author Jeffrey O. Hill - * Date 030692 - * - * 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: - * ----------------- - * - * - * - */ - -typedef long hpE1404Stat; - -hpE1404Stat hpE1404Init(void); - -hpE1404Stat hpE1404SignalConnect( - unsigned la, - void (*pSignalCallback)(int16_t signal) -); - -hpE1404Stat hpE1404RouteTriggerECL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -); - -hpE1404Stat hpE1404RouteTriggerTTL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -); - -#define VXI_HP_MODEL_E1404_REG_SLOT0 0x10 -#define VXI_HP_MODEL_E1404_REG 0x110 -#define VXI_HP_MODEL_E1404_MSG 0x111 - - diff --git a/src/drv/drvHpe1368a.c b/src/drv/drvHpe1368a.c deleted file mode 100644 index a760b09d1..000000000 --- a/src/drv/drvHpe1368a.c +++ /dev/null @@ -1,359 +0,0 @@ -/* drvHpe1368a.c*/ -/* base/src/drv $Id$ */ - -/* - * hpe1368a_driver.c - * - * driver for hpe1368a and hpe1369a microwave switch VXI modules - * - * Author: Jeff Hill - * Date: 052192 - * - * 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 071792 joh Added model name registration - * .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID - * .03 082692 mrk Added support for new I/O event scanning and DRVET - * .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - * - */ - -static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93"; - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define HPE1368A_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), hpe1368aDriverId, (PC)) - -#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08) -#define ModuleStatus(PCSR) ((PCSR)->dir.r.status) - -#define ALL_SWITCHES_OPEN 0 - -struct hpe1368a_config{ - FAST_LOCK lock; /* mutual exclusion */ - unsigned short pending; /* switch position pending int */ - unsigned short shadow; /* shadow of actual switch pos */ - int busy; /* relays active */ - IOSCANPVT ioscanpvt; -}; - -#define HPE1368A_INT_LEVEL 1 - -LOCAL int hpe1368aDriverId; - -LOCAL void hpe1368a_int_service(unsigned la); -LOCAL void hpe1368a_init_card(unsigned la); -LOCAL void hpe1368a_stat(unsigned la, int level); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvHpe1368a={ - 2, - NULL, /*VXI io report takes care of this */ - hpe1368a_init}; - - -/* - * hpe1368a_init - * - * initialize all hpe1368a cards - * - */ -hpe1368aStat hpe1368a_init(void) -{ - hpe1368aStat r0; - - /* - * do nothing on crates without VXI - */ - if(!epvxiResourceMangerOK){ - return VXI_SUCCESS; - } - - hpe1368aDriverId = epvxiUniqueDriverID(); - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_MODEL_HPE1368A; - r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL); - if(r0){ - errMessage(r0, NULL); - return r0; - } - } - - return VXI_SUCCESS; -} - - - -/* - * HPE1368A_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL void hpe1368a_init_card(unsigned la) -{ - hpe1368aStat r0; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - int model; - - r0 = epvxiOpen( - la, - hpe1368aDriverId, - (unsigned long) sizeof(*pc), - hpe1368a_stat); - if(r0){ - errMessage(r0,NULL); - return; - } - - r0 = HPE1368A_PCONFIG(la, pc); - if(r0){ - errMessage(r0, NULL); - return; - } - - pcsr = VXIBASE(la); - - /* - * we must reset the device to a known state since - * we cant read back the current state - */ - pc->pending = ALL_SWITCHES_OPEN; - pc->shadow = ALL_SWITCHES_OPEN; - ChannelEnable(pcsr) = ALL_SWITCHES_OPEN; - - FASTLOCKINIT(&pc->lock); - scanIoInit(&pc->ioscanpvt); - - r0 = intConnect( - INUM_TO_IVEC(la), - hpe1368a_int_service, - la); - if(r0 == ERROR){ - errMessage(S_dev_vxWorksVecInstlFail, NULL); - return; - } - - sysIntEnable(HPE1368A_INT_LEVEL); - - model = VXIMODEL(pcsr); - r0 = epvxiRegisterModelName( - VXIMAKE(pcsr), - model, - "E 1368A Microwave Switch\n"); - if(r0){ - errMessage(r0, NULL); - } - r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard"); - if(r0){ - errMessage(r0,NULL); - } -} - - -/* - * - * hpe1368a_int_service() - * - * - * This device interrupts once the - * switches have settled - * - */ -LOCAL void -hpe1368a_int_service(unsigned la) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la,pc); - if(s){ - return; - } - - /* - * operation completed so we can update - * the shadow value - */ - pc->shadow = pc->pending; - pc->busy = FALSE; - - /* - * tell them that the switches have settled - */ - scanIoRequest(pc->ioscanpvt); -} - - -/* - * HPE1368A_STAT - * - * initialize single at5vxi card - * - */ -LOCAL void hpe1368a_stat( -unsigned la, -int level -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return; - } - pcsr = VXIBASE(la); - - if(level>0){ - printf("\tSwitch states %x\n", pc->shadow); - printf("\tModule status %x\n", pcsr->dir.r.status); - if(pc->busy){ - printf("\tModule is busy.\n"); - } - } -} - - -/* - * hpe1368a_getioscanpvt() - */ -hpe1368aStat hpe1368a_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - *scanpvt = pc->ioscanpvt; - return VXI_SUCCESS; -} - - -/* - * HPE1368A_BO_DRIVER - */ -hpe1368aStat hpe1368a_bo_driver( -unsigned la, -unsigned val, -unsigned mask -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - unsigned int work; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pc->lock); - - work = pc->pending; - - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - pc->pending = work; - - ChannelEnable(pcsr) = work; - - FASTUNLOCK(&pc->lock); - - return VXI_SUCCESS; -} - - - -/* - * - * HPE1368A_BI_DRIVER - * - * - * - */ -hpe1368aStat hpe1368a_bi_driver( -unsigned la, -unsigned mask, -unsigned *pval -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - FASTLOCK(&pc->lock); - - *pval = pc->shadow & mask; - - FASTUNLOCK(&pc->lock); - - return VXI_SUCCESS; -} diff --git a/src/drv/drvHpe1368a.h b/src/drv/drvHpe1368a.h deleted file mode 100644 index 6e7688555..000000000 --- a/src/drv/drvHpe1368a.h +++ /dev/null @@ -1,60 +0,0 @@ -/* drvHpe1368a.h*/ -/* base/src/drv $Id$ */ - -/* - * hpe1368a_driver.h - * - * driver for hpe1368a and hpe1369a microwave switch VXI modules - * - * Author: Jeff Hill - * Date: 052192 - * - * 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: - * ----------------- - * - */ - -#define VXI_MODEL_HPE1368A (0xf28) - -typedef long hpe1368aStat; - -hpe1368aStat hpe1368a_init(void); - -hpe1368aStat hpe1368a_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -); - -hpe1368aStat hpe1368a_bo_driver( -unsigned la, -unsigned val, -unsigned mask -); - -hpe1368aStat hpe1368a_bi_driver( -unsigned la, -unsigned mask, -unsigned *pval -); - diff --git a/src/drv/drvHpe1445a.c b/src/drv/drvHpe1445a.c deleted file mode 100644 index e26af0598..000000000 --- a/src/drv/drvHpe1445a.c +++ /dev/null @@ -1,1185 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * driver for hpe1445a arbitrary function generator VXI modules - * - * Author: Jeff Hill - * Date: 082492 - * - * 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 021192 joh Fixed hpe1445aUnloadWaveformLocked() ANSI C - * function prototype missmatch. Changed - * unsigned short to unsigned. - * - * - */ - -static char *sccsId = "@(#)drvHpe1445a.c 1.5\t8/27/93"; - -#include -#include -#include - -#include -#include -#include -#include - -/* - * comment out this line if you prefer - * to use backplane ttl trigger 0 - */ -#define FRONT_PANEL_TRIGGER - -#define VXI_MODEL_HPE1445A (418) - -LOCAL int hpe1445aDriverId; - -#define HPE1445A_MAX_POINTS 0x40000 -#define HPE1445A_MIN_POINTS 4 - -#define HPE1445_DATA_PORT_OFFSET (0x26) - -struct hpe1445aConfig { - FAST_LOCK lck; - char device_active; - double dacPeakAmplitude; - double dacOffset; - char buf[256]; -}; - -#define HPE1445A_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), hpe1445aDriverId, (PC)) - -typedef long hpe1445aStat; - -/* - * - * For External Use - * - */ -hpe1445aStat hpe1445aInit(void); -hpe1445aStat hpe1445aSetupDAC(unsigned la, double dacPeakAmplitude, double dacOffset); -hpe1445aStat hpe1445aSetupFreq(unsigned la, char *pFreqString); -void hpe1445aIoReport(unsigned la, int level); -hpe1445aStat hpe1445aLoadWaveform(unsigned la, char *pWaveformName, - double *pdata, unsigned long npoints); -hpe1445aStat hpe1445aUnloadWaveform(unsigned la, char *pWaveformName); -hpe1445aStat hpe1445aActivateWaveform(unsigned la, char *pWaveformName); -hpe1445aStat hpe1445aTest(unsigned la); -hpe1445aStat hpe1445aWriteWithLineno(unsigned la, char *pmsg, unsigned lineno); -void hpe1445aLogErrorsWithLineno(unsigned la, int lineno); - - -/* - * - * For Driver Internal Use - * - */ -LOCAL void hpe1445aInitCard(unsigned la); -LOCAL hpe1445aStat hpe1445aReset(unsigned la); -LOCAL hpe1445aStat logEntireError(unsigned la, int lineno); -LOCAL hpe1445aStat hpe1445aActivateWaveformLocked(unsigned la, char *pWaveformName, - struct hpe1445aConfig *pc); -LOCAL hpe1445aStat hpe1445aSetupFunction(unsigned la); -LOCAL hpe1445aStat hpe1445aSetupOutput(unsigned la); -LOCAL hpe1445aStat hpe1445aArm(unsigned la); -LOCAL hpe1445aStat hpe1445aUnloadWaveformLocked(unsigned la, char *pWaveformName); -LOCAL hpe1445aStat hpe1445aLoadWaveformLocked(unsigned la, - struct hpe1445aConfig *pc, - char *pWaveformName, double *pdata, - unsigned long npoints); - - -#define logErrors(LA) hpe1445aLogErrorsWithLineno(LA, __LINE__) -#define hpe1445aWrite(LA, PMSG) hpe1445aWriteWithLineno(LA, PMSG, __LINE__) - -#define HPE1445A_MAX_NAME_LENGTH 12 -#define SEGMENT_NAME_PREFIX "e_" -#define SEQUENCE_NAME_PREFIX "e__" -#define PREFIX_MAX_NAME_LENGTH 3 -#define MAX_NAME_LENGTH (HPE1445A_MAX_NAME_LENGTH-PREFIX_MAX_NAME_LENGTH) - -#define TEST_FILE_NAME "hpe1445a.dat" - - -/* - * - * hpe1445aTest() - * - * - */ -hpe1445aStat hpe1445aTest(unsigned la) -{ - hpe1445aStat s; - FILE *pf; - char *pfn = TEST_FILE_NAME; - double *pwaveform; - int nsamples; - int i; - - pf = fopen(pfn, "r"); - if(!pf){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "file access problems %s", - pfn); - fclose(pf); - return s; - } - s = fscanf(pf, "%d", &nsamples); - if(s!=1){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "no element count in the file %s", - pfn); - fclose(pf); - return s; - } - - pwaveform = (double *) calloc(nsamples, sizeof(double)); - if(!pwaveform){ - s = S_dev_noMemory; - errPrintf( - s, - __FILE__, - __LINE__, - "specified sample count to large %s", - pfn); - fclose(pf); - return s; - } - - for(i=0; ibuf, - sizeof(pc->buf), - &read_count, - 0); - if(s!=S_epvxi_bufferFull && s!=VXI_SUCCESS){ - errPrintf( - s, - __FILE__, - lineno, - "error fetch problem at LA=0X%X", - la); - return s; - } - nreads++; - /* - * return of zero indicates no errors - * this will always be a very short message - */ - if(nreads==1){ - int val; - int n; - - n = sscanf(pc->buf,"%d",&val); - if(n==1){ - if(val==0){ - return S_epvxi_internal; - } - } - } - errPrintf( - S_epvxi_msgDeviceStatus, - __FILE__, - lineno, - "LA=0X%X: Error => %s", - la, - pc->buf); - - if(s==VXI_SUCCESS){ - break; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aReset() - * - * - */ -LOCAL -hpe1445aStat hpe1445aReset(unsigned la) -{ - hpe1445aStat s; - - s = hpe1445aWrite(la, "*RST"); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list1:ssequence:delete:all"); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list1:segment:delete:all"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupFreq() - * - * - */ -hpe1445aStat hpe1445aSetupFreq(unsigned la, char *pFreqString) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return s; - } - - /* - * - * Set the sample rate - * - */ - sprintf(pc->buf, "source:frequency:fixed %s", pFreqString); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupFunction() - * - * - */ -LOCAL -hpe1445aStat hpe1445aSetupFunction(unsigned la) -{ - hpe1445aStat s; - - /* - * - * set the function to arbitrary waveform - * - */ - s = hpe1445aWrite(la, "source:function:shape user"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupOutput() - * - * - */ -LOCAL -hpe1445aStat hpe1445aSetupOutput(unsigned la) -{ - hpe1445aStat s; - - - /* - * set the output impedance - * (50 Ohm coax assumed) - * - */ - s = hpe1445aWrite(la, "output:impedance 50 Ohm"); - if(s){ - return s; - } - - /* - * - * disable output low pass filter - * (freq would need to be set if it were turned on) - * - */ - s = hpe1445aWrite(la, "output:filter:lpass:state off"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * hpe1445aArm() - * - */ -hpe1445aStat hpe1445aArm(unsigned la) -{ - hpe1445aStat s; - - /* - * - * initiate waveform output off the external trigger input - * - */ -#ifdef FRONT_PANEL_TRIGGER - s = hpe1445aWrite(la, "arm:start:layer2:source external"); -#else - s = hpe1445aWrite(la, "arm:start:layer2:source ttltrg0"); -#endif - if(s){ - return s; - } - - /* - * - * initiate waveform output on the rising edge - * - */ - s = hpe1445aWrite(la, "arm:start:layer2:slope positive"); - if(s){ - return s; - } - - /* - * - * output the waveform once only after receiving - * a trigger - * - */ - s = hpe1445aWrite(la, "arm:start:layer1:count 1"); - if(s){ - return s; - } - - /* - * - * output the waveform after each trigger edge - * forever - * - */ - s = hpe1445aWrite(la, "arm:start:layer2:count infinity"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * - * hpe1445aSetupDAC - * - * - * - */ -hpe1445aStat hpe1445aSetupDAC( -unsigned la, -double dacPeakAmplitude, -double dacOffset) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la,pc); - if(s){ - errMessage(s,NULL); - return s; - } - - sprintf(pc->buf, - "source:voltage:level:immediate:amplitude %f V", - dacPeakAmplitude); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - pc->dacPeakAmplitude = dacPeakAmplitude; - - sprintf(pc->buf, - "source:voltage:level:immediate:offset %f V", - dacOffset); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - pc->dacOffset = dacOffset; - - logErrors(la); - - return VXI_SUCCESS; -} - - - -/* - * - * hpe1445aActivateWaveform() - * - * - * - */ -hpe1445aStat hpe1445aActivateWaveform( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return s; - } - - FASTLOCK(&pc->lck); - - s = hpe1445aActivateWaveformLocked(la, pWaveformName, pc); - - FASTUNLOCK(&pc->lck); - - return s; -} - - -/* - * - * hpe1445aActivateWaveformLocked() - * - * - * - */ -LOCAL hpe1445aStat -hpe1445aActivateWaveformLocked( -unsigned la, -char *pWaveformName, -struct hpe1445aConfig *pc -) -{ - int s; - - if(pc->device_active){ - s = hpe1445aWrite(la, "abort"); - if(s){ - return s; - } - pc->device_active = FALSE; - } - - /* - * - * select active sequence - * - */ - sprintf( pc->buf, - "source:function:user %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * - * initiate the trigger system - * - */ - s = hpe1445aWrite(la, "initiate:immediate"); - if(s){ - return s; - } - pc->device_active = TRUE; - - logErrors(la); - - return VXI_SUCCESS; -} - - - -/* - * - * hpe1445aUnloadWaveform() - * - * - * - */ -hpe1445aStat hpe1445aUnloadWaveform( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - FASTLOCK(&pc->lck); - - s = hpe1445aUnloadWaveformLocked(la, pWaveformName); - - FASTUNLOCK(&pc->lck); - - logErrors(la); - - return s; -} - - -/* - * - * hpe1445aUnloadWaveformLocked() - * - * - * - */ -LOCAL hpe1445aStat hpe1445aUnloadWaveformLocked( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - sprintf( - pc->buf, - "source:list:ssequence:select %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list:ssequence:delete:selected"); - if(s){ - return s; - } - - sprintf( - pc->buf, - "source:list:segment:select %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list:segment:delete:selected"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - - -/* - * hpe1445aLoadWaveform() - */ -hpe1445aStat -hpe1445aLoadWaveform( -unsigned la, -char *pWaveformName, -double *pdata, -unsigned long npoints -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - if(strlen(pWaveformName)>MAX_NAME_LENGTH){ - s = S_dev_highValue; - errMessage(s, "waveform element name to long"); - return s; - } - - if(npointslck); - - s = hpe1445aLoadWaveformLocked(la, pc, pWaveformName, pdata, npoints); - - FASTUNLOCK(&pc->lck); - - return s; -} - - -/* - * - * hpe1445aLoadWaveformLocked() - * - * - */ -LOCAL hpe1445aStat hpe1445aLoadWaveformLocked( -unsigned la, -struct hpe1445aConfig *pc, -char *pWaveformName, -double *pdata, -unsigned long npoints -) -{ - unsigned long read_count; - hpe1445aStat s; - - s = hpe1445aWrite(la, "source:list:segment:free?"); - if(s){ - return s; - } - s = epvxiRead( - la, - pc->buf, - sizeof(pc->buf), - &read_count, - 0); - if(s){ - errMessage(s, "\"source:list:segment:free?\" query failed"); - return s; - } - - { - int nfree; - int nused; - - s = sscanf(pc->buf, "%d,%d", &nfree, &nused); - if(s!=2){ - s = S_dev_internal; - errMessage(s, "bad \"source:list:segment:free?\" resp"); - return s; - } - if(nfree < npoints){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "%d waveform elements available", - nfree); - errPrintf( - s, - __FILE__, - __LINE__, - "%d element waveform rejected", - npoints); - return s; - } - } - - - /* - * - * select the segment for subsequent - * commands - * - */ - sprintf( - pc->buf, - "source:list:segment:select %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - - sprintf(pc->buf, "source:list:segment:define %u", npoints); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - sprintf( pc->buf, - "source:arbitrary:download VXI,%s%s,%d", - SEGMENT_NAME_PREFIX, - pWaveformName, - npoints); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * wait for the device to finish with the download - * command prior to the backplane download - */ - s = hpe1445aWrite(la, "*OPC?"); - if(s){ - return s; - } - s = epvxiRead( - la, - pc->buf, - sizeof(pc->buf), - &read_count, - 0); - if(s){ - errMessage(s,"\"*OPC?\" query failed"); - return s; - } - - { - double truncationOffset; - double dacPeakAmplitude; - double dacOffset; - double *pwf; - unsigned short *pdata_port; - - pdata_port = (unsigned short *) epvxiA24Base(la); - pdata_port += (HPE1445_DATA_PORT_OFFSET/sizeof(*pdata_port)); - dacPeakAmplitude = pc->dacPeakAmplitude; - dacOffset = pc->dacOffset; - truncationOffset = dacPeakAmplitude/(4095*2); - for(pwf=pdata; pwf < &pdata[npoints]; pwf++){ - short idata; - double fdata; - - /* - * extra step here preserves precision - */ - fdata = (*pwf-dacOffset)*4095; - fdata = fdata/dacPeakAmplitude; - /* - * This offset causes round up to occur and - * not truncation - */ - fdata += truncationOffset; - idata = (short) fdata; - idata = idata << 3; - - if(pwf == &pdata[npoints-4]){ -# define LAST_POINT 1 - idata |= LAST_POINT; - } - - /* - * load the waveform element into the 1445 - */ - *pdata_port = idata; - } - } - - s = hpe1445aWrite(la, "source:arbitrary:download:complete"); - if(s){ - return s; - } - - /* - * - * install this segment into the sequence - * - */ - sprintf( pc->buf, - "source:list:ssequence:select %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * set the number of segments in this sequence - */ - s = hpe1445aWrite(la, "source:list:ssequence:define 1"); - if(s){ - return s; - } - sprintf(pc->buf, - "source:list:ssequence:sequence %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - s = hpe1445aWrite(la, "source:list:ssequence:dwell:count 1"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aWriteWithLineno() - * - */ -hpe1445aStat hpe1445aWriteWithLineno( - unsigned la, - char *pmsg, - unsigned lineno -) -{ - unsigned long nactual; - hpe1445aStat s; - - s = epvxiWrite( - la, - pmsg, - strlen(pmsg), - &nactual, - 0); - if(s){ - errPrintf( - s, - __FILE__, - lineno, - "LA=0X%02X MSG=%s", - la, - pmsg); - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aIoReport() - * - * - */ -void hpe1445aIoReport(unsigned la, int level) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - char *pStateName[] = {"in",""}; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - - if(level>0){ - printf("\tdevice %sactive, DAC peak = %f V, DAC offset = %f V\n", - pStateName[(unsigned)pc->device_active], - pc->dacPeakAmplitude, - pc->dacOffset); - } -} diff --git a/src/drv/drvJgvtr1.c b/src/drv/drvJgvtr1.c deleted file mode 100644 index fbe1eb589..000000000 --- a/src/drv/drvJgvtr1.c +++ /dev/null @@ -1,641 +0,0 @@ -/* drvJgvtr1.c */ -/* base/src/drv $Id$ */ -/* - * Author: Jeff Hill - * Date: 5-89 - * - * 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: - * ----------------- - * 110689 joh print mem not full message only once - * 120789 joh temporary removal of memory full check - * 050190 joh clear ptr to callback prior to calling - * it so they can rearm from inside the callback - * 071190 joh check STD address after cycle complete detected - * to avoid erroneous card misaddressed messages - * 071190 joh internal sample rate status is bit reversed on the - * card- I added a lookup table to untwist it. - * 020491 ges Change taskDelay from 20 to 2 in "jgvtr1DoneTask". - * To allow rearm and data reads from succesive - * waveform scans up thru 10Hz rates. - * 031491 lrd move data into a local memory area for each card - * 090591 joh converted to V5 vxWorks - * 110591 lrd initialization of cards other than 0 not - * allocating data buffer correctly - * 013092 bg added sysBusToLocalAdrs. Added levels to io_report - * and the ability to read out the Joerger's raw values - * in io_report if level is > 1. - * 031992 joh Took the vxMemProbe out of each arm and checked - * the card present bit instead. - * 062592 bg Combined drvJgvtr1.c and jgvtr_driver.c - * 062992 joh removed file pointer argument added to io - * report by bg - * 082792 joh added ANSI C function prototypes - * 080293 mrk added call to taskwdInsert - * 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - */ - -static char *sccsID = "@(#)drvJgvtr1.c 1.17\t9/9/93"; - -/* - * Code Portions - * - * jgvtr1_init() - * jgvtr1_driver(card, pcbroutine, parg) - * jgvtr1_int_service() - * jgvtr1DoneTask() - * jgvtr1_io_report() - * jgvtr1_stat(card) - * - */ - -/* drvJgvtr1.c - Driver Support Routines for Jgvtr1 */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -LOCAL jgvtr1Stat jgvtr1_io_report( - unsigned level -); - -LOCAL jgvtr1Stat jgvtr1_init( - void -); - -#ifdef INTERRUPT_HARDWARE_FIXED -LOCAL void jgvtr1_int_service( - void -); -#endif - -LOCAL void jgvtr1DoneTask( - void -); - -LOCAL jgvtr1Stat jgvtr1_dump( - unsigned card, - unsigned n -); - -LOCAL jgvtr1Stat jgvtr1_stat( - unsigned card, - int level -); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvJgvtr1={ - 2, - jgvtr1_io_report, - jgvtr1_init}; - -static volatile char *stdaddr; -static volatile char *shortaddr; - - -#define JGVTR1MAXFREQ 25.0e6 -/* NBBY - the number of bits per byte */ -#define JGVTR1SHORTSIZE (1<<(NBBY*sizeof(uint8_t))) -#define JGVTR1STDSIZE (1<<(NBBY*sizeof(uint16_t))) -#define JGVTR1_INT_LEVEL 5 -#define JGVTR1BASE(CARD)\ -(shortaddr+wf_addrs[JGVTR1]+(CARD)*JGVTR1SHORTSIZE) -#define JGVTR1DATA(CARD)\ -(stdaddr+wf_memaddrs[JGVTR1]+(CARD)*JGVTR1STDSIZE) - - -/* -Joerger fixed hardware bug by switching to an inverting tristate buffer -where these commands are read from the VME bus. As a result these commands -are complemented. -*/ -#define JGVTR1ARM (~1) -#define JGVTR1START (~2) -#define JGVTR1STOP (~4) - - - -/* -!! our compiler allocates bit fields starting from the ms bit !! -*/ -struct jgvtr1_status{ - volatile unsigned pad:8; - volatile unsigned internal_frequency:3; - volatile unsigned internal_clock:1; - volatile unsigned cycle_complete:1; - volatile unsigned interrupt:1; - volatile unsigned active:1; - volatile unsigned memory_full:1; -}; - -struct jgvtr1_config{ - char present; /* card present */ - char std_ok; /* std addr ok on first read */ - void (*psub) /* call back routine */ - (void *pprm, unsigned nbytes, uint16_t *pData); - void *pprm; /* call back parameter */ - FAST_LOCK lock; /* mutual exclusion */ - uint16_t *pdata; /* pointer to the data buffer */ -}; - -/* amount of data to make available from the waveform */ -#define JRG_MEM_SIZE 2048 - -LOCAL -struct jgvtr1_config *pjgvtr1_config; - -LOCAL -int jgvtr1_max_card_count; - -#ifdef INTERRUPT_HARDWARE_FIXED -LOCAL -SEM_ID jgvtr1_interrupt; /* interrupt event */ -#endif - - - -/* - * JGVTR1_INIT - * - * intialize the driver for the joerger vtr1 - * - */ -jgvtr1Stat jgvtr1_init(void) -{ - unsigned card; - unsigned card_count = 0; - struct jgvtr1_config *pconfig; - uint16_t readback; - jgvtr1Stat status; - - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - 0, - (char **)&shortaddr); - if (status != OK){ - status = S_dev_badA16; - errMessage(status,NULL); - return status; - } - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - 0, - (char **)&stdaddr); - if (status != OK){ - status = S_dev_badA24; - errMessage(status,NULL); - return status; - } - - jgvtr1_max_card_count = wf_num_cards[JGVTR1]; - - if(pjgvtr1_config){ - if(FASTLOCKFREE(&pjgvtr1_config->lock)<0) - return ERROR; - free(pjgvtr1_config); - } - - pjgvtr1_config = - (struct jgvtr1_config *) - calloc(wf_num_cards[JGVTR1], sizeof(*pjgvtr1_config)); - if(!pjgvtr1_config){ - status = S_dev_noMemory; - errMessage(status,NULL); - return status; - } - - for( card=0, pconfig=pjgvtr1_config; - card < wf_num_cards[JGVTR1]; - pconfig++, card++){ - - FASTLOCKINIT(&pconfig->lock); - - status = vxMemProbe( (char *)JGVTR1BASE(card), - READ, - sizeof(readback), - (char *)&readback); - if(status==ERROR) - continue; - - - pconfig->pdata = - (uint16_t *)malloc(JRG_MEM_SIZE); - /* - not easy to test for correct addressing in - standard address space since the module does - not respond if it has not clocked in data - - - so I check this the first time data is ready - */ - pconfig->std_ok = FALSE; /* presumed guilty before tested */ - pconfig->present = TRUE; - card_count++; - } - - if(!card_count) - return OK; - - -# ifdef INTERRUPT_HARDWARE_FIXED - jgvtr1_interrupt = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - if(!jgvtr1_interrupt) - return ERROR; -# endif - - /* start the waveform readback task */ - status = taskSpawn( WFDONE_NAME, - WFDONE_PRI, - WFDONE_OPT, - WFDONE_STACK, - (FUNCPTR) jgvtr1DoneTask, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - if(status < 0){ - status = S_dev_internal; - errMessage(status, "vxWorks taskSpawn failed"); - return status; - } - - taskwdInsert(status, NULL, NULL); - - -# ifdef INTERRUPT_HARDWARE_FIXED - status = intConnect( INUM_TO_IVEC(JGVTR1_INT_VEC), - jgvtr1_int_service, - NULL); - if(status != OK) - return S_dev_internal; - sysIntEnable(JGVTR_INT_LEVEL); -# endif - - return JGVTR1_SUCCESS; -} - - - -/* - * JGVTR1_DRIVER - * - * initiate waveform read - * - */ -jgvtr1Stat jgvtr1_driver( -unsigned card, -void (*pcbroutine)(void *, unsigned, uint16_t *), -void *parg -) -{ - if(card >= jgvtr1_max_card_count) - return S_dev_badSignalNumber; - - if(!pjgvtr1_config[card].present) - return S_dev_noDevice; - - if(pjgvtr1_config[card].psub) - return S_dev_badRequest; - - FASTLOCK(&pjgvtr1_config[card].lock); - - *(volatile uint16_t *)JGVTR1BASE(card) = JGVTR1ARM; - - pjgvtr1_config[card].pprm = parg; - pjgvtr1_config[card].psub = pcbroutine; - - FASTUNLOCK(&pjgvtr1_config[card].lock); - - return JGVTR1_SUCCESS; -} - - -/* - * JGVTR1_INT_SERVICE - * - * signal via the RTK that an interrupt occured from the joerger vtr1 - * - */ -#ifdef INTERRUPT_HARDWARE_FIXED -LOCAL void jgvtr1_int_service(void) -{ - semGive(jgvtr1_interrupt); -} -#endif - - -/* - * JGVTR1DONETASK - * - * wait for joerger vtr1 waveform record cycle complete - * and call back to the database with the waveform size and address - * - */ -LOCAL void jgvtr1DoneTask(void) -{ - unsigned card; - struct jgvtr1_config *pconfig; - struct jgvtr1_status stat; - static char started = FALSE; - volatile uint16_t *pdata; - volatile uint16_t *pjgdata; - long i; - - /* dont allow two of this task */ - if(started) - exit(0); - started = TRUE; - - while(TRUE){ - -# ifdef INTERRUPT_HARDWARE_FIXED - semTake(jgvtr1_interrupt, WAIT_FOREVER); -# else - /* ges: changed from 20 ticks to 2 ticks 2/4/91 */ - taskDelay(2); -# endif - - for( card=0, pconfig = pjgvtr1_config; - card < jgvtr1_max_card_count; - card++, pconfig++){ - - if(!pconfig->present) - continue; - - if(!pconfig->psub) - continue; - - stat = *(struct jgvtr1_status *) JGVTR1BASE(card); - /* - * Wait for the module to finish filling its memory - * or a stop trigger - */ - if(!stat.cycle_complete) - continue; - - /* - clear ptr to function here so they - can rearm in the callback - */ - pconfig->psub = NULL; - /* - check the first time for module - correctly addressed - - card does not respond at STD address - until it has data - */ - if(!pconfig->std_ok){ - uint16_t readback; - int status; - - status = vxMemProbe( - (char *)JGVTR1DATA(card), - READ, - sizeof(readback), - (char *)&readback); - if(status==ERROR){ - errPrintf( - S_dev_badA24, - __FILE__, - __LINE__, - "jgvtr1 card %d incorrectly addressed- use std addr 0X%X", - card, - JGVTR1DATA(card)); - pconfig->present = FALSE; - continue; - } - pconfig->std_ok = TRUE; - } -/* - Test for full memory - ( card designer does not give a sample count register ) - ( instead a bus error returned when on the last sample - to test every location is a lot of overhead so a test - for memory full is used for now ) -*/ - if(!stat.memory_full){ - errMessage(S_dev_internal, - "jgvtr1 driver: proceeding with partial mem"); - errMessage(S_dev_internal, - "jgvtr1 driver: beware of bus errors"); - } - - /* copy the data into a local memory buffer */ - /* this is to avoid any bus errors */ - for(i = 0, - pdata = pconfig->pdata, - pjgdata = (volatile uint16_t *)JGVTR1DATA(card); - i < JRG_MEM_SIZE/sizeof(uint16_t); - i++, pdata++, pjgdata++){ - *pdata = *pjgdata; - } - -/* - Post waveform to the database - perhaps the size must be the size below+1 ? - (Joerger's documentation is not clear here) -*/ - (*pconfig->psub)(pconfig->pprm,JRG_MEM_SIZE,pconfig->pdata); - } - } -} - - - -/* - * - * JGVTR1_IO_REPORT - * - * print status for all cards in the specified joerger - * vtr1 address range - * - * - */ -LOCAL jgvtr1Stat jgvtr1_io_report(unsigned level) -{ - unsigned card; - unsigned nelements; - jgvtr1Stat status; - - for(card=0; card < wf_num_cards[JGVTR1]; card++){ - status = jgvtr1_stat(card,level); - if(status){ - continue; - } - if (level >= 2){ - printf("enter the number of elements to dump:"); - status = scanf("%d",&nelements); - if(status == 1){ - jgvtr1_dump(card, nelements); - } - } - } - return JGVTR1_SUCCESS; -} - - - -/* - * - * JGVTR1_STAT - * - * print status for a single card in the joerger vtr1 address range - * - * - */ -jgvtr1Stat jgvtr1_stat( -unsigned card, -int level -) -{ - struct jgvtr1_status stat; - jgvtr1Stat status; - - /* - internal freq status is bit reversed so I - use a lookup table - */ - - static float sample_rate[8] = { - JGVTR1MAXFREQ/(1<<7), - JGVTR1MAXFREQ/(1<<3), - JGVTR1MAXFREQ/(1<<5), - JGVTR1MAXFREQ/(1<<1), - JGVTR1MAXFREQ/(1<<6), - JGVTR1MAXFREQ/(1<<2), - JGVTR1MAXFREQ/(1<<4), - JGVTR1MAXFREQ/(1<<0)}; - - static char *clock_status[] = - {"ext-clock", "internal-clk"}; - static char *cycle_status[] = - {"cycling", "done"}; - static char *interrupt_status[] = - {"", "int-pending"}; - static char *activity_status[] = - {"", "active"}; - static char *memory_status[] = - {"", "mem-full"}; - - status = vxMemProbe( (char *)JGVTR1BASE(card), - READ, - sizeof(stat), - (char *)&stat); - if(status != OK) - return ERROR; - if (level == 0) - printf("WF: JGVTR1:\tcard=%d \n",card); - else if (level > 0) - printf( "WF: JGVTR1:\tcard=%d Sample rate=%g %s %s %s %s %s \n", - card, - sample_rate[stat.internal_frequency], - clock_status[ stat.internal_clock ], - cycle_status[ stat.cycle_complete ], - interrupt_status[ stat.interrupt ], - activity_status[ stat.active ], - memory_status[ stat.memory_full ]); - - return JGVTR1_SUCCESS; -} - - -/* - * jgvtr1_dump - * - */ -LOCAL jgvtr1Stat jgvtr1_dump( -unsigned card, -unsigned n -) -{ - volatile uint16_t *pjgdata; - uint16_t *pread; - uint16_t *pdata; - unsigned nread; - jgvtr1Stat status; - - /* Print out the data if user requests it. */ - - n = min(JRG_MEM_SIZE,n); - - pdata = (uint16_t *)malloc(n * (sizeof(*pdata))); - if(!pdata){ - return S_dev_noMemory; - } - - pread = pdata; - nread = 0; - pjgdata = (volatile uint16_t *)JGVTR1DATA(card); - while(nread <= (n>>1)){ - status = vxMemProbe( - (char *)pjgdata, - READ, - sizeof(*pread), - (char *)pread); - if(status<0){ - break; - } - nread++; - pread++; - pjgdata++; - } - - for(pread=pdata; pread<&pdata[nread]; pread++){ - if ((pread-pdata)%8 == 0){ - printf("\n\t"); - } - printf( "%02X %02X ", - (unsigned char) ((*pread)>>8), - (unsigned char) *pread); - } - - printf("\n"); - - free(pdata); - - return JGVTR1_SUCCESS; -} diff --git a/src/drv/drvJgvtr1.h b/src/drv/drvJgvtr1.h deleted file mode 100644 index f4c3f6454..000000000 --- a/src/drv/drvJgvtr1.h +++ /dev/null @@ -1,43 +0,0 @@ -/* drvJgvtr1.h */ -/* base/src/drv $Id$ */ -/* - * Author: Jeff Hill - * Date: 5-89 - * - * 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: - * ----------------- - */ - - - -typedef long jgvtr1Stat; - -#define JGVTR1_SUCCESS 0 - -jgvtr1Stat jgvtr1_driver( -unsigned card, -void (*pcbroutine)(void *, unsigned, uint16_t *), -void *parg -); - diff --git a/src/drv/drvKscV215.c b/src/drv/drvKscV215.c deleted file mode 100644 index 35a245a8a..000000000 --- a/src/drv/drvKscV215.c +++ /dev/null @@ -1,484 +0,0 @@ -/* drvKscV215.c*/ -/* base/src/drv $Id$ */ -/* - * KscV215_driver.c - * - * driver for KscV215 VXI module - * - * Author: Jeff Hill - * Date: 052192 - * - * 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 071792 joh Added model name registration - * .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID - * .03 082692 mrk Added support for new I/O event scanning and DRVET - * .04 012893 joh include file name change - * .05 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - * - */ - - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define MAXTRIES 100 - -#define KSCV215_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), KscV215DriverId, PC) - -#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08) -#define ModuleStatus(PCSR) ((PCSR)->dir.r.status) - -#define ALL_SWITCHES_OPEN 0 - -struct KscV215_config{ - FAST_LOCK lock; /* mutual exclusion */ - IOSCANPVT ioscanpvt; -}; - -#define KSCV215_INT_LEVEL 1 -#define KscV215Handshake (0x0040) -#define KscV215csrInit (0x9000) - -LOCAL int KscV215DriverId; - - -struct KscV215_A24{ - unsigned short diag; - unsigned short isr; - unsigned short pad1[7]; - unsigned short channels[64]; /* odd access causes a bus error ? */ - unsigned short controlMemoryAddr; - unsigned short pad2; - unsigned short controlMemoryDataWrite; - unsigned short pad3; - unsigned short controlMemoryDataRead; - unsigned short pad4; - unsigned short lastChannel; - unsigned short pad5; - unsigned short singleScan; - unsigned short pad6; - unsigned short stopScan; - unsigned short pad7; - unsigned short clearControlMemoryAddr; - unsigned short pad8; - unsigned short enableContinuousScanning; - unsigned short pad9; - unsigned short disableContinuousScanning; - unsigned short pad10; - unsigned short enableDoneInt; - unsigned short pad11; - unsigned short disbaleDoneInt; - unsigned short pad12; - unsigned short clearDoneInt; - unsigned short pad13; - unsigned short testDoneInt; - unsigned short pad14; -}; - -#ifdef INTERRUPTS -LOCAL void KscV215_int_service(unsigned la); -#endif -LOCAL void KscV215_init_card(unsigned la); - -LOCAL void KscV215_stat( -unsigned la, -int level -); - -LOCAL kscV215Stat KscV215WriteSync( -struct KscV215_A24 *pA24, -unsigned short *preg, -unsigned val -); - - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvKscV215={ - 2, - NULL, /* VXI report takes care of this */ - KscV215Init}; - -/* - * KscV215_init - * - * initialize all KscV215 cards - * - */ -kscV215Stat KscV215Init(void) -{ - kscV215Stat r0; - - /* - * do nothing on crates without VXI - */ - if(!epvxiResourceMangerOK){ - return VXI_SUCCESS; - } - - KscV215DriverId = epvxiUniqueDriverID(); - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_KSC; - dsp.model = VXI_MODEL_KSCV215; - r0 = epvxiLookupLA(&dsp, KscV215_init_card, (void *)NULL); - if(r0){ - return r0; - } - } - - return VXI_SUCCESS; -} - - - -/* - * KSCV215_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL void KscV215_init_card(unsigned la) -{ - kscV215Stat status; - int i; - struct KscV215_config *pc; - struct KscV215_A24 *pA24; - struct vxi_csr *pcsr; - int model; - - status = epvxiOpen( - la, - KscV215DriverId, - (unsigned long) sizeof(*pc), - KscV215_stat); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "AT5VXI: device open failed %d\n", - la); - - return; - } - - status = KSCV215_PCONFIG(la, pc); - if(status){ - errMessage(status,NULL); - epvxiClose(la, KscV215DriverId); - return; - } - - pA24 = epvxiA24Base(la); - pcsr = VXIBASE(la); - - pcsr->dir.w.control = KscV215csrInit; - - status = KscV215WriteSync(pA24, &pA24->controlMemoryAddr, 0); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed\n"); - return; - } - for(i=0; i<(NELEMENTS(pA24->channels)/2); i++){ - status = KscV215WriteSync( - pA24, - &pA24->controlMemoryDataWrite, - 0); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed\n"); - return; - } - } - - /* - * turn on continuous scan mode - */ - status = KscV215WriteSync( - pA24, - &pA24->enableContinuousScanning, - 0); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed- device left open\n"); - return; - } - - FASTLOCKINIT(&pc->lock); - scanIoInit(&pc->ioscanpvt); - -#ifdef INTERRUPTS - status = intConnect( - (unsigned char) INUM_TO_IVEC(la), - KscV215_int_service, - (void *) la); - if(status == ERROR){ - epvxiClose(la, KscV215DriverId); - errMessage(S_dev_vxWorksVecInstlFail, - "KscV215 init failed- device left open"); - return; - } - sysIntEnable(KSCV215_INT_LEVEL); -#endif - - status = epvxiRegisterMakeName(VXI_MAKE_KSC, "Kinetic Systems"); - if(status){ - errMessage(status, NULL); - } - - model = VXIMODEL(pcsr); - status = epvxiRegisterModelName( - VXIMAKE(pcsr), - model, - "V215 16 bit 32 channel ADC\n"); - if(status){ - errMessage(status, NULL); - } - -} - - -/* - * - * KscV215WriteSync - * - * - */ -LOCAL kscV215Stat KscV215WriteSync( -struct KscV215_A24 *pA24, -unsigned short *preg, -unsigned val -) -{ - kscV215Stat status; - int i; - - for(i=0; idiag & KscV215Handshake){ - return VXI_SUCCESS; - } - taskDelay(1); - } - - status = S_dev_deviceTMO; - errMessage(status, NULL); - return status; -} - - -/* - * - * KscV215_int_service() - * - * - * This device interrupts once the - * switches have settled - * - */ -#ifdef INTERRUPTS -LOCAL void KscV215_int_service(unsigned la) -{ - kscV215Stat s; - struct KscV215_config *pc; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - logMsg( "Int to ukn device %s line=%d\n", - __FILE__, - __LINE__, - NULL, - NULL, - NULL, - NULL); - return; - } - - /* - * tell them that the switches have settled - */ - scanIoRequest(pc->ioscanpvt); -} -#endif - - -/* - * KSCV215_STAT - * - * initialize single at5vxi card - * - */ -LOCAL void KscV215_stat( -unsigned la, -int level -) -{ - kscV215Stat s; - struct KscV215_config *pc; - struct vxi_csr *pcsr; - struct KscV215_A24 *pA24; - int i; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - pcsr = VXIBASE(la); - - pA24 = (struct KscV215_A24 *) epvxiA24Base(la); - - if(level>0){ - printf ("KSC V215 32 CHANNEL 16 BIT ADC.\n"); - } - if (level > 1) { - for (i = 0; i < 32; i++) - printf ("Channel %d Value %d\n", - i, - pA24->channels[i*2]); - } - if (level > 2) { - printf ("\nGain Setting (Control Memory Data Register\n"); - pA24->controlMemoryAddr = 0; - for (i = 0; i < 32; i++) { - switch (pA24->controlMemoryAddr) { - case 0: - printf ("+- 10V"); - break; - case 1: - printf ("+- 5V"); - break; - case 3: - printf ("+- 2.5V"); - break; - case 5: - printf ("+- 1.25V"); - break; - case 6: - printf ("+- 625mV"); - break; - default: - printf ("Unknown Gain Setting."); - } - } - printf ("\n"); - } - - - -} - - - -/* - * - * - * AT5VXI_AI_DRIVER - * - * analog input driver - */ -kscV215Stat KscV215_ai_driver( -unsigned la, -unsigned chan, -unsigned short *prval -) -{ - struct KscV215_config *pc; - struct vxi_csr *pcsr; - struct KscV215_A24 *pA24; - long tmp; - int i; - kscV215Stat s; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - return s; - } - pcsr = VXIBASE(la); - - pA24 = epvxiA24Base(la); - - if(chan >= NELEMENTS(pA24->channels)/2){ - return S_dev_badSignalNumber; - } - - for(i=0; ichannels[chan<<1]; - if(pA24->diag & KscV215Handshake){ - tmp = tmp + 0xffff; - tmp = tmp >> 4; - tmp &= 0xfff; - *prval = tmp; - return VXI_SUCCESS; - } - taskDelay(1); - } - - s = S_dev_deviceTMO; - return s; -} - - -/* - * KscV215_getioscanpvt() - */ -kscV215Stat KscV215_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -) -{ - kscV215Stat s; - struct KscV215_config *pc; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - *scanpvt = pc->ioscanpvt; - return VXI_SUCCESS; -} diff --git a/src/drv/drvKscV215.h b/src/drv/drvKscV215.h deleted file mode 100644 index 34eaf2c27..000000000 --- a/src/drv/drvKscV215.h +++ /dev/null @@ -1,56 +0,0 @@ -/* drvKscV215.c*/ -/* base/src/drv $Id$ */ -/* - * KscV215_driver.c - * - * driver for KscV215 VXI module - * - * Author: Jeff Hill - * Date: 052192 - * - * 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: - * ----------------- - * - */ - -#define VXI_MODEL_KSCV215 (0x215) - -typedef long kscV215Stat; - -kscV215Stat KscV215Init(void); - -kscV215Stat KscV215_ai_driver( -unsigned la, -unsigned chan, -unsigned short *prval -); - -kscV215Stat KscV215_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -); - - - - diff --git a/src/drv/drvMsg.c b/src/drv/drvMsg.c deleted file mode 100644 index cfa92d202..000000000 --- a/src/drv/drvMsg.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 04-14-92 - * EPICS Generic message based I/O driver - * - * 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-14-92 jrw created - * .02 05-26-92 jrw changed enumeration of the record types - * .03 08-02-93 mrk Added call to taskwdInsert - * - */ - -#include -#include -#if 0 /* COMMENTED OUT SOME INCLUDES */ -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* COMMENTED OUT SOME INCLUDES */ - - -#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 - -int msgDebug = 0; - -#ifndef INVALID_ALARM -#define INVALID_ALARM VALID_ALARM -#endif - -static long drvMsg_write(), drvMsg_AiFmt(); -static long drvMsg_AoFmt(); -long drvMsg_proc(); -static long drvMsg_BiFmt(), drvMsg_BoFmt(), drvMsg_MiFmt(), drvMsg_MoFmt(); -static long drvMsg_LiFmt(), drvMsg_LoFmt(), drvMsg_SiFmt(), drvMsg_SoFmt(); -static long drvMsg_SiRaw(), drvMsg_SoRaw(); -static long drvMsg_CheckAck(); - -static void drvMsg_callbackFunc(); -static int msgTask(); - -static long (*(msgSupFun[]))() = { - NULL, /* MSG_OP_NOP */ - drvMsg_write, /* MSG_OP_WRITE */ - drvMsg_AiFmt, /* MSG_OP_FAI */ - drvMsg_AoFmt, /* MSG_OP_FAO */ - drvMsg_BiFmt, /* MSG_OP_FBI */ - drvMsg_BoFmt, /* MSG_OP_FBO */ - drvMsg_MiFmt, /* MSG_OP_FMI */ - drvMsg_MoFmt, /* MSG_OP_FMO */ - drvMsg_LiFmt, /* MSG_OP_FLI */ - drvMsg_LoFmt, /* MSG_OP_FLO */ - drvMsg_SiFmt, /* MSG_OP_FSI */ - drvMsg_SoFmt, /* MSG_OP_FSO */ - drvMsg_SiRaw, /* MSG_OP_RSI */ - drvMsg_SoRaw, /* MSG_OP_RSO */ - drvMsg_CheckAck /* MSG_OP_ACK */ -}; -#define NUM_VALID_OPS sizeof(msgSupFun)/sizeof(msgSupFun[0]) - -/****************************************************************************** - * - * These are the msgRecEnum structures that are used to define the - * types of records supported by the message based driver system. - * - * This list may be extended by the application developer in the device support - * module if necessary. - * - ******************************************************************************/ -msgRecEnum drvMsgAi = { "Analog In" }; -msgRecEnum drvMsgAo = { "Analog Out" }; -msgRecEnum drvMsgBi = { "Binary In" }; -msgRecEnum drvMsgBo = { "Binary Out" }; -msgRecEnum drvMsgMi = { "Multibit In" }; -msgRecEnum drvMsgMo = { "Multibit Out" }; -msgRecEnum drvMsgLi = { "Long In" }; -msgRecEnum drvMsgLo = { "Long Out" }; -msgRecEnum drvMsgSi = { "String In" }; -msgRecEnum drvMsgSo = { "String Out" }; -msgRecEnum drvMsgWf = { "Waveform" }; - -/****************************************************************************** - * - * Driver entry table for the message based I/O driver - * - ******************************************************************************/ -struct drvet drvMsg = { 2, drvMsg_reportMsg, drvMsg_initMsg }; - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_reportMsg(pdset) -msgDset *pdset; -{ - printf("Message driver report\n"); - - if (pdset->pparmBlock->pdrvBlock->drvIoctl != NULL) - return((*(pdset->pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_REPORT, NULL)); - - return(OK); -} - - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_initMsg(parm, pdset) -int parm; -msgDset *pdset; -{ - - msgDrvIniParm initParms; - - initParms.parm = parm; - initParms.pdset = pdset; - - if (msgDebug) - printf("Message init routine entered %d, 0x%08.8X\n", parm, pdset); - - if(pdset->pparmBlock->pdrvBlock->drvIoctl != NULL) - return((*(pdset->pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_INIT, &initParms)); - - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -drvMsg_xactListAddHead(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - pnode->prev = NULL; - pnode->next = plist->head; - - if (plist->head != NULL) - plist->head->prev = pnode; - - if (plist->tail == NULL) - plist->tail = pnode; - - plist->head = pnode; - - return(0); -} -/****************************************************************************** - * - ******************************************************************************/ -drvMsg_xactListAddTail(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - pnode->next = NULL; /* No next node if this is the TAIL */ - pnode->prev = plist->tail; /* previous node is the 'old' TAIL node */ - - if (plist->tail != NULL) - plist->tail->next = pnode; /* link the 'old' tail to the 'new' tail node */ - - if (plist->head == NULL) - plist->head = pnode; - - plist->tail = pnode; /* this is the 'new' tail node */ - - return(0); -} -/****************************************************************************** - * - ******************************************************************************/ -drvMsg_xactListDel(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - if (pnode->next != NULL) - pnode->next->prev = pnode->prev; - - if (pnode->prev != NULL) - pnode->prev->next = pnode->next; - - if (plist->head == pnode) - plist->head = pnode->next; - - if (plist->tail == pnode) - plist->tail = pnode->prev; - - return(0); -} - -/****************************************************************************** - * - * Generate a transaction structure and initialize it. - * - ******************************************************************************/ -msgXact * -drvMsg_genXact(pparmBlock, plink, prec) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -struct dbCommon *prec; -{ - msgXact *pmsgXact; - msgDrvGenXParm genXactParm; - char message[200]; - - /* allocate and fill in msg specific part */ - if ((pmsgXact = malloc(sizeof (msgXact))) == NULL) - { - sprintf(message, "drvMsg_genXact:%s out of memory\n", prec->name); - errMessage(S_db_badField, message); - return(NULL); - } - pmsgXact->pparmBlock = pparmBlock; - pmsgXact->prec = prec; - - genXactParm.plink = plink; - genXactParm.pmsgXact = pmsgXact; - - /* fill in communication-link specific portion and phwpvt */ - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENXACT, &genXactParm) == ERROR) - { - /* free-up the xact structure and clean up */ - - /* errMessage() */ - printf("(Message driver): An error occurred while initializing %s\n", prec->name); - return(NULL); - } - /* Verify that the parm number is within range */ - if (pmsgXact->parm >= pparmBlock->numCmds) - { - sprintf(message, "(Message driver) %s parm number %d invalid\n", prec->name, pmsgXact->parm); - errMessage(S_db_badField, message); - return(NULL); - } - - /* Make a simple check to see if the parm entry makes sense */ - if ((pparmBlock->pcmds[pmsgXact->parm].flags & READ_DEFER) && (pparmBlock->pcmds[pmsgXact->parm].readOp.p == NULL)) - { - sprintf(message, "(Message driver) %s parm number %d specifies a deferred read, but no read operation\n", prec->name, pmsgXact->parm); - errMessage(S_db_badField, message); - return(NULL); - } - return(pmsgXact); -} - -/****************************************************************************** - * - * Generate a hardware private structure and initialize it. - * This is called by pparmBlock->pdrvBlock->drvIoctl(MSGIOCTL_GENXACT) when it - * finds that a hardware private structure is not present when a transaction - * structure is being initialized for it. - * - ******************************************************************************/ -msgHwpvt * -drvMsg_genHwpvt(pparmBlock, plink) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -{ - msgHwpvt *pmsgHwpvt; - msgDrvGenHParm genHParms; - - if (msgDebug) - printf("In drvMsg_genHwpvt\n"); - - /* allocate and fill in msg specific part */ - if((pmsgHwpvt = malloc(sizeof(msgHwpvt))) == NULL) - return(NULL); - - /* Link it into the msgParmBlock list */ - pmsgHwpvt->next = pparmBlock->pmsgHwpvt; - pparmBlock->pmsgHwpvt = pmsgHwpvt; - - pmsgHwpvt->tmoVal = 0; - pmsgHwpvt->tmoCount = 0; - - genHParms.pparmBlock = pparmBlock; - genHParms.plink = plink; - genHParms.pmsgHwpvt = pmsgHwpvt; - - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENHWPVT, &genHParms) == ERROR) - { - /* Free up the hardware private structure and clean up */ - /* It is still first on the list, so don't have to look for it */ - return(NULL); - } - - return(pmsgHwpvt); -} - -/****************************************************************************** - * - * Generate a message queue link structure and start a task to manage it. - * This is called by pparmBlock->pdrvBlock->drvIoctl(MSGIOCTL_GENHWPVT) when - * it finds that a specific link structure is not present that is needed when - * initializing a hardware private structure. - * - ******************************************************************************/ -msgLink * -drvMsg_genLink(pparmBlock, plink) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -{ - msgDrvGenLParm genlParms; - msgLink *pmsgLink; - char name[20]; - long status; - int j; - int taskId; - - if (msgDebug) - printf("In drvMsg_genLink\n"); - - /* Allocate and fill in the msg specific part */ - if ((pmsgLink = malloc(sizeof(msgLink))) == NULL) - return(NULL); - - /* init all the prioritized transaction queues */ - for(j=0; jqueue[j].head = NULL; - pmsgLink->queue[j].tail = NULL; - FASTLOCKINIT(&(pmsgLink->queue[j].lock)); - } - pmsgLink->linkEventSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - genlParms.pmsgLink = pmsgLink; - genlParms.plink = plink; - genlParms.op = MSG_GENLINK_CREATE; - genlParms.pparmBlock = pparmBlock; - - /* do the driver-specific init */ - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENLINK, &genlParms) == ERROR) - { - /* free the pmsgLink structure and clean up */ - return(NULL); - } - sprintf(name, "%s", pparmBlock->pdrvBlock->taskName); - if ((taskId = taskSpawn(name, pparmBlock->pdrvBlock->taskPri, pparmBlock->pdrvBlock->taskOpt, pparmBlock->pdrvBlock->taskStack, msgTask, pparmBlock->pdrvBlock, pmsgLink)) == ERROR) - { - printf("Message driver: Failed to start link task %s\n", name); -/* BUG --delete the FASTLOCK in here */ - status = ERROR; - } else { - taskwdInsert(taskId,NULL,NULL); - status = OK; - } - - if (status == ERROR) - { - genlParms.op = MSG_GENLINK_ABORT; - - (*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENLINK, &genlParms); - free(pmsgLink); - return(NULL); - } - return(pmsgLink); -} - -/****************************************************************************** - * - * Check to verify that a given parameter number is within range for the - * given device type. - * - ******************************************************************************/ -long -drvMsg_checkParm(prec, recTyp) -struct dbCommon *prec; -char *recTyp; -{ - unsigned int parm; - char message[100]; - - if (prec->dpvt != NULL) - { - parm = ((msgXact *)(prec->dpvt))->parm; - if ((((msgXact *)(prec->dpvt))->pparmBlock->pcmds)[parm].recTyp != ((struct msgDset *)(prec->dset))->precEnum) - { - sprintf(message, "Message driver-checkParm: %s parm number %d not valid for %s record type\n", prec->name, parm, recTyp); - errMessage(S_db_badField, message); - prec->pact = TRUE; - return(S_db_badField); - } - return(0); - } - return(S_db_badField); -} - -/****************************************************************************** - * - * Callback function used to complete async-record processing. - * - ******************************************************************************/ -static void -drvMsg_callbackFunc(pcallback) -CALLBACK *pcallback; -{ - dbScanLock(((msgXact *)(pcallback->user))->prec); - (*(struct rset *)(((msgXact *)(pcallback->user))->prec->rset)).process(((msgXact *)(pcallback->user))->prec); - dbScanUnlock(((msgXact *)(pcallback->user))->prec); -} - -/****************************************************************************** - * - * Function used to initialize the callback structure within the transaction - * structure. This sets it up so that it is used to perform the completion - * phase of the async record processing. - * - ******************************************************************************/ -long -drvMsg_initCallback(prec) -struct dbCommon *prec; -{ - ((msgXact *)(prec->dpvt))->callback.callback = drvMsg_callbackFunc; - /* ((msgXact *)(prec->dpvt))->callback.priority = prec->prio; */ - ((msgXact *)(prec->dpvt))->callback.user = (void *)(prec->dpvt); - - return(OK); -} - -/****************************************************************************** - * - * Queue a transaction for the link task. - * - ******************************************************************************/ -long -drvMsg_qXact(xact, prio) -msgXact *xact; -int prio; -{ - msgLink *pmsgLink = xact->phwpvt->pmsgLink; - - /* The link verification is done at record-init time & not needed here. */ - - if ((prio < 0) || (prio >= NUM_CALLBACK_PRIORITIES)) - { - xact->status = XACT_BADPRIO; - return(ERROR); - } - - xact->callback.priority = prio; /* Callback processing priority */ - - FASTLOCK(&(pmsgLink->queue[prio].lock)); - drvMsg_xactListAddTail(&(pmsgLink->queue[prio]), xact); - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - semGive(pmsgLink->linkEventSem); - - return(OK); -} - -/****************************************************************************** - * - * Message-driver link-task. - * - * This function is spawned as a task during iocInit(). It waits on a semaphore - * that is given when either a message (transaction) is queued for a device - * associated with the link, or an event of some kind was detected from a device - * associated with the link. - * - * When the task wakes up, it checks to see if it was due to an event. If so, - * the support function that identified the event will also specify a - * transaction structure to process. If no event occurred, then the - * transaction request queues are checked. - * - * If a transaction was found, either due to an event or the work queues, it - * is processed. Processing a transaction consists of two optional phases. - * These phases are called the write and read phases, but either of them - * may do either writing, reading, or nothing. In the typical case, the - * first phase will do some writing (either setting a condition or soliciting a - * response) and the second phase will do some reading (reading back a solicited - * response) or nothing (in cases where no response will be generated to some - * write command.) - * - ******************************************************************************/ -static int msgTask(pdrvBlock, pmsgLink) -msgDrvBlock *pdrvBlock; -msgLink *pmsgLink; -{ - int working; - int prio; - msgXact *xact; - int event; - msgCmd *pmsgCmd; - msgChkEParm checkEventParms; - - if (msgDebug) - printf("Message driver link task %s started\n", pdrvBlock->taskName); - - checkEventParms.pdrvBlock = pdrvBlock; - checkEventParms.pmsgLink = pmsgLink; - checkEventParms.pxact = &xact; - - working = 1; /* Force a first time check on events and xact queues */ - - while (1) - { - if (!working) - semTake(pmsgLink->linkEventSem, WAIT_FOREVER); - - working = 0; - xact = NULL; - - /* Check to see if we woke up because of a device event */ - event = (*(pdrvBlock->drvIoctl))(MSGIOCTL_CHECKEVENT, &checkEventParms); - - if (event == MSG_EVENT_NONE) - { /* No device events pending, check the request queues for work */ - prio = 0; - while ((xact == NULL) && prio < NUM_CALLBACK_PRIORITIES) - { - FASTLOCK(&(pmsgLink->queue[prio].lock)); - if ((xact = pmsgLink->queue[prio].head) != NULL) - { - drvMsg_xactListDel(&(pmsgLink->queue[prio]), xact); - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - } - else - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - - prio++; - } - } - if (xact != NULL) - { - working = 1; - xact->status = XACT_OK; /* All well, so far */ - pmsgCmd = &(xact->pparmBlock->pcmds[xact->parm]); - - if ((pmsgCmd->writeOp.op != MSG_OP_NOP) && ((event == MSG_EVENT_NONE)||(event & MSG_EVENT_WRITE))) - { /* Perform the write portion of a transaction operation */ - (*(xact->pparmBlock->doOp))(xact, &(pmsgCmd->writeOp)); - } - - if ((xact->status == XACT_OK) && (pmsgCmd->readOp.op != MSG_OP_NOP)) - { /* There is a read opertaion spec'd, check to see if I can do it now */ - if (((pmsgCmd->flags & READ_DEFER) == 0)||(event & MSG_EVENT_READ)) - { /* Not a deferred readback parm -or- it is and is time to read */ - (*(xact->pparmBlock->doOp))(xact, &(pmsgCmd->readOp)); - - if (xact->callback.callback != NULL) - callbackRequest(xact); - - if (xact->psyncSem != NULL) - semGive(*(xact->psyncSem)); - } - /* else -- is a defered readback, must wait for readback event */ - } - else - { /* There is no read operation specified, finish the xact opetation */ - if (xact->callback.callback != NULL) - callbackRequest(xact); - - if (xact->psyncSem != NULL) - semGive(*(xact->psyncSem)); - } - } - } -} - -/****************************************************************************** - * - * These functions encapsulates the calls made to the device-specific read and - * write functions. The idea here is that we can monitor and/or buffer I/O - * operations from here. - * - * At the moment, this is used to do cehcks on the read-cache's time-to-live. - * - ******************************************************************************/ -long -drvMsg_drvWrite(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return(pxact->pparmBlock->pdrvBlock->drvWrite(pxact, pparm)); -} - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_drvRead(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return((*(pxact->pparmBlock->pdrvBlock->drvRead))(pxact, pparm)); -} - -/****************************************************************************** - * - * This function is called to handle the processing of a transaction. - * The idea here is that xact->pparmBlock->doOp could point to this - * function if there are not any custom operations, or to it's own - * function that could check to see if the operation is local/custom and - * then call this if it is not. - * - ******************************************************************************/ -long -drvMsg_xactWork(pxact, pop) -msgXact *pxact; -msgCmdOp *pop; -{ - if ((pop->op > 0) && (pop->op < NUM_VALID_OPS)) - return((*(msgSupFun[pop->op]))(pxact, pop->p)); - - printf("drvMsg_xactWork: Invalid operation code %d encountered\n", pop->op); - pxact->status = XACT_BADCMD; - return(XACT_BADCMD); -} - -/****************************************************************************** - * - * Write a string to the device w/o any formatting. - * - ******************************************************************************/ -static long -drvMsg_write(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return(drvMsg_drvWrite(pxact, pparm)); -} - -/****************************************************************************** - * - * Read a string and see if it contains the substring provided in the - * msgAkParm structure. This is useful to check the ack string from a - * device because it will cause the record to go into a INVALID alarm - * state if the ACK does not match the provided string. - * - * If the provided substring is a zero-length string, it will match - * any possible ACK string. - * - ******************************************************************************/ -static long -drvMsg_CheckAck(pxact, packParm) -msgXact *pxact; -msgAkParm *packParm; -{ - msgStrParm strParm; -/* BUG -- the buffer size will have to be configurable */ - char buf[100]; - char *ach; - char *rch; - - strParm.buf = buf; - strParm.len = packParm->len; - - drvMsg_drvRead(pxact, &strParm); - if (msgDebug > 5) - printf("drvMsg_CheckAck comparing >%s< at %d against >%s<\n", buf, packParm->index, packParm->str); - - if (pxact->status == XACT_OK) - { - ach = &(packParm->str[packParm->index]); - rch = buf; - while (*ach != '\0') - { - if (*ach != *rch) - { - *ach = '\0'; /* stop the while loop */ - pxact->status = XACT_IOERR; - } - else - { - ach++; - rch++; - } - } - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_AiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct aiRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - * NOTE: The rval is filled in for the BI record so that conversion may - * take place in record support. - * - ******************************************************************************/ -static long -drvMsg_BiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct biRecord *)(pxact->prec))->rval)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - * NOTE: The rval is filled in for the MBBI record so that conversion may - * take place in record support. - * - ******************************************************************************/ -static long -drvMsg_MiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct mbbiRecord *)(pxact->prec))->rval)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_LiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct longinRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_SiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), (((struct stringinRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string - * - ******************************************************************************/ -static long -drvMsg_SiRaw(pxact, parm) -msgXact *pxact; -void *parm; -{ - msgStrParm strParm; - - strParm.buf = ((struct stringinRecord *)(pxact->prec))->val; - strParm.len = sizeof(((struct stringinRecord *)(pxact->prec))->val); - - drvMsg_drvRead(pxact, &strParm); - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to write a string that includes the VAL field of an - * analog output record, to an RS-232 device. - * - ******************************************************************************/ -static long -drvMsg_AoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct aoRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_BoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct boRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -/****************************************************************************** - * - * NOTE: The formatting of the MBBO value uses the RVAL field so that the - * conversion from VAL to RVAL in the record (the movement of one of the - * onvl, twvl,... fields to the rval field during record processing.) - * - ******************************************************************************/ -static long -drvMsg_MoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct mbboRecord *)(pxact->prec))->rval); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_LoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct longoutRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_SoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct stringoutRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_SoRaw(pxact, parm) -msgXact *pxact; -void *parm; -{ - msgStrParm wrParm; - - wrParm.buf = ((struct stringoutRecord *)(pxact->prec))->val; - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -/****************************************************************************** - * - * The following functions are called from record support. - * They are used to initialize a record's DPVT (xact structure) for - * processing by the message driver later when the record is processed. - * - ******************************************************************************/ -/****************************************************************************** - * - * Init record routine for AI - * - ******************************************************************************/ -long -drvMsg_initAi(pai) -struct aiRecord *pai; -{ - char message[100]; - long status; - - pai->dpvt = drvMsg_genXact(((struct msgDset *)(pai->dset))->pparmBlock, &(pai->inp), pai); - - if (pai->dpvt != NULL) - { - status = drvMsg_checkParm(pai, "AI"); - if (status == 0) - drvMsg_initCallback(pai); /* Init for async record completion callback */ - else - pai->pact = 1; /* mark so is never scanned */ - - return(status); - } - pai->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for AO - * - ******************************************************************************/ -long -drvMsg_initAo(pao) -struct aoRecord *pao; -{ - long status; - - pao->dpvt = drvMsg_genXact(((struct msgDset *)(pao->dset))->pparmBlock, &(pao->out), pao); - - if (pao->dpvt != NULL) - { - status = drvMsg_checkParm(pao, "AO"); - if (status == 0) - { - drvMsg_initCallback(pao); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pao->pact = 1; /* mark so is never scanned */ - - return(status); - } - pao->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for BI - * - ******************************************************************************/ -long -drvMsg_initBi(pbi) -struct biRecord *pbi; -{ - char message[100]; - long status; - - pbi->dpvt = drvMsg_genXact(((struct msgDset *)(pbi->dset))->pparmBlock, &(pbi->inp), pbi); - - if (pbi->dpvt != NULL) - { - status = drvMsg_checkParm(pbi, "BI"); - if (status == 0) - drvMsg_initCallback(pbi); /* Init for async record completion callback */ - else - pbi->pact = 1; /* mark so is never scanned */ - - return(status); - } - pbi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for BO - * - ******************************************************************************/ -long -drvMsg_initBo(pbo) -struct boRecord *pbo; -{ - long status; - - pbo->dpvt = drvMsg_genXact(((struct msgDset *)(pbo->dset))->pparmBlock, &(pbo->out), pbo); - - if (pbo->dpvt != NULL) - { - status = drvMsg_checkParm(pbo, "BO"); - if (status == 0) - { - drvMsg_initCallback(pbo); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pbo->pact = 1; /* mark so is never scanned */ - - return(status); - } - pbo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for MI - * - ******************************************************************************/ -long -drvMsg_initMi(pmi) -struct mbbiRecord *pmi; -{ - char message[100]; - long status; - - pmi->dpvt = drvMsg_genXact(((struct msgDset *)(pmi->dset))->pparmBlock, &(pmi->inp), pmi); - - if (pmi->dpvt != NULL) - { - status = drvMsg_checkParm(pmi, "MBBI"); - if (status == 0) - drvMsg_initCallback(pmi); /* Init for async record completion callback */ - else - pmi->pact = 1; /* mark so is never scanned */ - - return(status); - } - pmi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for MO - * - ******************************************************************************/ -long -drvMsg_initMo(pmo) -struct mbboRecord *pmo; -{ - long status; - - pmo->dpvt = drvMsg_genXact(((struct msgDset *)(pmo->dset))->pparmBlock, &(pmo->out), pmo); - - if (pmo->dpvt != NULL) - { - status = drvMsg_checkParm(pmo, "MBBO"); - if (status == 0) - { - drvMsg_initCallback(pmo); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pmo->pact = 1; /* mark so is never scanned */ - - return(status); - } - pmo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for LI - * - ******************************************************************************/ -long -drvMsg_initLi(pli) -struct longinRecord *pli; -{ - char message[100]; - long status; - - pli->dpvt = drvMsg_genXact(((struct msgDset *)(pli->dset))->pparmBlock, &(pli->inp), pli); - - if (pli->dpvt != NULL) - { - status = drvMsg_checkParm(pli, "LI"); - if (status == 0) - drvMsg_initCallback(pli); /* Init for async record completion callback */ - else - pli->pact = 1; /* mark so is never scanned */ - - return(status); - } - pli->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * init record routine for LO - * - ******************************************************************************/ -long -drvMsg_initLo(plo) -struct longoutRecord *plo; -{ - char message[100]; - long status; - - plo->dpvt = drvMsg_genXact(((struct msgDset *)(plo->dset))->pparmBlock, &(plo->out), plo); - - if (plo->dpvt != NULL) - { - status = drvMsg_checkParm(plo, "LO"); - if (status == 0) - drvMsg_initCallback(plo); /* Init for async record completion callback */ - else - plo->pact = 1; /* mark so is never scanned */ - - return(status); - } - plo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for SI - * - ******************************************************************************/ -long -drvMsg_initSi(psi) -struct stringinRecord *psi; -{ - char message[100]; - long status; - - psi->dpvt = drvMsg_genXact(((struct msgDset *)(psi->dset))->pparmBlock, &(psi->inp), psi); - - if (psi->dpvt != NULL) - { - status = drvMsg_checkParm(psi, "SI"); - if (status == 0) - drvMsg_initCallback(psi); /* Init for async record completion callback */ - else - psi->pact = 1; /* mark so is never scanned */ - - return(status); - } - psi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * init record routine for SO - * - ******************************************************************************/ -long -drvMsg_initSo(pso) -struct stringoutRecord *pso; -{ - char message[100]; - long status; - - pso->dpvt = drvMsg_genXact(((struct msgDset *)(pso->dset))->pparmBlock, &(pso->out), pso); - - if (pso->dpvt != NULL) - { - status = drvMsg_checkParm(pso, "SI"); - if (status == 0) - drvMsg_initCallback(pso); /* Init for async record completion callback */ - else - pso->pact = 1; /* mark so is never scanned */ - - return(status); - } - pso->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for WF - * - ******************************************************************************/ -long -drvMsg_initWf(pwf) -struct waveformRecord *pwf; -{ - char message[100]; - long status; - - pwf->dpvt = drvMsg_genXact(((struct msgDset *)(pwf->dset))->pparmBlock, &(pwf->inp), pwf); - - if (pwf->dpvt != NULL) - { - status = drvMsg_checkParm(pwf, "WAVEFORM"); - if (status == 0) - drvMsg_initCallback(pwf); /* Init for async record completion callback */ - else - pwf->pact = 1; /* mark so is never scanned */ - - return(status); - } - pwf->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * These functions are called by record support. - * - * Service routines to process a input records. - * - ******************************************************************************/ -long -drvMsg_procAi(pai) -struct aiRecord *pai; -{ - return(drvMsg_proc(pai, 2)); /* no conversion */ -} -long -drvMsg_procBi(pbi) -struct biRecord *pbi; -{ - return(drvMsg_proc(pbi, 0)); /* convert RVAL to VAL */ -} -long -drvMsg_procMi(pmi) -struct mbbiRecord *pmi; -{ - return(drvMsg_proc(pmi, 0)); /* convert RVAL to VAL */ -} -long -drvMsg_procLi(pli) -struct longinRecord *pli; -{ - return(drvMsg_proc(pli, 2)); /* no conversion */ -} -long -drvMsg_procSi(psi) -struct stringinRecord *psi; -{ - return(drvMsg_proc(psi, 2)); /* no conversion */ -} -long -drvMsg_procWf(pwf) -struct waveformRecord *pwf; -{ - return(drvMsg_proc(pwf, 2)); /* no conversion */ -} - -/****************************************************************************** - * - * These functions are called by record support. - * - * Service routine to process output records. - * - * It does not make sense to return a conversion code to record support from - * processing an output record. - * - ******************************************************************************/ -long -drvMsg_procAo(pao) -struct aoRecord *pao; -{ - return(drvMsg_proc(pao, 0)); -} -long -drvMsg_procBo(pbo) -struct boRecord *pbo; -{ - return(drvMsg_proc(pbo, 0)); -} -long -drvMsg_procMo(pmo) -struct mbboRecord *pmo; -{ - return(drvMsg_proc(pmo, 0)); -} -long -drvMsg_procLo(plo) -struct longoutRecord *plo; -{ - return(drvMsg_proc(plo, 0)); -} -long -drvMsg_procSo(pso) -struct stringoutRecord *pso; -{ - return(drvMsg_proc(pso, 0)); -} - -/****************************************************************************** - * - * Generic service routine to process a record. - * - ******************************************************************************/ - -/* - * BUG -- I should probably figure out the return code from the conversion - * routine. Not from a hard-coded value passed in from above. - */ - -long -drvMsg_proc(prec, ret) -struct dbCommon *prec; /* record to process */ -int ret; /* If all goes well, return this value */ -{ - if (prec->pact) /* if already actively processing, finish up */ - { - if (((msgXact *)(prec->dpvt))->status != XACT_OK) - { /* something went wrong during I/O processing */ - if (msgDebug) - printf("Setting an alarm on record %s\n", prec->name); - - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - } - else - if (ret == 2) - prec->udf = FALSE; /* Set only if I return 2 (I filled in VAL) */ - - return(ret); - } - /* Not already actively processing, start things going */ - - prec->pact = TRUE; - if (drvMsg_qXact(prec->dpvt, prec->prio) == ERROR) - printf("Error during drvMsg_qXact\n"); - - return(ret); -} diff --git a/src/drv/drvMvme162.c b/src/drv/drvMvme162.c deleted file mode 100644 index 94ee96446..000000000 --- a/src/drv/drvMvme162.c +++ /dev/null @@ -1,683 +0,0 @@ -/* base/src/drv $Id$ */ - -/* Author: John Winans - * Date: 06-28-93 - * - * 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 -#include -#include -#include -#include -#include - -#include - -#include -#include "drvGpib.h" - -struct IB162Link { - struct ibLink ibLink; - SEM_ID IOsem; - int IrqLevel; - int IrqVector; - Mvme162LinkStruct *pMvme162Link; -}; - -static struct IB162Link *pIB162[MVME162_NUM_LINKS*4]; -static int linkTask(struct ibLink *plink); -int mv167Debug = 0; - -/****************************************************************************** - * - * IRQ handler that is invoked when the default IRQ vector is generated - * from the MVME162 board. - * - ******************************************************************************/ -/* BUG have to add new extended IRQ handshake code in here */ -static void my162Handler(Mvme162LinkStruct *pMvme162) -{ - if (semGive(*(SEM_ID*)(pMvme162->pIrqParm)) != OK) - { - logMsg("my162Handler(0x%08.8X) semGive failed!!!!!\n", *(SEM_ID*)(pMvme162->pIrqParm)); - } - pMvme162->IrqHandshake = 0; /* Clear the IRQ status */ - return; -} -/****************************************************************************** - * - * Initialize the specified GPIB link number for future use. - * - * Should only be called by GPIB library code. - ******************************************************************************/ -long -drv162IB_InitLink(int link) -{ - int j; - - link -= MVME162_LINK_NUM_BASE; - - if ((link < 0) || (link >= MVME162_NUM_LINKS*4)) - return(-1); - - if (pIB162[link] == NULL) - { - /* Allocate the memory for the link descriptor. */ - pIB162[link] = malloc(sizeof(struct IB162Link)); - if (pIB162[link] == NULL) - return(-1); - - pIB162[link]->ibLink.linkType = GPIB_IO; - pIB162[link]->ibLink.linkId = link; - pIB162[link]->ibLink.bug = -1; - pIB162[link]->ibLink.linkEventSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY); - lstInit(&pIB162[link]->ibLink.hiPriList); - pIB162[link]->ibLink.hiPriSem = semBCreate(SEM_Q_FIFO, SEM_FULL); - lstInit(&pIB162[link]->ibLink.loPriList); - pIB162[link]->ibLink.loPriSem = semBCreate(SEM_Q_FIFO, SEM_FULL); - pIB162[link]->ibLink.srqIntFlag = 0; - - for (j=0; jibLink.srqHandler[j] = NULL; - pIB162[link]->ibLink.srqParm[j] = NULL; - pIB162[link]->ibLink.deviceStatus[j] = 0; - pIB162[link]->ibLink.pollInhibit[j] = 0; - } - - pIB162[link]->IOsem = semBCreate(SEM_Q_FIFO, SEM_EMPTY); - if (pIB162[link]->IOsem == NULL) - { - printf("drv162IB_InitLink(%d) IOsem creation failed\n", link); - return(-1); - } - printf("IOsem is %08.8X\n", pIB162[link]->IOsem); - - /* BUG Should be using sysBusToLocal() in here */ - j = link>>2; - - pIB162[link]->pMvme162Link = (Mvme162LinkStruct *)(MVME162_EXT_OFF+(j*MVME162_EXT_SIZE)); - pIB162[link]->IrqLevel = MVME162_IRQ_LEVEL; - pIB162[link]->IrqVector = MVME162_IVEC_BASE+j; - - printf("drvMvme162_InitLink(%d) at 0x%08.8X - 0x%08.8X\n", link, pIB162[link]->pMvme162Link, &(pIB162[link]->pMvme162Link->pIrqParm)); - - if (intConnect(INUM_TO_IVEC(MVME162_IVEC_BASE+j), my162Handler, pIB162[link]->pMvme162Link) != OK) - { - printf("drv162IB_InitLink(%d) intConnect() failed\n", link); - return(-1); - } - sysIntEnable(MVME162_IRQ_LEVEL); - - { /* Send a message out to do GPIB link initialization */ - CommandStruct cmd; - Mvme162GpibParmStruct parm; - - cmd.Command = MVME162_GPIB_ALLINIT; - cmd.pOutput = NULL; - cmd.pInput = NULL; - parm.OutLength = 0; - parm.InLength = 0; - parm.Address = 0; - parm.Time = 0; - - sysLocalToBusAdrs(VME_AM_EXT_SUP_DATA, &parm, &cmd.pParms); - - cmd.IrqLevel = pIB162[link]->IrqLevel; - cmd.IrqVector = pIB162[link]->IrqVector; - cmd.pIrqParm = &(pIB162[link]->IOsem); - - Send162(pIB162[link]->pMvme162Link, &cmd); - printf("init() Ready to take semaphore\n"); - semTake(pIB162[link]->IOsem, WAIT_FOREVER); - printf("Got Semaphore, status = %08.8X\n", parm.Status); - } - /* Spawn the link task */ - if (taskSpawn("162IB", GPIBLINK_PRI, GPIBLINK_OPT, GPIBLINK_STACK, linkTask, &pIB162[link]->ibLink) == ERROR) - { - printf("drv162IB_InitLink(%d): can't start link task\n", link); - return(-1); - } - } - - - return(0); -} -/****************************************************************************** - * - * Return the address of an iblink structure. - * - * Should only be called by GPIB library code. - ******************************************************************************/ -long -drv162IB_GetLink(int link, struct ibLink **pplink) -{ - link -= MVME162_LINK_NUM_BASE; - - if(mv167Debug) - printf("drvMvme162_GetLink(%d, 0x%08.8X)\n", link, pplink); - - if ((link < 0) || (link >= MVME162_NUM_LINKS*4)) - return(-1); - - *pplink = &(pIB162[link]->ibLink); - return(0); -} -/****************************************************************************** - * - * This allows a device support module to register an SRQ event handler. - * - * It is used to specify a function to call when an SRQ event is detected - * on the specified link and device. When the SRQ handler is called, it is - * passed the requested parm and the poll-status from the gpib device. - * - ******************************************************************************/ -long -drv162IB_RegisterSrq(struct ibLink *pibLink, int device, int (*handler)(), void *parm) -{ - if(mv167Debug) - printf("registerSrqCallback(%08.8X, %d, 0x%08.8X, %08.8X)\n", pibLink, device, handler, parm); - - pibLink->srqHandler[device] = handler; - pibLink->srqParm[device] = parm; - return(0); -} -/****************************************************************************** - * - * - * Should only be called by GPIB library code. - ******************************************************************************/ -long -drv162IB_QueueReq(struct dpvtGpibHead *pGpibHead, int prio) -{ - if(mv167Debug) - printf("drv162IB_QueueReq()\n"); - - if (pGpibHead->pibLink == NULL) - { - printf("drv162IB_QueueReq(%08.8X, %d): dpvt->pibLink=NULL!\n", pGpibHead, prio); - return(-1); - } - - switch (prio) { - case IB_Q_LOW: /* low priority transaction request */ - semTake(pGpibHead->pibLink->loPriSem, WAIT_FOREVER); - lstAdd(&(pGpibHead->pibLink->loPriList), pGpibHead); - semGive(pGpibHead->pibLink->loPriSem); - semGive(pGpibHead->pibLink->linkEventSem); - break; - case IB_Q_HIGH: /* high priority transaction request */ - semTake(pGpibHead->pibLink->hiPriSem, WAIT_FOREVER); - lstAdd(&(pGpibHead->pibLink->hiPriList), pGpibHead); - semGive(pGpibHead->pibLink->hiPriSem); - semGive(pGpibHead->pibLink->linkEventSem); - break; - default: /* invalid priority */ - printf("invalid priority requested in call to drv162IB_QueueReq(%08.8X, %d)\n", pGpibHead, prio); - return(-1); - } - if (mv167Debug) - printf("drv162IB_QueueReq(%d, 0x%08.8X, %d): xact queued\n", pGpibHead, prio); - return(0); -} - -/****************************************************************************** - * - * At the time this function is started as its own task, the linked list - * structures will have been created and initialized. - * - * This function is spawned as a task for each GPIB bus present in the - * system. That is one for each Ni card port, and one for each Bit Bus - * bug that contains a GPIB port on it. - * - * All global data areas referenced by this task are limited to the non-port - * specific items (no niLink[] references allowed.) so that the same task - * can operate all forms of GPIB busses. - * - ******************************************************************************/ -static int linkTask(struct ibLink *plink) -{ - struct dpvtGpibHead *pnode; - int working; - - if (mv167Debug) - printf("IB162 link task started for link link %d\n", plink->linkId); - - working = 1; /* check queues for work the first time */ - while (1) - { - if (!working) - { -#if 0 - if (ibSrqLock == 0) - { - /* Enable SRQ interrupts while waiting for an event */ - srqIntEnable(plink->linkType, plink->linkId, plink->bug); - } -#endif - /* wait for an event associated with this GPIB link */ - semTake(plink->linkEventSem, WAIT_FOREVER); -#if 0 - /* Disable SRQ interrupts while processing an event */ - srqIntDisable(plink->linkType, plink->linkId, plink->bug); -#endif - if (mv167Debug) - { - printf("IB152LinkTask(%d, %d): got an event\n", plink->linkType, plink->linkId); - } - } - working = 0; /* Assume will do nothing */ -#if 0 - if ((plink->srqIntFlag) && (ibSrqLock == 0)) - { - if (mv167Debug || ibSrqDebug) - printf("IB152LinkTask(%d, %d): srqIntFlag set.\n", plink->linkType, plink->linkId); - - /* Read the SRQ message buffer and callback the handler for each - device. */ - - printf("IB152LinkTask(%d, %d): dispatching srq handler for device %d\n", plink->linkType, plink->linkId, ringData.device); - plink->deviceStatus[ringData.device] = (*(plink->srqHandler)[ringData.device])(plink->srqParm[ringData.device], ringData.status); - working=1; - } -#endif - /* - * see if the Hi priority queue has anything in it - */ - semTake(plink->hiPriSem, WAIT_FOREVER); - - if ((pnode = (struct dpvtGpibHead *)lstFirst(&(plink->hiPriList))) != NULL) - { - while (plink->deviceStatus[pnode->device] == BUSY) - if ((pnode = (struct dpvtGpibHead *)lstNext(pnode)) == NULL) - break; - } - if (pnode != NULL) - lstDelete(&(plink->hiPriList), pnode); - - semGive(plink->hiPriSem); - - if (pnode != NULL) - { - if (mv167Debug) - printf("IB152LinkTask(%d, %d): got Hi Pri xact, pnode= 0x%08.8X\n", plink->linkType, plink->linkId, pnode); - - plink->deviceStatus[pnode->device] = (*(pnode->workStart))(pnode); - working=1; - } - else - { - semTake(plink->loPriSem, WAIT_FOREVER); - if ((pnode = (struct dpvtGpibHead *)lstFirst(&(plink->loPriList))) != NULL) - { - while (plink->deviceStatus[pnode->device] == BUSY) - if ((pnode = (struct dpvtGpibHead *)lstNext(pnode)) == NULL) - break; - } - if (pnode != NULL) - lstDelete(&(plink->loPriList), pnode); - - semGive(plink->loPriSem); - - if (pnode != NULL) - { - if(mv167Debug) - printf("IB152LinkTask(%d, %d): got Lo Pri xact, pnode= 0x%08.8X\n", plink->linkType, plink->linkId, pnode); - plink->deviceStatus[pnode->device] = (*(pnode->workStart))(pnode); - working=1; - } - } - } -} -#if 0 -/****************************************************************************** - * - * The following are functions used to take care of serial polling. They - * are called from the ibLinkTask. - * - ******************************************************************************/ -/****************************************************************************** - * - * Pollib sends out an SRQ poll and returns the poll response. - * If there is an error during polling (timeout), the value -1 is returned. - * - ******************************************************************************/ -static int -pollIb(plink, gpibAddr, verbose, time) -struct ibLink *plink; -int gpibAddr; -int verbose; /* set to 1 if should log any errors */ -int time; -{ - char pollCmd[4]; - unsigned char pollResult[3]; - int status; - int tsSave; - - if(verbose && (mv167Debug || ibSrqDebug)) - printf("pollIb(0x%08.8X, %d, %d, %d)\n", plink, gpibAddr, verbose, time); - - tsSave = timeoutSquelch; - timeoutSquelch = !verbose; /* keep the I/O routines quiet if desired */ - - /* raw-read back the response from the instrument */ - if (readIb(plink, gpibAddr, pollResult, sizeof(pollResult), time) == ERROR) - { - if(verbose) - printf("pollIb(%d, %d): data read error\n", plink->linkId, gpibAddr); - status = ERROR; - } - else - { - status = pollResult[0]; - if (mv167Debug || ibSrqDebug) - { - printf("pollIb(%d, %d): poll status = 0x%02.2X\n", plink->linkId, gpibAddr, status); - } - } - - timeoutSquelch = tsSave; /* return I/O error logging to normal */ - return(status); -} -/****************************************************************************** - * - * Functions used to enable and disable SRQ interrupts. These only make - * sense on a Ni based link, so they are ignored in the BitBus case. - * (In the BitBus, SRQ status is passed back via query. So there is no - * asynchronous interupt associated with it.) - * - * The interrupts referred to here are the actual VME bus interrupts that are - * generated by the GPIB interface when it sees the SRQ line go high. - * - ******************************************************************************/ -static int -srqIntEnable(linkType, link, bug) -int linkType; -int link; -{ - if (linkType == GPIB_IO) - return(niSrqIntEnable(link)); - - if (linkType == BBGPIB_IO) - return(OK); /* Bit Bus does not use interrupts for SRQ handeling */ - - return(ERROR); /* Invalid link type specified on the call */ -} - -static int -srqIntDisable(linkType, link, bug) -int linkType; -int link; -{ - if (linkType == GPIB_IO) - return(niSrqIntDisable(link)); - - if (linkType == BBGPIB_IO) - return(0); /* Bit Bus does not use interrupts for SRQ handeling */ - - return(ERROR); /* Invlaid link type specified on the call */ -} -/**************************************************************************** - * - * The following routines are the user-callable entry points to the GPIB - * driver. - * - ****************************************************************************/ -/****************************************************************************** - * - * A device support module may call this function to request that the GPIB - * driver NEVER poll a given device. - * - * Devices are polled when an SRQ event is present on the GPIB link. Some - * devices are too dumb to deal with being polled. - * - * This is NOT a static function, because it must be invoked from the startup - * script BEFORE iocInit is called. - * - * BUG -- - * This could change if we decide to poll them during the second call to init() - * when epics 3.3 is available. - * - ******************************************************************************/ -/* static */ int -srqPollInhibit(linkType, link, bug, gpibAddr) -int linkType; /* link type (defined in link.h) */ -int link; /* the link number the handler is related to */ -int bug; /* the bug node address if on a bitbus link */ -int gpibAddr; /* the device address the handler is for */ -{ - if (mv167Debug || ibSrqDebug) - printf("srqPollInhibit(%d, %d, %d, %d): called\n", linkType, link, bug, gpibAddr); - - if (linkType == GPIB_IO) - { - return(niSrqPollInhibit(link, gpibAddr)); - } - - if (linkType == BBGPIB_IO) - { - return(bbSrqPollInhibit(link, bug, gpibAddr)); - } - - printf("drvGpib: srqPollInhibit(%d, %d, %d, %d): invalid link type specified\n", linkType, link, bug, gpibAddr); - return(ERROR); -} -/****************************************************************************** - * - * Allow users to operate the internal functions of the driver. - * - * This can be fatal to the driver... make sure you know what you are doing! - * - ******************************************************************************/ -static int -ioctlIb(linkType, link, bug, cmd, v, p) -int linkType; /* link type (defined in link.h) */ -int link; /* the link number to use */ -int bug; /* node number if is a bitbus -> gpib link */ -int cmd; -int v; -caddr_t p; -{ - int stat; - - if (linkType == GPIB_IO) - return(niGpibIoctl(link, cmd, v, p));/* link checked in niGpibIoctl */ - - if (linkType == BBGPIB_IO) - return(bbGpibIoctl(link, bug, cmd, v, p));/* link checked in bbGpibIoctl */ - - if (mv167Debug || bbmv167Debug) - printf("ioctlIb(%d, %d, %d, %d, %08.8X, %08.8X): invalid link type\n", linkType, link, bug, cmd, v, p); - - return(ERROR); -} -#endif - -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ - -/* BUG -- this has to be converted into a FIFO list insertion!!! */ -static int Send162(Mvme162LinkStruct *pMvme162Link, CommandStruct *pCmd) -{ - Mvme162GpibParmStruct *pParms; - - if(mv167Debug>20) - { - printf("Send162() sending command:\n"); - printf(" Command %d\n", pCmd->Command); - printf(" pParms 0x%08.8X\n", pCmd->pParms); - printf(" pOutput 0x%08.8X\n", pCmd->pOutput); - printf(" pInput 0x%08.8X\n", pCmd->pInput); - printf(" IrqLevel %d\n", pCmd->IrqLevel); - printf(" IrqVector 0x%02.2X\n", (unsigned char)(pCmd->IrqVector)); - printf(" pIrqParm 0x%08.8X\n", pCmd->pIrqParm); - - if (pCmd->pParms != NULL) - { - /* vxWorks is a pain in the bung */ - pParms = (Mvme162GpibParmStruct *)((unsigned long)(pCmd->pParms) - ((unsigned long)(0x00800000))); - printf(" parms on command:\n"); - printf(" OutLength %d\n", pParms->OutLength); - printf(" InLength %d\n", pParms->InLength); - printf(" Address %d\n", pParms->Address); - printf(" Time %d\n", pParms->Time); - } - } - - /* Lock the command queue */ - while(!vxTas(&pMvme162Link->DRListLock)); - - /* Insert the command */ - pCmd->pNextCommand = pMvme162Link->pDRList; - sysLocalToBusAdrs(VME_AM_EXT_SUP_DATA, pCmd, &pMvme162Link->pDRList); - - /* unlock the command queue */ - pMvme162Link->DRListLock = 0; - - return(0); -} -/****************************************************************************** - * - * A device support callable entry point used to write data to GPIB devices. - * - * This function returns the number of bytes written out. - * - ******************************************************************************/ -int -drv162IB_write(struct ibLink *pibLink, int gpibAddr, char *data, int length, int time) -{ - CommandStruct cmd; - Mvme162GpibParmStruct parm; - - if(mv167Debug) - printf("drv162IB_write(%08.8X, %d, 0x%08.8X, %d, %d)\n", pibLink, gpibAddr, data, length, time); - - cmd.Command = MVME162_GPIB_WRITE_X; - parm.OutLength = length; - parm.InLength = 0; - parm.Address = gpibAddr; - parm.Time = time; - - sysLocalToBusAdrs(VME_AM_EXT_SUP_DATA, data, &cmd.pOutput); - sysLocalToBusAdrs(VME_AM_EXT_SUP_DATA, &parm, &cmd.pParms); - - cmd.IrqLevel = pIB162[pibLink->linkId]->IrqLevel; - cmd.IrqVector = pIB162[pibLink->linkId]->IrqVector; - cmd.pIrqParm = &(pIB162[pibLink->linkId]->IOsem); - - Send162(pIB162[pibLink->linkId]->pMvme162Link, &cmd); - semTake(pIB162[pibLink->linkId]->IOsem, WAIT_FOREVER); - - return(parm.Status); -} - -/****************************************************************************** - * - * A device support callable entry point used to read data from GPIB devices. - * - * This function returns the number of bytes read from the device, or ERROR - * if the read operation failed. - * - ******************************************************************************/ -int -drv162IB_read(struct ibLink *pibLink, int gpibAddr, char *data, int length, int time) -{ - CommandStruct cmd; - Mvme162GpibParmStruct parm; - - if(mv167Debug) - printf("readIb(%08.8X, %d, 0x%08.8X, %d)\n", pibLink, gpibAddr, data, length); - - cmd.Command = MVME162_GPIB_READ_X; - parm.OutLength = 0; - parm.InLength = length; - parm.Address = gpibAddr; - parm.Time = time; - - sysLocalToBusAdrs(VME_AM_EXT_SUP_DATA, data, &cmd.pInput); - sysLocalToBusAdrs(VME_AM_EXT_SUP_DATA, &parm, &cmd.pParms); - - cmd.IrqLevel = pIB162[pibLink->linkId]->IrqLevel; - cmd.IrqVector = pIB162[pibLink->linkId]->IrqVector; - cmd.pIrqParm = &(pIB162[pibLink->linkId]->IOsem); - - Send162(pIB162[pibLink->linkId]->pMvme162Link, &cmd); - semTake(pIB162[pibLink->linkId]->IOsem, WAIT_FOREVER); - - return(parm.Status); -} -#if 0 - -/****************************************************************************** - * - * A device support callable entry point that is used to write commands - * to GPIB devices. (this is the same as a regular write except that the - * ATN line is held high during the write. - * - * This function returns the number of bytes written out. - * - ******************************************************************************/ -static int -writeIbCmd(pibLink, data, length) -struct ibLink *pibLink; -char *data; /* the data buffer to write out */ -int length; /* number of bytes to write out from the data buffer */ -{ - - if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO))) - printf("writeIbCmd(%08.8X, %08.8X, %d)\n", pibLink, data, length); - - if (pibLink->linkType == GPIB_IO) - { - /* raw-write the data */ - return(niGpibCmd(pibLink->linkId, data, length)); - } - if (pibLink->linkType == BBGPIB_IO) - { - /* raw-write the data */ - return(bbGpibCmd(pibLink, data, length)); - } - return(ERROR); -} -#endif diff --git a/src/drv/drvMz8310.c b/src/drv/drvMz8310.c deleted file mode 100644 index d526c0837..000000000 --- a/src/drv/drvMz8310.c +++ /dev/null @@ -1,628 +0,0 @@ - -/* drvMz8310.c */ -/* base/src/drv $Id$ */ -/* - * Routines specific to the MZ8310. Low level routines for the AMD STC in - * stc_driver.c - * Author: Jeff Hill - * Date: Feb 1989 - * - * 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 History - * joh 02-20-89 Init Release - * joh 04-28-89 Added read back - * joh 11-17-89 added readback to io report - * joh 12-10-89 DB defaults the internal/external clock - * parameter to 0 or external clock. This was the opposite - * of what this driver expected. Fix was made here. - * joh 07-06-90 print channel number with channel value in IO report - * joh 02-25-91 made ext/int clk IO report more readable - * joh 09-05-91 converted to v5 vxWorks - * bg 09-15-91 added sysBustoLocalAdrs() for addressing - * bg 03-10-92 added the argument, level, to mz310_io_report(). - * bg 04-27-92 added rebootHookAdd and mz8310_reset so ioc will - * not hang on ctl X reboot. - * joh 04-28-92 added arguments to MACROS which had hidden - * parameters - * bg 06-25-92 combined drvMz8310.c and mz8310_driver.c - * bg 06-26-92 Added level to mz8310_io_report. - * joh 08-05-92 callable interface now conforms with epics standard - * mgb 08-04-93 Removed V5/V4 and EPICS_V2 conditionals - * joh 08-24-93 Include drvStc.h and ANSI C upgrade - * joh 09-29-93 removed superfluous error message - */ - -/* drvMz8310.c - Driver Support Routines for Mz8310 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#define MZ8310CHIPSIZE 0x20 -#define MZ8310SIZE 0x00000100 -#define MZ8310BASE(CARD) (shortaddr+tm_addrs[MZ8310]+(CARD)*MZ8310SIZE) - -#define MZ8310DATA 0 -#define MZ8310CMD 3 -#define MZ8310CHANONCHIP 5 -#define MZ8310CHIPCOUNT 2 -#define MZ8310CHANCNT (MZ8310CHANONCHIP*MZ8310CHIPCOUNT) - -/* - NOTE: The mizar draftsman has labeled the chip at the - highest address as one and the chip at the lowest address - 2 so I am reversing the chip number below. -*/ -#define CHIP_REVERSE(CHIP) (MZ8310CHIPCOUNT-1-(CHIP)) -#define CHIP_ADDR(CARD,CHIP) (MZ8310BASE(CARD)+\ - (CHIP_REVERSE(CHIP)*MZ8310CHIPSIZE)) - -#define MZ8310_CMD_ADDR(CARD,CHIP)\ -((volatile unsigned char *) CHIP_ADDR(CARD,CHIP) + MZ8310CMD) -#define MZ8310_DATA_ADDR(CARD,CHIP)\ -((volatile unsigned short *) CHIP_ADDR(CARD,CHIP) + MZ8310DATA) -#if 0 -#define MZ8310VECBASE(CARD,CHIP)\ -((volatile unsigned char *) CHIP_ADDR(CARD,CHIP) + 0x41) -#endif - -#define MZ8310VECSIZE (0x20) -#define MZ8310INTCNT 4 -#define MZ8310FIRSTINTCHAN 0 -#define MZ8310INTVEC(CARD,CHAN)\ -(MZ8310_INT_VEC_BASE + (CARD*MZ8310INTCNT) + mz8310_strap[CHAN].vec_num) - -#define MZ8310_INTERUPTABLE(CHAN) (mz8310_strap[CHAN].vec_addr) - -# define INT_TICKS 4.0e06 /* speed of F1 in Hz */ -# define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */ - - -struct mz8310_int_conf{ - void (*user_service)(); - int user_param; - unsigned int cnt; -}; - -struct mz8310_conf{ - char init; - FAST_LOCK lock; - struct mz8310_int_conf icf[MZ8310CHANCNT]; -}; - -struct mz8310_strap_info{ - unsigned char irq; /* the level at which the chan gen ints */ - unsigned char vec_num; /* really a vec offset-see MZ8310INTVEC */ - unsigned char vec_addr;/* offset from card base address */ -}; - -static volatile char *shortaddr; - -LOCAL struct mz8310_conf *mzconf; -LOCAL unsigned int mz8310_card_count; - -/* - only 4 unique interrupts per card but any channel can potentially - generate an interrupt depending on board strapping. - - NOTE: existence of vec addr tells the driver that that channel is - strapped for interrupts since the card can't be polled for this info. - - In the MIZAR 8310 Documentation: - - Designation vector reg offset - IRQA 0x41 - IRQB 0x61 - IRQC 0x81 - IRQD 0xa1 -*/ - -LOCAL struct mz8310_strap_info mz8310_strap[MZ8310CHANCNT] = -{ - { NULL, NULL, NULL }, /* channel 0 */ - { NULL, NULL, NULL }, /* channel 1 */ - { NULL, NULL, NULL }, /* channel 2 */ - { NULL, NULL, NULL }, /* channel 3 */ - { NULL, NULL, NULL }, /* channel 4 */ - { NULL, NULL, NULL }, /* channel 5 */ - { 1, 0, 0x41 }, /* channel 6 */ - { 3, 1, 0x61 }, /* channel 7 */ - { 5, 2, 0x81 }, /* channel 8 */ - { 6, 3, 0xa1 } /* channel 9 */ -}; - -/* forward reference. */ -LOCAL int mz8310_reset(void); -LOCAL mz8310Stat mz8310_io_report_card(unsigned card, int level); -LOCAL mz8310Stat mz8310_init_card(unsigned card); -LOCAL mz8310Stat mz8310_setup_int(unsigned card, unsigned channel); -LOCAL mz8310Stat mz8310_io_report(int level); -LOCAL mz8310Stat mz8310_init(void); -LOCAL mz8310Stat mz8310_read_test(int card, int channel); -LOCAL void mz8310_int_service(struct mz8310_int_conf *icf); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvMz8310={ - 2, - mz8310_io_report, - mz8310_init}; - - -/* - * mz8310_io_report() - */ -LOCAL mz8310Stat mz8310_io_report(int level) -{ - unsigned card; - - for(card=0; card= MZ8310CHANONCHIP * MZ8310CHIPCOUNT) - return S_dev_badSignalNumber; - - if(card>=mz8310_card_count) - return S_dev_badA16; - - if(!mzconf) - return S_dev_noDevice; - - FASTLOCK(&mzconf[card].lock); - - status = - stc_one_shot_read( - preset, - &iedge0, - &iedge1, - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - int_source); - if(status==STC_SUCCESS){ - ticks = *int_source ? INT_TICKS : EXT_TICKS; - *edge0_delay = iedge0 / ticks; - *edge1_delay = iedge1 / ticks; - } - - FASTUNLOCK(&mzconf[card].lock); - - return status; -} - - -/* - * mz8310_read_test() - */ -LOCAL mz8310Stat mz8310_read_test(int card, int channel) -{ - int preset; - double edge0_delay; - double edge1_delay; - int int_source; - mz8310Stat status; - static char *pclktype[] = {"external-clk", "internal-clk"}; - static char *ppresettype[] = {"preset-FALSE", "preset-TRUE "}; - - status = - mz8310_one_shot_read( - &preset, - &edge0_delay, - &edge1_delay, - card, - channel, - &int_source); - if(status==MZ8310_SUCCESS){ - printf( "\tChannel %d %s delay=%f width=%f %s\n", - channel, - ppresettype[preset&1], - edge0_delay, - edge1_delay, - pclktype[int_source&1]); - if(mzconf[card].icf[channel].cnt) - printf("\tChannel %d Interrupt count=%u\n", - channel, - mzconf[card].icf[channel].cnt); - } - - return status; -} - - -/* - * mz8310_one_shot() - */ -mz8310Stat mz8310_one_shot( -int preset, /* TRUE or COMPLEMENT logic */ -double edge0_delay, /* sec */ -double edge1_delay, /* set */ -int card, /* 0 through ... */ -int channel, /* 0 through channels on a card */ -int int_source, /* (FALSE)External/ (TRUE)Internal source */ -void *event_rtn, /* subroutine to run on events */ -int event_rtn_param /* parameter to pass to above routine */ -) -{ - int chip = channel/MZ8310CHANONCHIP; - double ticks = int_source?INT_TICKS:EXT_TICKS; - mz8310Stat status; - - if(channel >= MZ8310CHANONCHIP * MZ8310CHIPCOUNT) - return S_dev_badSignalNumber; - - if(card>=mz8310_card_count) - return S_dev_badA16; - - if(!mzconf) - return S_dev_noDevice; - - /* dont overflow unsigned short in STC */ - if(edge0_delay >= 0xffff/ticks) - return S_dev_highValue; - if(edge1_delay >= 0xffff/ticks) - return S_dev_highValue; - if(edge0_delay < 0.0) - return S_dev_lowValue; - if(edge1_delay < 0.0) - return S_dev_lowValue; - - FASTLOCK(&mzconf[card].lock); - - /* Enable calling of user routine */ - if(MZ8310_INTERUPTABLE(channel)){ - mzconf[card].icf[channel].user_service = event_rtn; - mzconf[card].icf[channel].user_param = event_rtn_param; - } - - status = - stc_one_shot( - preset, - (unsigned short) (edge0_delay * ticks), - (unsigned short) (edge1_delay * ticks), - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - int_source); - - FASTUNLOCK(&mzconf[card].lock); - - return status; - -} - - - -/* - * mz8310_int_service() - */ -LOCAL void mz8310_int_service(struct mz8310_int_conf *icf) -{ - icf->cnt++; - - if(icf->user_service) - (*icf->user_service)(icf->user_param); - - return; -} - -/* - * The following are provided for mz8310 access from the shell - */ - - -/* - * mz8310_cmd() - */ -int mz8310_cmd( -unsigned value, -unsigned card, -unsigned chip -) -{ - volatile unsigned char *cmd = MZ8310_CMD_ADDR(card,chip); - - *cmd = value; - - return *cmd; -} - - -/* - * mz8310_rdata() - */ -int mz8310_rdata(int card, int chip) -{ - volatile unsigned short *data = MZ8310_DATA_ADDR(card,chip); - - return *data; -} - - -/* - * mz8310_wdata() - */ -int mz8310_wdata( -unsigned value, -int card, -int chip -) -{ - volatile unsigned short *data = MZ8310_DATA_ADDR(card,chip); - - *data = value; - - return value; - -} - - - -/* - * mz8310_reset - */ -LOCAL int mz8310_reset(void) -{ - short card,channel,chip; - - for (card = 0; card < mz8310_card_count; card++){ - FASTLOCK(&mzconf[card].lock); - for ( channel = 0; channel < tm_num_channels[MZ8310]; channel++){ - if (mzconf[card].icf[channel].cnt){ - chip = channel/MZ8310CHANONCHIP; - - stc_one_shot( - 0, - 10, - 0, - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - 0); - } - } - FASTUNLOCK(&mzconf[card].lock); - } - - return OK; -} - - - diff --git a/src/drv/drvMz8310.h b/src/drv/drvMz8310.h deleted file mode 100644 index 865d1bb8c..000000000 --- a/src/drv/drvMz8310.h +++ /dev/null @@ -1,74 +0,0 @@ -/* drvMz8310.c */ -/* base/src/drv $Id$ */ -/* - * Routines specific to the MZ8310. Low level routines for the AMD STC in - * stc_driver.c - * Author: Jeff Hill - * Date: Feb 1989 - * - * 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 History - */ - - - - -#define MZ8310_SUCCESS 0 - -typedef long mz8310Stat; - -mz8310Stat mz8310_one_shot_read( -int *preset, /* TRUE or COMPLEMENT logic */ -double *edge0_delay, /* sec */ -double *edge1_delay, /* sec */ -int card, /* 0 through ... */ -int channel, /* 0 through channels on a card */ -int *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -mz8310Stat mz8310_one_shot( -int preset, /* TRUE or COMPLEMENT logic */ -double edge0_delay, /* sec */ -double edge1_delay, /* set */ -int card, /* 0 through ... */ -int channel, /* 0 through channels on a card */ -int int_source, /* (FALSE)External/ (TRUE)Internal source */ -void *event_rtn, /* subroutine to run on events */ -int event_rtn_param /* parameter to pass to above routine */ -); - -int mz8310_cmd( -unsigned value, -unsigned card, -unsigned chip -); - -int mz8310_rdata(int card, int chip); - -int mz8310_wdata( -unsigned value, -int card, -int chip -); - - diff --git a/src/drv/drvOms.c b/src/drv/drvOms.c deleted file mode 100644 index cede9ac96..000000000 --- a/src/drv/drvOms.c +++ /dev/null @@ -1,685 +0,0 @@ -/* drvOms.c */ -/* base/src/drv $Id$ */ -/* - * subroutines and tasks that are used to interface to the - * Oregon Micro Systems six axis stepper motor drivers - * - * Author: Bob Dalesio - * Date: 12-28-89 - * - * 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 02-07-90 lrd add command to read status - * .02 02-09-90 lrd removed the clamp on the MR command - * .03 03-22-90 lrd added the acceleration - * .04 04-12-90 lrd only allow one record to connect to each motor - * .05 04-28-90 lrd request motor data at 10 Hz. Needed delay to let - * motor start moving - * .06 04-30-90 lrd fix interrupt vectors for more than one motor - * .07 07-31-90 lrd lock the communication to the oms card for - * one user - * .08 08-01-90 lrd fix turn off of auxilary output when move is - * complete - * .09 08-01-90 lrd fix the initialization of the card to only - * enable the buffer full interrupt - * .10 10-23-90 lrd clamp the send value to something the motor - * driver can handle - * .11 11-13-90 lrd add intelligence in looking for an OMS card with - * an encoder - * .12 05-15-91 lrd add initialization of encoder and motor position - * .13 09-05-91 joh updated for v5 vxWorks - * .14 12-10-91 bg added sysBusToLocalAddrs(). Added - * compu_sm_driver.c. - * .15 03-10-92 bg Added level to io_report and gave - * compu_sm_io_report() the ability to print out - * contents of motor_data array if level > 1. - * .16 06-26-92 bg Combined drvOms.c with oms_driver.c - * .17 06-29-92 joh took file pointer arg out of io report - * .18 08-11-92 joh io report format cleanup - * .19 08-02-93 mrk Added call to taskwdInsert - * .20 08-05-93 jbk took out 200000 pulse limit - * .21 02-28-94 mrk Replaced itob by cvtLongToString - * .22 05-05-94 kornke Now supports VMEX-8 and VMEX-44E - * (8 axis s'motors and 4 encoded s'motors) - */ - -/* data requests are made from the oms_task at - * a rate of 10Hz when a motor is active - * post every .1 second or not moving - * requests are sent at 10Hz in oms_task - */ - -/* drvOms.c - Driver Support Routines for Oms */ -#include -#include -#include /* library for task support */ -#include -#include /* library for ring buffer support */ -#include -#include /* library to support sysBusToLocalAdrs. */ - -#include -#include -#include -#include -#include -#include - -#define OMS_INT_LEV 5 - -/* If any of the following does not exist replace it with #define <> NULL */ -static long report(); -static long init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvOms={ - 2, - report, - init}; - -static long report(level) - int level; -{ - oms_io_report(level); -} - - -static long init() -{ - int status; - oms_driver_init(); - return(0); -} - -/* - * a rate of 10Hz when a motor is active - * post every .1 second or not moving - * requests are sent at 10Hz in oms_task - */ - -/* addresses of all motors present */ -struct vmex_motor *oms_motor_present[MAX_OMS_CARDS]; -char encoder_present[MAX_OMS_CARDS]; - -static char *localaddr; /* Local address used to address cards. */ - -/* motor information */ -struct oms_motor oms_motor_array[MAX_OMS_CARDS][MAX_OMS_CHANNELS]; - -/* motor status - returned to the database library routines */ -struct motor_data motor_data_array[MAX_OMS_CARDS][MAX_OMS_CHANNELS]; - -char oms_motor_specifier[MAX_OMS_CHANNELS+1] = {'X','Y','Z','T','U','V'}; - -/* scan task parameters */ -LOCAL SEM_ID oms_wakeup; /* oms_task wakeup semaphore */ -LOCAL SEM_ID oms_send_sem; /* oms_task wakeup semaphore */ - -/* response task variables */ -LOCAL SEM_ID oms_resp_sem; /* wakeup semaphore for the resp task */ -LOCAL RING_ID oms_resp_q; /* queue of responses */ - -/* interrupt routine message buffers */ -int resp_inx[MAX_OMS_CARDS]; -char read_buffer[MAX_OMS_CARDS][34]; - -/* forward reference. */ -VOID oms_reset(); - - -oms_intr(card) -register short card; -{ - register struct vmex_motor *pmotor; - register int key; - register char inp_char; - register int *pinx; - - key = intLock(); - - /* pointer to this motor */ - if ((pmotor = oms_motor_present[card]) == 0){ - intUnlock(key); - return(0); - } - pinx = &resp_inx[card]; - - /* get the next character */ - if (pmotor->status & INPUT_BUFFER_FULL){ - - /* check for end of command */ - inp_char = pmotor->data; - if (((inp_char == 0xa) || (inp_char == 0xd)) && (*pinx > 0)){ - /* check if the encoder command caused an error */ - if (pmotor->status & (OMS_ENCODER | OMS_CMD_ERROR)) - encoder_present[card] = FALSE; - else encoder_present[card] = TRUE; - /* terminate and send the message */ - read_buffer[card][*pinx] = 0; - if (rngBufPut(oms_resp_q,read_buffer[card],OMS_MSG_SZ) - != OMS_MSG_SZ){ - logMsg("oms_resp_q full\n"); - }else{ - semGive (oms_resp_sem); - } - *pinx = 0; /* reset buffer */ - - /* save printable ascii characters */ - }else if ((inp_char >= 0x20) && (inp_char < 0x7f)){ - if (*pinx == 0){ - read_buffer[card][*pinx] = card; - *pinx += 1; - } - if (*pinx < OMS_MSG_SZ){ - read_buffer[card][*pinx] = inp_char; - *pinx += 1; - }else{ - logMsg("oms intr buffer full\n"); - } - } - } - intUnlock(key); - return(0); -} - -/* - * STEPPER MOTOR RESPONSE TASK - REMOVES RESPONSES FROM the INTERRUPT QUEUE - */ -short oms_channel[MAX_OMS_CARDS]; -short oms_state[MAX_OMS_CARDS]; -char off_msg[40]; -int oms_debug = 0; -int oms_compare = 3; -oms_resp_task() -{ - unsigned char resp[OMS_MSG_SZ*4]; - register struct motor_data *pmotor_data_array; - register struct oms_motor *poms_motor_array; - short *pchannel; - int (*psmcb_routine)(); - register short *pstate; - register short card,i; - int temp; - - FOREVER { - /* wait for somebody to wake us up */ - semTake (oms_resp_sem, WAIT_FOREVER); - /* process requests in the command ring buffer */ - while (rngBufGet(oms_resp_q,resp,OMS_MSG_SZ) == OMS_MSG_SZ){ - if (oms_debug) - printf("card: %d msg:%s\n",resp[0],&resp[1]); - /* get the card number and pointers to the state and channel */ - card = resp[0]; - pchannel = &oms_channel[card]; - pstate = &oms_state[card]; - pmotor_data_array = &motor_data_array[card][*pchannel]; - poms_motor_array = &oms_motor_array[card][*pchannel]; - - /* motor selection */ - if (resp[1] == 'A') - { - switch (resp[2]) - { - case 'X': - *pchannel = 0; - break; - case 'Y': - *pchannel = 1; - break; - case 'Z': - *pchannel = 2; - break; - case 'T': - *pchannel = 3; - break; - case 'U': - *pchannel = 4; - break; - case 'V': - *pchannel = 5; - break; - case 'R': - *pchannel = 6; - break; - case 'S': - *pchannel = 7; - break; - } - - *pstate = 0; - /* position readback */ - }else if (resp[1] == 'R'){ - if (resp[2] == 'E') *pstate = 1; - else if (resp[2] == 'P') *pstate = 2; - else if (resp[2] == 'A') *pstate = 3; - else *pstate = 0; - - /* convert encoder position */ - }else if (*pstate == 1){ - sscanf(&resp[1],"%d",&temp); - pmotor_data_array->encoder_position = temp; - *pstate = 0; - /* convert motor position */ - /* use the motor position for detecting end of motion because */ - /* all motors use this, not all motors have encoders */ - }else if (*pstate == 2){ - sscanf(&resp[1],"%d",&temp); - if ((pmotor_data_array->motor_position == temp) - && (poms_motor_array->active == TRUE)){ - poms_motor_array->stop_count++; - if (poms_motor_array->stop_count >= oms_compare) { - poms_motor_array->active = FALSE; - strcpy(off_msg,"AB\nAN\n"); - off_msg[1] = oms_motor_specifier[*pchannel]; - oms_send_msg(oms_motor_present[card],off_msg); - poms_motor_array->stop_count = 0; - } - - }else{ - pmotor_data_array->motor_position = temp; - poms_motor_array->stop_count = 0; - } - *pstate = 0; - - /* convert axis status */ - }else if (*pstate == 3){ - pmotor_data_array->ccw_limit = 0; - pmotor_data_array->cw_limit = 0; - if (resp[1] == 'P'){ - pmotor_data_array->direction = 0; - if (resp[3] == 'L'){ - pmotor_data_array->ccw_limit= 1; - } - }else{ - pmotor_data_array->direction = 1; - if (resp[3] == 'L'){ - pmotor_data_array->cw_limit = 1; - } - } - pmotor_data_array->moving = poms_motor_array->active; - *pstate = 0; - - /* post every .1 second or not moving */ - if ((poms_motor_array->update_count-- <= 0) - || (pmotor_data_array->moving == 0)){ - if (poms_motor_array->callback != 0){ - (int)psmcb_routine = poms_motor_array->callback; - (*psmcb_routine)(pmotor_data_array,poms_motor_array->callback_arg); - } - if (pmotor_data_array->moving){ - poms_motor_array->update_count = 2; - }else{ - poms_motor_array->update_count = 0; - } - } - /* reset state */ - }else{ - *pstate = 0; - } - } - } -} - -oms_task() -{ - register short motor_active; - register short card,channel; - char oms_msg[40]; - register struct vmex_motor *pmotor; - - while(1){ - semTake(oms_wakeup, WAIT_FOREVER); - motor_active = TRUE; - while (motor_active){ - motor_active = FALSE; - taskDelay(2); - for (channel = 0; channel < MAX_OMS_CHANNELS; channel++){ - pmotor = oms_motor_present[0]; - for (card = 0; card < MAX_OMS_CARDS; card++,pmotor++){ - if (pmotor == 0) continue; - if (oms_motor_array[card][channel].active){ - motor_active = TRUE; - - /* request status data */ - if ((channel <= 3) && (encoder_present[card])) - strcpy(oms_msg,"A?\nRE\nRP\nRA\n"); - else - strcpy(oms_msg,"A?\nRP\nRA\n"); - oms_msg[1] = oms_motor_specifier[channel]; - oms_send_msg(oms_motor_present[card],oms_msg); - } - } - } - } - } -} - -/* - * OMS_DRIVER_INIT - * - * initialize all oms drivers present - */ -oms_driver_init(){ - struct vmex_motor *pmotor; - short i,j,got_one; - int status; - short dummy; - char oms_init_msg[20]; - int taskId; - - for (i = 0; i < MAX_OMS_CARDS; i++){ - resp_inx[i] = 0; - } - - /* find all cards present */ - got_one = FALSE; - - status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,sm_addrs[OMS_6AXIS], &localaddr); - if (status != OK){ - logMsg("Addressing error in oms driver\n"); - return(ERROR); - } - rebootHookAdd(oms_reset); - pmotor = (struct vmex_motor *)localaddr; - for (i = 0; i < MAX_OMS_CARDS; i++,pmotor++){ - if (vxMemProbe(pmotor,READ,sizeof(short),&dummy) == OK){ - got_one = TRUE; - - /* intialize the motor */ - pmotor->control = 0; - - /* interrupt vector */ - pmotor->vector = 0x80+i; - intConnect(((0x80+i)*4),oms_intr,i); - sysIntEnable(OMS_INT_LEV); - - /* enable interrupt on input buffer full */ - pmotor->control |= 0xa0; - - /* mark the motor card as present */ - oms_motor_present[i] = pmotor; - encoder_present[i] = TRUE; - }else{ - /* mark the motor card as not present */ - oms_motor_present[i] = 0; - } - for (j = 0; j < MAX_OMS_CHANNELS; j++){ - oms_motor_array[i][j].active = FALSE; - oms_motor_array[i][j].callback = 0; - motor_data_array[i][j].encoder_position = 0; - motor_data_array[i][j].motor_position = 0; - } - } - - if (got_one){ - /* initialize the command task ring buffer */ - if ((oms_resp_q = rngCreate(OMS_RESP_Q_SZ)) == (RING_ID)NULL) - panic ("oms_driver_init: oms_resp_q not created\n"); - - /* initialize the oms response task semaphore */ - if(!(oms_resp_sem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))) - errMessage(0,"semBcreate failed in oms_driver_init"); - /* intialize the data request wakeup semaphore */ - if(!(oms_wakeup=semBCreate(SEM_Q_FIFO,SEM_EMPTY))) - errMessage(0,"semBcreate failed in oms_driver_init"); - /* oms card mutual exclusion semaphore */ - if(!(oms_send_sem=semBCreate(SEM_Q_FIFO,SEM_FULL))) - errMessage(0,"semBcreate failed in oms_driver_init"); - /* spawn the motor data request task */ - taskId = taskSpawn("oms_task",42,VX_FP_TASK,8000,oms_task); - taskwdInsert(taskId,NULL,NULL); - - /* spawn the motor data request task */ - taskId = taskSpawn("oms_resp_task",42,VX_FP_TASK,8000,oms_resp_task); - taskwdInsert(taskId,NULL,NULL); - - /* enable echo on each motor that is present */ - - pmotor = (struct vmex_motor *)localaddr; - - for (i = 0; i < MAX_OMS_CARDS; i++,pmotor++){ - if (oms_motor_present[i]){ - - /* give it the initialization commands */ - oms_send_msg(pmotor,"EN\nWY\n"); - } - } - } - return(0); -} - -/* - * OMS_DRIVER - * - * interface routine called from the database library - */ -#define MOTOR_POS 1 -oms_driver(card,channel,value_flag,arg1,arg2) -register short card; -register short channel; -short value_flag; -register int arg1; -int arg2; -{ - char oms_move_msg[100]; - short i,count; - - if (!oms_motor_present[card]) return(-1); - switch (value_flag){ - case (SM_MODE): /* only supports positional mode */ - break; - case (SM_VELOCITY): - /* set the velocity */ - motor_data_array[card][channel].velocity = arg1; - strcpy(oms_move_msg,"A?\nVL"); - oms_move_msg[MOTOR_POS] = oms_motor_specifier[channel]; - count = cvtLongToString(arg1,&oms_move_msg[5]); - strcat(oms_move_msg,"\n"); - oms_send_msg(oms_motor_present[card],oms_move_msg); - - /* set the acceleration */ - strcpy(oms_move_msg,"A?\nAC"); - oms_move_msg[MOTOR_POS] = oms_motor_specifier[channel]; - count = cvtLongToString(arg2,&oms_move_msg[5]); - strcat(oms_move_msg,"\n"); - oms_send_msg(oms_motor_present[card],oms_move_msg); - - break; - - case (SM_MOVE): - /* move the motor */ - strcpy(oms_move_msg,"A?\nAF\nMR"); - oms_move_msg[1] = oms_motor_specifier[channel]; - count = cvtLongToString(arg1,&oms_move_msg[8]); - strcat(oms_move_msg,"\nGO\n"); - oms_send_msg(oms_motor_present[card],oms_move_msg); - - /* set the motor to active */ - oms_motor_array[card][channel].active = TRUE; - - /* wakeup the oms task */ - semGive(oms_wakeup); - - break; - case (SM_MOTION): - /* stop the motor */ - strcpy(oms_move_msg,"A?ST\n"); - if (arg1 == 0){ - oms_move_msg[1] = oms_motor_specifier[channel]; - }else{ - return(0); - } - oms_send_msg(oms_motor_present[card],oms_move_msg); - - /* wakeup the oms task */ - semGive(oms_wakeup); - break; - - case (SM_CALLBACK): - i = 0; - if (oms_motor_array[card][channel].callback != 0) return(-1); - oms_motor_array[card][channel].callback = arg1; - oms_motor_array[card][channel].callback_arg = arg2; - break; - - /* reset encoder and motor positions to zero */ - case (SM_SET_HOME): - /* load the position to be zero */ - strcpy(oms_move_msg,"A?\nLP0\n"); - oms_move_msg[1] = oms_motor_specifier[channel]; - oms_send_msg(oms_motor_present[card],oms_move_msg); - - /* set the motor to active */ - oms_motor_array[card][channel].active = TRUE; - - /* wakeup the oms task */ - semGive(oms_wakeup); - - break; - - case (SM_ENCODER_RATIO): - /* set the encoder ratio */ - /* The "ER" command changes how far a pulse will move the */ - /* motor. */ - /* As this is not the desired action this command is not */ - /* implemented here. */ - break; - - case (SM_READ): - /* set the motor to active */ - oms_motor_array[card][channel].active = TRUE; - - /* wakeup the oms task */ - semGive(oms_wakeup); - - break; - } - return(0); -} - -char last_msg[80]; -int oms_count,oms_icount,oms_illcmd,oms_sleep,oms_isleep; -/* - * OMS_SEND_MSG - * - * Gives messages to the OMS card - */ -oms_send_msg(pmotor,pmsg) -struct vmex_motor *pmotor; -register char *pmsg; -{ -int i; -i = 0; - /* take the mutual exclusion semaphore */ - semTake(oms_send_sem, WAIT_FOREVER); - while (*pmsg){ - if (pmotor->status & 0x01){ - oms_illcmd++; - while ((pmotor->status & TRANSMIT_BUFFER_EMPTY) == 0){ - oms_icount++; - if ((oms_icount % 5) == 0){ - oms_isleep++; -/* A taskDelay makes a 68040 wait frequently */ - /*taskDelay(1);*/ - } - } - pmotor->data = 0x19; /* reset */ - }else{ - while ((pmotor->status & TRANSMIT_BUFFER_EMPTY) == 0){ - oms_count++; - if ((oms_count % 5) == 0){ - oms_sleep++; -/* A taskDelay makes a 68040 wait frequently */ - /*taskDelay(1);*/ - } - } - pmotor->data = *pmsg; - pmsg++; - } - } - /* release the mutual exclusion semaphore */ - semGive(oms_send_sem); -} - -oms_io_report(level) -short int level; -{ - register short int i,j; - - for (i = 0; i < MAX_OMS_CARDS; i++) { - if (oms_motor_present[i]){ - printf("SM: OMS:\tcard %d\n",i); - for (j = 0; j < MAX_OMS_CHANNELS; j++){ - if (level > 0) - oms_sm_stat(i,j); - } - } - - } - } - -VOID oms_sm_stat(card,channel) - short int card,channel; - { - - printf("SM: OMS: Card = %d,channel = %d\n",card,channel); - printf("\tCW limit = %d\tCCW limit = %d\tMoving = %d\tDirection = %d\n", - motor_data_array[card][channel].cw_limit, - motor_data_array[card][channel].ccw_limit, - motor_data_array[card][channel].moving, - motor_data_array[card][channel].direction); - - printf("\tConstant Velocity = %ld\tVelocity = %ld\t \n", - motor_data_array[card][channel].constant_velocity, - motor_data_array[card][channel].velocity); - - printf("\tAcceleration = %ld\tEncoder Position = %ld\tMotor Position = %ld\n", - motor_data_array[card][channel].accel, - motor_data_array[card][channel] .encoder_position, - motor_data_array[card][channel].motor_position); - } - - -/* - * - * Disables interrupts. Called on CTL X reboot. - * - */ - -VOID oms_reset(){ - short card; - struct vmex_motor *pmotor; - short dummy; - - pmotor = (struct vmex_motor *)localaddr; - for (card = 0; card < MAX_OMS_CARDS; card++,pmotor++){ - if(vxMemProbe(pmotor,READ,sizeof(short),&dummy) == OK){ - pmotor->control &= 0x5f; - } - } - -} diff --git a/src/drv/drvOms.h b/src/drv/drvOms.h deleted file mode 100644 index 065074afa..000000000 --- a/src/drv/drvOms.h +++ /dev/null @@ -1,74 +0,0 @@ -/* oms_sm_driver.h */ -/* base/src/drv $Id$ */ -/* - * headers that are used to interface to the - * Oregon Micro Systems six axis stepper motor drivers - * - * Author: Bob Dalesio - * Date: 02-25-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 04-12-90 lrd only allow one connection to each motor - * .02 11-13-90 lrd add status bit definitions for encoder commands - * .03 05-05-94 kornke supports 8 OMS channels now - */ -#define MAX_OMS_CARDS 8 -#define MAX_OMS_CHANNELS 8 - - -/* motor information */ -struct oms_motor{ -short active; /* flag to tell the oms_task if the motor is moving */ -int callback; /* routine in database library to call with status */ -int callback_arg; /* argument to callback routine */ -short update_count; -short stop_count; -}; - -#define MIRQE 0x80 -#define TRANSMIT_BUFFER_EMPTY 0x40 -#define INPUT_BUFFER_FULL 0x20 -#define MDONE 0x10 -#define OMS_ENCODER 0x04 -#define OMS_CMD_ERROR 0x01 - -struct vmex_motor{ - char unused0; - char data; - char unused1; - char done; - char unused2; - char control; - char unused3; - char status; - char unused4; - char vector; - char unused5[6]; -}; - -/* oms message defines */ -#define OMS_MSG_SZ 32 /* response message size */ -#define OMS_RESP_Q_SZ (OMS_MSG_SZ*500) /* response ring buffer size */ - diff --git a/src/drv/drvPEPBitBus.c b/src/drv/drvPEPBitBus.c deleted file mode 100644 index b521e6d74..000000000 --- a/src/drv/drvPEPBitBus.c +++ /dev/null @@ -1,1300 +0,0 @@ -/* drvPEPBitBus.c */ -/* base/src/drv $Id$ */ - -/* - * Original Author: Ned Arnold - * Author: John Winans - * Current: Claude Saunders - * Date: 8-4-93 - * PEP Modular PB-BIT BitBus driver - * - * 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 mm-dd-yy name note - * .01 08-04-93 saunders removed automatic RAC_RESET on timeout - * done by device support for compat. w/ xycom - * NOTES: - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "drvBitBusInterface.h" -#include "drvPEPBitBus.h" - -#define STATIC - -#define PEP_BB_BOARD_OFF 0x800 - -STATIC long reportBB(), initBB(), qBBReq(); -STATIC int xvmeTmoHandler(), xvmeRxTask(), xvmeTxTask(), xvmeWdTask(); -STATIC int xvmeIrqRdav(), xvmeIrqRcmd(); - int bbKill(int link); - -int bbDebug = 0; /* set to 1 from the shell to print debugging info */ - -/****************************************************************************** - * - * This structure contains a list of the outside-callable functions. - * - *****************************************************************************/ -struct drvBitBusEt drvBitBus = { - 3, - reportBB, - initBB, - qBBReq -}; - -STATIC char init_called = 0; /* to insure that init is done first */ -STATIC void *short_base; /* base of short address space */ - -STATIC struct xvmeLink *pXvmeLink[BB_NUM_LINKS]; /* NULL if link not present */ - -/****************************************************************** - * FUNCTION: reportBB() - * PURPOSE : Prints a message indicating the presence of each - * PB-BIT module found in system. - * ARGS IN : none - * ARGS OUT: none - * GLOBALS: checks pXvmeLink[i] for NULL - ******************************************************************/ -STATIC long -reportBB() -{ - int i; - - printf("Debugging flag is set to %d\n", bbDebug); - - if (init_called) - { - for (i=0; i< BB_NUM_LINKS; i++) - { - if (pXvmeLink[i] != NULL) - { - printf("Link %d (address 0x%08.8X) present and initialized.\n", i, pXvmeLink[i]->bbRegs); - } - else - { - printf("Link %d not installed.\n", i); - } - } - } - else - { - printf("BB driver has not yet been initialized.\n"); - } - return(OK); -} - -/****************************************************************** - * - * Reset hook function... takes down ALL the bitbus links and leaves - * them down. - * - ******************************************************************/ -STATIC void BBrebootFunc(void) -{ - int i; - - for (i=0; iint_vec), WRITE, 1, &probeValue) < OK) { - /* no BB board present here */ - pXvmeLink[i] = (struct xvmeLink *) NULL; - if (bbDebug) - printf("Probing of address 0x%08.8X failed\n", pXvmeRegs); - } else { - /* BB board found... reserve space for structures */ - - if (bbDebug) - printf("BB card found at address 0x%08.8X\n", pXvmeRegs); - - if ((pXvmeLink[i] = - (struct xvmeLink *)malloc(sizeof(struct xvmeLink))) == NULL) { - printf("Can't malloc memory for link data structures!\n"); - return(ERROR); - } - if ((pXvmeLink[i]->pbbLink = - (struct bbLink *)malloc(sizeof(struct bbLink))) == NULL) { - printf("Can't malloc memory for link data structures!\n"); - return(ERROR); - } - pXvmeLink[i]->pbbLink->linkType = BITBUS_IO; /* spec'd in link.h */ - pXvmeLink[i]->pbbLink->linkId = i; /* link number */ - - /* Semaphore for blocking/unblocking Tx task */ - pXvmeLink[i]->pbbLink->linkEventSem = - semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - /* Semaphore for blocking/unblocking Rx task */ - pXvmeLink[i]->rxInt = - semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - /* init all the prioritized queue lists */ - for (j=0; jpbbLink->queue[j].head = NULL; - pXvmeLink[i]->pbbLink->queue[j].tail = NULL; - pXvmeLink[i]->pbbLink->queue[j].sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - } - - /* init the busy message list */ - pXvmeLink[i]->pbbLink->busyList.sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - pXvmeLink[i]->pbbLink->busyList.head = NULL; - pXvmeLink[i]->pbbLink->busyList.tail = NULL; - - for (j=0; jpbbLink->deviceStatus[j] = BB_IDLE; - } - - pXvmeLink[i]->bbRegs = pXvmeRegs; - pXvmeLink[i]->watchDogId = wdCreate(); - - /* Semaphore for blocking/unblocking Wd task */ - pXvmeLink[i]->watchDogSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - /* clear the link abort status */ - pXvmeLink[i]->abortFlag = 0; - pXvmeLink[i]->txAbortAck = 0; - pXvmeLink[i]->rxAbortAck = 0; - - xvmeReset(pXvmeRegs, i); /* finish reset the PB-BIT module */ - - /* Attach the Rx interrupt handler routine. Vector based on link # */ - intConnect(INUM_TO_IVEC(PEP_BB_IVEC_BASE + (i*2)), xvmeIrqRdav, i); - - /* start a task to manage the TX link */ - sprintf(nameTemp, "%s%d", BBTXLINK_NAME, i); - if (taskSpawn(nameTemp,BBTXLINK_PRI,BBTXLINK_OPT,BBTXLINK_STACK, - xvmeTxTask, i) == ERROR) { - printf("initBB: failed to start TX link task for link %d\n", i); - } - - /* start a task to manage the RX link */ - sprintf(nameTemp, "%s%d", BBRXLINK_NAME, i); - if (taskSpawn(nameTemp,BBRXLINK_PRI,BBRXLINK_OPT,BBRXLINK_STACK, - xvmeRxTask, i) == ERROR) { - printf("initBB: failed to start RX link task for link %d\n", i); - } - - /* start a watchdog (Wd) task to keep an eye on the busy list */ - sprintf(nameTemp, "%s%d", BBWDTASK_NAME, i); - if (taskSpawn(nameTemp,BBWDTASK_PRI,BBWDTASK_OPT,BBWDTASK_STACK, - xvmeWdTask, i) == ERROR) { - printf("initBB: failed to start watchdog task for link %d\n", i); - } - } - - /* set pXvmeRegs to point to next piggyback or board window */ - if (((unsigned)pXvmeRegs & 0xff) == 0x80) - pXvmeRegs = (struct xvmeRegs *) - ((unsigned char *)pXvmeRegs - 0x80 + PEP_BB_BOARD_OFF); - else - pXvmeRegs = (struct xvmeRegs *)((unsigned char *)pXvmeRegs + 0x80); - - } - sysIntEnable(BB_IRQ_LEVEL); - - init_called = 1; /* let reportBB() know init occured */ - return(OK); -} - -/****************************************************************** - * FUNCTION: xvmeReset() - * PURPOSE : Performs firmware reset of PB-BIT module corresponding - * to link. Attempts to empty any data sitting in receive - * FIFO. Interrupts are disabled and Rx task is unblocked. - * ARGS IN : xvmeRegs ptr to register structure of PB-BIT module - * link link number serviced by PB-BIT module - * ARGS OUT: none - * GLOBALS: twiddles board - ******************************************************************/ -STATIC int -xvmeReset(xvmeRegs, link) -struct xvmeRegs *xvmeRegs; -int link; -{ - char trash; - int j; - int lockKey; - - if (bbDebug) - printf("xvmeReset(%08.8X, %d): Resetting xvme module\n", xvmeRegs, link); - - /* Write firmware reset package (2 bytes) to board */ - xvmeRegs->data = 0x83; - xvmeRegs->stat_ctl = 0x01; - - taskDelay(20); /* give the 80152 time to self check */ - - if ((xvmeRegs->stat_ctl & 0x10) != 0x0) { - printf("xvmeReset(%d): PB-BIT firmware reset failed!\n", link); - return(ERROR); - } - - j = 1026; /* 1K deep receive fifo */ - while ((xvmeRegs->stat_ctl & XVME_RFNE) && --j) - trash = xvmeRegs->data; /* flush receive fifo if junk in it */ - - if (!j) { - printf("xvmeReset(%d): receive fifo will not clear after reset!\n"); - return(ERROR); - } - - /* Disable interrupts */ - lockKey = intLock(); - xvmeRegs->int_vec = 0; - intUnlock(lockKey); - - semGive(pXvmeLink[link]->rxInt); /* Tell xvmeRxTask to Re-enable ints */ - - return(OK); -} - -/************************************************************************** - * - * This function is used to add a node to the HEAD of a list. - * - **************************************************************************/ -static int -listAddHead(plist, pnode) -struct bbList *plist; -struct dpvtBitBusHead *pnode; -{ - pnode->prev = NULL; - pnode->next = plist->head; - - if (plist->head != NULL) - plist->head->prev = pnode; - - if (plist->tail == NULL) - plist->tail = pnode; - - plist->head = pnode; - - return(0); -} -/****************************************************************************** - * - * This function is used to add a node to the TAIL of a list. - * - ******************************************************************************/ -static int -listAddTail(plist, pnode) -struct bbList *plist; -struct dpvtBitBusHead *pnode; -{ - pnode->next = NULL; /* No next node if this is the TAIL */ - pnode->prev = plist->tail; /* previous node is the 'old' TAIL node */ - - if (plist->tail != NULL) - plist->tail->next = pnode; /* link the 'old' tail to the 'new' tail node */ - - if (plist->head == NULL) - plist->head = pnode; - - plist->tail = pnode; /* this is the 'new' tail node */ - - return(0); -} - -/****************************************************************************** - * - * This function is used to delete a node from a list. - * - ******************************************************************************/ -static int -listDel(plist, pnode) -struct bbList *plist; -struct dpvtBitBusHead *pnode; -{ - if (pnode->next != NULL) - pnode->next->prev = pnode->prev; - - if (pnode->prev != NULL) - pnode->prev->next = pnode->next; - - if (plist->head == pnode) - plist->head = pnode->next; - - if (plist->tail == pnode) - plist->tail = pnode->prev; - - return(0); -} - -/****************************************************************** - * FUNCTION: xvmeIrqRdav() - * PURPOSE : Invoked when PB-BIT module has received a complete - * bitbus message (ie. not on a byte-by-byte basis). - * ARGS IN : link link number upon which message has arrived - * ARGS OUT: none - * GLOBALS: unblocks Rx task (if it is not already running) - ******************************************************************/ -STATIC int -xvmeIrqRdav(link) -int link; -{ - pXvmeLink[link]->bbRegs->int_vec = 0; /* disable interrupts */ - - if (bbDebug > 30) - logMsg("bitbus rx IRQ on link %d\n", link); - - semGive(pXvmeLink[link]->rxInt); /* unblock it */ - return(0); -} - -/****************************************************************** - * FUNCTION: checkLink() - * PURPOSE : Checks to make sure driver is initialized to handle link. - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -static int -checkLink(link) -int link; -{ - - if (link<0 || link>BB_NUM_LINKS) - return(ERROR); /* link number out of range */ - - if (pXvmeLink[link] == NULL) - return(ERROR); /* link number has no card installed */ - - return(OK); -} - -/****************************************************************** - * FUNCTION: xvmeTmoHandler() - * PURPOSE : Invoked whenever a watchdog timer times out. Watchdogs - * are running whenever the busyList has any elements on - * it. The idea here is that the watchdog handler scans - * through the busyList, looking for old requests that have - * not been replied to in too long a time. If there are - * any old ones around, they are removed from the list, - * and the associated node is reset and marked offline. - * - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int -xvmeTmoHandler(link) -int link; -{ - if (bbDebug > 25) - logMsg("xvmeTmoHandler(%d): Watch dog interrupt\n", link); - - semGive(pXvmeLink[link]->watchDogSem); /* unblock Wd task */ - return(0); -} - -/****************************************************************** - * FUNCTION: xvmeRxTask() - * PURPOSE : This function is started as a task during driver init - * time. It's purpose is to read messages off the receive - * FIFO. After a complete message is read, the soliciting - * message's completion routines are started by the use - * of semaphores and/or a callbackRequest(). - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int -xvmeRxTask(link) -int link; -{ - int rxState; /* current state of the receiver */ -#define BBRX_HEAD 1 -#define BBRX_DATA 2 -#define BBRX_RCMD 3 -#define BBRX_IGN 4 - - unsigned char rxHead[7]; /* room for header of current rx msg */ - unsigned char *rxMsg; /* where to place next byte (after header) */ - int rxTCount; /* byte counter for data in rxHead */ - unsigned char ch; - struct dpvtBitBusHead *rxDpvtHead; /* for message currently receiving */ - int lockKey; /* used for intLock calls */ - int packageComplete; /* indicates last byte of package was read */ - - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - packageComplete = 0; - - while (1) { - /* Wait for RX interrupts, but only if no chars are ready */ - if ((pXvmeLink[link]->bbRegs->stat_ctl & XVME_RFNE) == 0) { - - /* Enable interrupts and check again in case PB-BIT blew it */ - lockKey = intLock(); - pXvmeLink[link]->bbRegs->int_vec = PEP_BB_IVEC_BASE +(link*2); - intUnlock(lockKey); - - while (((pXvmeLink[link]->bbRegs->stat_ctl & XVME_RFNE) == 0) && - (pXvmeLink[link]->abortFlag == 0)) { - - /* Re-enable ints here each time in case board got reset */ - lockKey = intLock(); - pXvmeLink[link]->bbRegs->int_vec = PEP_BB_IVEC_BASE +(link*2); - intUnlock(lockKey); - - semTake(pXvmeLink[link]->rxInt, WAIT_FOREVER); /* wait for message */ - } - - /* Disable RX Interrupts (prevents unnecessary context switching) */ - lockKey = intLock(); - pXvmeLink[link]->bbRegs->int_vec = 0; - intUnlock(lockKey); - } - - if (pXvmeLink[link]->abortFlag == 0) { - /* READ ONE CHAR FROM RECEIVE FIFO */ - ch = pXvmeLink[link]->bbRegs->data; - - /* check to see if we got a data byte or a command byte */ - if ((pXvmeLink[link]->bbRegs->stat_ctl & XVME_RCMD) == XVME_RCMD) - packageComplete = 1; - - switch (rxState) { - case BBRX_HEAD: /* getting the head of a new message */ - if (rxTCount > 1) /* Toss the 2 PEP specific header bytes */ - rxHead[rxTCount] = ch; - if (bbDebug>21) - printf("xvmeRxTask(%d): >%02.2X< (Header)\n", link, ch); - - if (++rxTCount == 7) { - /* find the message this is a reply to */ - /* rxTCount += 2; PEP header bytes already messed up the count (jrw)*/ - - /* Lock the busy list */ - semTake(pXvmeLink[link]->pbbLink->busyList.sem, WAIT_FOREVER); - - rxDpvtHead = pXvmeLink[link]->pbbLink->busyList.head; - while (rxDpvtHead != NULL) { - if (bbDebug>19) - printf("xvmeRxTask(%d): checking reply against 0x%08.8X\n", - link, rxDpvtHead); - - /* see if node's match */ - if (rxDpvtHead->txMsg.node == rxHead[4]) { - /* see if the tasks match */ - /* if (rxDpvtHead->txMsg.tasks == rxHead[5]) */ - { - /* They match, finish putting response into the rxMsg buffer */ - if (bbDebug>4) - printf("xvmeRxTask(%d): reply to 0x%08.8X\n", - link, rxDpvtHead); - - /* Delete the node from the list */ - listDel(&(pXvmeLink[link]->pbbLink->busyList), rxDpvtHead); - - /* If busy list is empty, stop the dog */ - if (pXvmeLink[link]->pbbLink->busyList.head == NULL) - wdCancel(pXvmeLink[link]->watchDogId); - - /* decrement the number of outstanding messages to the node */ - (pXvmeLink[link]->pbbLink->deviceStatus[rxDpvtHead->txMsg.node])--; - - /* Wake up Link Task in case was waiting on "this" node */ - semGive(pXvmeLink[link]->pbbLink->linkEventSem); - - semGive(pXvmeLink[link]->pbbLink->busyList.sem); - - rxDpvtHead->rxMsg.length = rxHead[2]; - rxDpvtHead->rxMsg.route = rxHead[3]; - rxDpvtHead->rxMsg.node = rxHead[4]; - rxDpvtHead->rxMsg.tasks = rxHead[5]; - rxDpvtHead->rxMsg.cmd = rxHead[6]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ - break; /* get out of the while() */ - } - } - rxDpvtHead = rxDpvtHead->next; /* Keep looking */ - } - - if (rxDpvtHead == NULL) { - if (bbDebug > 9) { - printf("xvmeRxTask(%d): msg from node %d unsolicited!\n", - link, rxHead[4]); - printf("contents: %02.2x %02.2x %02.2x %02.2x %02.2x\n",rxHead[2], - rxHead[3],rxHead[4],rxHead[5],rxHead[6]); - } - semGive(pXvmeLink[link]->pbbLink->busyList.sem); - rxState = BBRX_IGN; /* nothing waiting... toss it */ - } - } - break; - - case BBRX_DATA: /* finish reading data portion of message */ - if (rxTCount >= rxDpvtHead->rxMaxLen) { - rxState = BBRX_IGN; /* toss the rest of the data */ - rxDpvtHead->status = BB_LENGTH; /* set driver status */ - if (bbDebug>22) - printf("xvmeRxTask(%d): %02.2X (Ignored)\n", link, ch); - - } - else { - *rxMsg = ch; - if (bbDebug>22) - printf("xvmeRxTask(%d): %02.2X (Data)\n", link, ch); - rxMsg++; - rxTCount++; - } - break; - - case BBRX_IGN: - if (bbDebug>22) - printf("xvmeRxTask(%d): %02.2X (Ignored)\n", link, ch); - break; - } - - if (packageComplete) { - if (rxDpvtHead == NULL) { - if (bbDebug > 22) - printf("xvmeRxTask(%d): got unexpected XVME_RCMD\n", link); - } - else { - rxDpvtHead->status = BB_OK; - if (bbDebug>24) - printf("xvmeRxTask(%d): RX command byte = %02.2X\n", link, ch); - - if (rxDpvtHead->finishProc != NULL) { - if (bbDebug>8) - printf("xvmeRxTask(%d): invoking the callbackRequest\n", link); - callbackRequest(rxDpvtHead); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (rxDpvtHead->psyncSem != NULL) - semGive(*(rxDpvtHead->psyncSem)); - } - } - /* Reset the state of the RxTask to expect a new message */ - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - packageComplete = 0; - } - - } - else { - /* Link abort state is active reset receiver link status now */ - if (rxDpvtHead != NULL) { - /* This xact is not on the busy list, put it back on */ - semTake(pXvmeLink[link]->pbbLink->busyList.sem, WAIT_FOREVER); - (pXvmeLink[link]->pbbLink->deviceStatus[rxDpvtHead->txMsg.node])++; - listAddTail(&(pXvmeLink[link]->pbbLink->busyList), rxDpvtHead); - semGive(pXvmeLink[link]->pbbLink->busyList.sem); - } - - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - /* Tell the watch dog I am ready for the reset (reset in the dog task) */ - pXvmeLink[link]->rxAbortAck = 1; - - /* if (bbDebug) */ - printf("xvmeRxTask(%d): resetting due to abort status\n", link); - - /* wait for link state to become active again */ - while (pXvmeLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); - - /* if bbDebug) */ - printf("xvmeRxTask(%d): restarting after abort\n", link); - } - } -} - -/****************************************************************** - * FUNCTION: bbReset() - * PURPOSE : Induces a link reset by setting nukeEm flag and - * unblocking the watchDog task. - * - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: nukeEm set and Wd unblocked - ******************************************************************/ -int -bbReset(link) -int link; -{ - if (checkLink(link) != ERROR) - { - pXvmeLink[link]->pbbLink->nukeEm = 1; - semGive(pXvmeLink[link]->watchDogSem); - } - else - printf("Link %d not installed.\n", link); - - return(0); -} - -/******************************************************************* - * - * Same as bbReset() but it takes the link down and leaves it down. - * - *******************************************************************/ -int bbKill(int link) -{ - if (checkLink(link) != ERROR) - { - pXvmeLink[link]->pbbLink->nukeEm = 2; - semGive(pXvmeLink[link]->watchDogSem); - } - else - printf("Link %d not installed.\n", link); - - return(0); -} - - -/****************************************************************** - * FUNCTION: xvmeWdTask() - * PURPOSE : - * - * ARGS IN : none - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int - xvmeWdTask(link) -int link; -{ - struct bbLink *plink; - struct dpvtBitBusHead *pnode; - struct dpvtBitBusHead *npnode; - unsigned long now; - SEM_ID syncSem; - - struct dpvtBitBusHead resetNode; - unsigned char resetNodeData; /* 1-byte data field for RAC_RESET */ - unsigned char responseData; - - struct dpvtBitBusHead offlnNode; - unsigned char offlnNodeData; /* 1-byte data field for RAC_OFFLN */ - unsigned char response1Data; /* 1-byte response data field */ - - /* init the SEM used when sending the RAC_OFFLN message */ - syncSem = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY); - - /* - * Hand-craft a RAC_RESET and RAC_OFFLINE message to use when - * a message times out. - * NOTE that having only one copy is OK provided that the dog waits for - * a response before sending it again! - */ - resetNode.finishProc = NULL; /* no callback routine used */ - resetNode.psyncSem = NULL; - resetNode.link = link; /* which bitbus link to send message out on */ - resetNode.rxMaxLen = 10; - resetNode.ageLimit = sysClkRateGet()*100; /* make sure this never times out */ - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.data = &resetNodeData; - resetNode.rxMsg.data = &responseData; - - offlnNode.finishProc = NULL; /* no callback routine used */ - offlnNode.psyncSem = &syncSem;/* do a semGive on this SEM when responded to*/ - offlnNode.link = link; /* which bitbus link to send message out on */ - offlnNode.rxMaxLen = 10; - offlnNode.ageLimit = sysClkRateGet()*100; /* make sure this never times out */ - - offlnNode.txMsg.length = 8; - offlnNode.txMsg.route = BB_STANDARD_TX_ROUTE; - offlnNode.txMsg.tasks = 0x0; - offlnNode.txMsg.data = &offlnNodeData; - offlnNode.rxMsg.data = &response1Data; - - plink = pXvmeLink[link]->pbbLink; - - plink->nukeEm = 0; /* Make sure the nuke status is clear */ - while(1) { - /* SLEEP UNTIL WATCHDOG TIMER ROUTINE GIVES SEMAPHORE */ - semTake(pXvmeLink[link]->watchDogSem, WAIT_FOREVER); - now = tickGet(); /* what time is it? */ - - if (plink->nukeEm != 0) - printf("Bitbus manual reset being issued on link %d\n", link); - - if (bbDebug>4) - printf("xvmeWdTask(%d): (Watchdog) checking busy list\n", link); - - pXvmeLink[link]->rxAbortAck = 0; - pXvmeLink[link]->txAbortAck = 0; - - if (plink->nukeEm != 0) { - /* set abort status and wait for the abort acks */ - pXvmeLink[link]->abortFlag = 1; - - /* wake up the Tx task so it can observe the abort status */ - semGive(plink->linkEventSem); - - /* wake up the Rx task so it can observe the abort ststus */ - semGive(pXvmeLink[link]->rxInt); - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pXvmeLink[link]->rxAbortAck == 0) && - (pXvmeLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - } - /* - * Run thru entire busy list to see if there are any transactions - * that have been waiting on a response for too long a period. - */ - semTake(plink->busyList.sem, WAIT_FOREVER); - pnode = plink->busyList.head; - - while (pnode != NULL) { - npnode = pnode->next; /* remember where we were in the list */ - - if ((plink->nukeEm != 0) || (pnode->retire <= now)) { - /* Get rid of the request and set error status etc... */ - listDel(&(plink->busyList), pnode); - - printf("xvmeWdTask(%d): TIMEOUT on xact 0x%08.8X\n", link, pnode); - - (plink->deviceStatus[pnode->txMsg.node])--; /* fix device status */ - pnode->status = BB_TIMEOUT; - - /* Gotta do this now in case we need the info after the completion */ - resetNode.txMsg.node = pnode->txMsg.node; - offlnNodeData = pnode->txMsg.node; /* mark the node number */ - - /* Make the callbackRequest if one was spec'd */ - if(pnode->finishProc != NULL) - { - if (bbDebug>2) - { - printf("xvmeWdTask(%d): invoking the callbackRequest %8.8x %d\n", link, pnode->finishProc, pnode->priority); - } - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* Release a completion lock if one was spec'd */ - if (pnode->psyncSem != NULL && plink->nukeEm == 0) - semGive(*(pnode->psyncSem)); - } - /* If we are not going to reboot the link... */ - if ( plink->nukeEm == 0 ) { - /* Send out a RAC_RESET/RAC_OFFLINE pair */ - semGive(plink->busyList.sem); - - /* Configure message for a RAC_RESET */ - resetNode.txMsg.cmd = 0x00; - - /* Configure message for a RAC_OFFLINE */ - offlnNode.txMsg.cmd = RAC_OFFLINE; - offlnNode.txMsg.node = 0xff; - - /* Queue the messages (high priority, reset first) */ - - semTake(plink->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(plink->queue[BB_Q_HIGH]), &offlnNode); -/* listAddHead(&(plink->queue[BB_Q_HIGH]), &resetNode); */ - semGive(plink->queue[BB_Q_HIGH].sem); - - semGive(plink->linkEventSem); /* Tell TxTask to send the messages */ - - if (semTake(syncSem, (sysClkRateGet()) ) == ERROR) { - printf("xvmeWdTask(%d): link dead, trying manual reboot\n", link); - plink->nukeEm = 1; - pXvmeLink[link]->abortFlag = 1; - semGive(plink->linkEventSem); - semGive(pXvmeLink[link]->rxInt); - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pXvmeLink[link]->rxAbortAck == 0) && - (pXvmeLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - } - - /* Start over since released the busy list */ - semTake(plink->busyList.sem, WAIT_FOREVER); - npnode = plink->busyList.head; - } - } - pnode = npnode; - } - - /* Finish the link reboot if necessary */ - if (plink->nukeEm != 0) - { - /* shut down the bitbus card. */ - xvmeReset(pXvmeLink[link]->bbRegs, link); - - if (plink->nukeEm == 2) - { - /* - * Stop the watchdog task so the link stays dead. - * Since the busy list is locked and the nukeEm flag is still set, - * this link can not do any more work. - */ - exit(); - } - - /* clear the abort_flag */ - pXvmeLink[link]->abortFlag = 0; - - plink->nukeEm = 0; - } - - if (plink->busyList.head != NULL) { - /* Restart the dog timer */ - if (bbDebug>5) - printf("xvmeWdTask(%d): restarting watch dog timer\n", link); - - wdStart(pXvmeLink[link]->watchDogId, plink->busyList.head->retire - now, - xvmeTmoHandler, link); - } - - semGive(plink->busyList.sem); - } -} - -/****************************************************************** - * FUNCTION: xvmeTxTask() - * PURPOSE : This function is started as a task during driver init - * time. It's purpose is to keep the link busy with - * outgoing messages. It awaits user-calls to qBBReq() - * (new message to send). It also awaits wake up calls - * from the Wd timer (a timed out message to a node, - * once handled, means Tx is free to send again to that - * node). - * - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int - xvmeTxTask(link) -int link; -{ - struct bbLink *plink; - struct dpvtBitBusHead *pnode; - struct dpvtBitBusHead *npnode; - int prio; - int working; - int dogStart; - int stuck; - - int txTCount; - int txCCount; - unsigned char *txMsg; - register int x; - unsigned long now; - - if (bbDebug) - printf("xvmeTxTask started for link %d\n", link); - - plink = pXvmeLink[link]->pbbLink; - - while(1) { - if (pXvmeLink[link]->abortFlag != 0) { - /* let the dog know we are ready */ - pXvmeLink[link]->txAbortAck = 1; - - printf("xvmeTxTask(%d): resetting due to abort status\n", link); - - while (pXvmeLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); /* wait for link to reset */ - - printf("xvmeTxTask(%d): restarting after abort\n", link); - } - else - semTake(plink->linkEventSem, WAIT_FOREVER); - - if (bbDebug>5) - printf("xvmeTxTask(%d): got an event\n", link); - - working = 1; - while ((working != 0) && (pXvmeLink[link]->abortFlag == 0)) { - working = 0; - - prio = BB_NUM_PRIO-1; - while ((prio >= 0) && (pXvmeLink[link]->abortFlag == 0)) { - /* see if the queue has anything in it */ - semTake(plink->queue[prio].sem, WAIT_FOREVER); - - if ((pnode = plink->queue[prio].head) != NULL) { - while (plink->deviceStatus[pnode->txMsg.node] == BB_BUSY) { - if ((pnode = pnode->next) == NULL) - break; - } - } - - if (pnode != NULL) { /* have an xact to start processing */ - working = 1; - - /* delete the node from the inbound fifo queue */ - listDel(&(plink->queue[prio]), pnode); - - semGive(plink->queue[prio].sem); - - if (bbDebug>3) - printf("xvmeTxTask(%d): got xact, pnode=0x%08.8X\n", link, pnode); - - /* Send the message in polled mode */ - txTCount = pnode->txMsg.length; - txCCount = 0; - txMsg = &(pnode->txMsg.length); - - while ((txCCount < txTCount) && (pXvmeLink[link]->abortFlag == 0)) { - - stuck = 1000; - while (((pXvmeLink[link]->bbRegs->stat_ctl & XVME_TFNF) - != XVME_TFNF) && - (pXvmeLink[link]->abortFlag == 0) && - --stuck) - for(x=0;x<100;x++); /* wait for TX ready */ - - if (!stuck) - txStuck(link); - else if (txCCount == 0) { /* first byte is package type */ - if (bbDebug>30) - printf("xvmeTxTask(%d): outputting %02.2X\n",link,0x81); - pXvmeLink[link]->bbRegs->data = 0x81; - } - else if (txCCount == 1) { /* unused 2nd byte of package */ - if (bbDebug>30) - printf("xvmeTxTask(%d): outputting %02.2X\n",link,0x00); - pXvmeLink[link]->bbRegs->data = 0x00; - } - else if (txCCount == (txTCount -1)) { /* last byte of package */ - pXvmeLink[link]->bbRegs->stat_ctl = *txMsg; - if (bbDebug>30) - printf("xvmeTxTask(%d): outputting last byte %02.2X\n", - link,*txMsg); - } else { /* regular ol' message byte */ - pXvmeLink[link]->bbRegs->data = *txMsg; - if (bbDebug>30) - printf("xvmeTxTask(%d): outputting %02.2X\n",link,*txMsg); - if (txCCount != 6) - txMsg++; - else - txMsg = pnode->txMsg.data; - } - txCCount++; - } - - if (pXvmeLink[link]->abortFlag == 0) { - - /* don't add to busy list if was a RAC_RESET_SLAVE */ - if ((pnode->txMsg.cmd == RAC_RESET_SLAVE) && (pnode->txMsg.tasks == 0)) - { - printf("xvmeTxTask(%d): RAC_RESET_SLAVE sent\n", link); - - pnode->status = BB_OK; - - if (pnode->finishProc != NULL) { - if (bbDebug>4) - printf("xvmeTxTask(%d): invoking the callbackRequest\n", - link); - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (pnode->psyncSem != NULL) - semGive(*(pnode->psyncSem)); - } - taskDelay(15); - } - else - { - /* Lock the busy list */ - semTake(plink->busyList.sem, WAIT_FOREVER); - - /* set the retire time */ - pnode->retire = tickGet(); - if (pnode->ageLimit) - pnode->retire += pnode->ageLimit; - else - pnode->retire += 5*sysClkRateGet(); - - if (plink->busyList.head == NULL) - dogStart = 1; - else - dogStart = 0; - - /* Add pnode to the busy list */ - listAddTail(&(plink->busyList), pnode); - - /* Count the outstanding messages */ - (plink->deviceStatus[pnode->txMsg.node])++; - - semGive(plink->busyList.sem); - - /* If something just added to empty busy list, start the dog */ - if (dogStart) { - now = tickGet(); - wdStart(pXvmeLink[link]->watchDogId, - plink->busyList.head->retire - now, - xvmeTmoHandler, link); - } - } - } else { /* if abortFlag != 0 */ - /* Aborted transmission operation, re-queue the message */ - semTake(plink->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(plink->queue[BB_Q_HIGH]), pnode); - semGive(plink->queue[BB_Q_HIGH].sem); - } - - } else { /* if pnode == NULL */ - /* we have no xacts that can be processed at this time */ - semGive(plink->queue[prio].sem); - } - prio--; /* look at the next prio queue */ - } - } - } -} - -/****************************************************************** - * FUNCTION: txStuck() - * PURPOSE : Invoked by Tx task when PB-BIT xmit FIFO won't - * accept bytes after a reasonable time. - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int -txStuck(link) -int link; -{ - printf("xvmeTxTask(%d): transmitter stuck, resetting link\n",link); - - bbReset(link); - while(pXvmeLink[link]->abortFlag == 0) /* wait until reset complete */ - taskDelay(1); - - return(OK); -} - -/****************************************************************** - * FUNCTION: qBBReq() - * PURPOSE : This function is called by user programs to queue an io - * request for the BB driver. It is the only user-callable - * function provided in this driver. - * ARGS IN : pdpvt ptr to bitbus message struct in record dpvt area - * prio requested priority of message - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC long -qBBReq(pdpvt, prio) -struct dpvtBitBusHead *pdpvt; -int prio; -{ - char message[200]; - static linkErrFlags[BB_NUM_LINKS]; /* Supposedly init'd to zero */ - - if ((prio < 0) || (prio >= BB_NUM_PRIO)) { - sprintf(message, - "invalid priority requested in call to qbbreq(%08.8X, %d)\n", - pdpvt, prio); - errMessage(S_BB_badPrio, message); - return(ERROR); - } - - if (checkLink(pdpvt->link) == ERROR) - { - if (pdpvt->link >= BB_NUM_LINKS) - { - sprintf(message, "qbbreq(%08.8X, %d) %d\n", pdpvt, prio, pdpvt->link); - errMessage(S_BB_badlink, message); - } - else if (linkErrFlags[pdpvt->link] == 0) - { /* Anti-message swamping check */ - linkErrFlags[pdpvt->link] = 1; - sprintf(message, "qbbreq(%08.8X, %d) %d... card not present\n", - pdpvt, prio, pdpvt->link); - errMessage(S_BB_badlink, message); - } - return(ERROR); - } - - semTake(pXvmeLink[pdpvt->link]->pbbLink->queue[prio].sem, WAIT_FOREVER); - - /* Add to the end of the queue of waiting transactions */ - listAddTail(&(pXvmeLink[pdpvt->link]->pbbLink->queue[prio]), pdpvt); - - semGive(pXvmeLink[pdpvt->link]->pbbLink->queue[prio].sem); - - semGive(pXvmeLink[pdpvt->link]->pbbLink->linkEventSem); - - if (bbDebug>5) - printf("qbbreq(0x%08.8X, %d): transaction queued\n", pdpvt, prio); - - return(OK); -} - -/****************************************************************** - * FUNCTION: drvBitBusDumpMsg() - * PURPOSE : Print out bitbus message structure. - * ARGS IN : none - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -int -drvBitBusDumpMsg(pbbMsg) -struct bitBusMsg *pbbMsg; -{ - char ascBuf[15]; /* for ascii xlation part of the dump */ - int x; - int y; - int z; - - printf("Link 0x%04.4X, length 0x%02.2X, route 0x%02.2X, node 0x%02.2X, tasks 0x%02.2X, cmd %02.2X\n", pbbMsg->link, pbbMsg->length, pbbMsg->route, pbbMsg->node, pbbMsg->tasks, pbbMsg->cmd); - - x = BB_MSG_HEADER_SIZE; - y = pbbMsg->length; - z = 0; - - while (x < y) - { - printf("%02.2X ", pbbMsg->data[z]); - ascBuf[z] = pbbMsg->data[z]; - - if (!((ascBuf[z] >= 0x20) && (ascBuf[z] <= 0x7e))) - ascBuf[z] = '.'; - - x++; - z++; - } - - while (x < BB_MAX_MSG_LENGTH) - { - printf(" "); - x++; - } - - ascBuf[z] = '\0'; - printf(" *%s*\n", ascBuf); - return(OK); -} - -/****************************************************************** - * FUNCTION: dumpStat() - * PURPOSE : Temporary function. Shows contents of status - * register on PB-BIT module corresponding to link. - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -int dumpStat(link) - int link; -{ - unsigned char stat_ctl; - - stat_ctl = pXvmeLink[link]->bbRegs->stat_ctl; - - printf("stat_ctl reg: %02x\n",stat_ctl); - return(OK); -} diff --git a/src/drv/drvPEPBitBus.h b/src/drv/drvPEPBitBus.h deleted file mode 100644 index aecd79515..000000000 --- a/src/drv/drvPEPBitBus.h +++ /dev/null @@ -1,121 +0,0 @@ -/* drvBitBusInterface.h */ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Current: Claude Saunders - * Date: 01-27-93 - * PB-BIT BitBus driver - * - * 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 09-30-91 jrw Written - * .02 12-10-91 jrw moved some stuff over to drvBitBusInterface.h - * .03 01-27-93 saunders ported driver to pb-bit (PEP Modular, INC.) - */ - -/****************************************************************************** - * Memory Map of PEP Modular PB-BIT BITBUS CARD - * - * This board is rather stupid in that it wastes a bunch of bytes - * for its regs. So the dm* fields in the structure below are - * for those filler locations. - * - *****************************************************************************/ -struct xvmeRegs { - unsigned char dm0; - unsigned char data; - unsigned char dm2; - unsigned char stat_ctl; - unsigned char dm[29]; - unsigned char int_vec; -}; - -#define RESET_POLL_TIME 10 /* time to sleep when waiting on a link abort */ - -#define BB_SEND_CMD 0x0 /* command to initiate sending of msg */ - -#define XVME_ENABLE_INT 0x20 /* Allow interupts */ - -#define XVME_TX_INT 0x20 /* int enable TX only */ -#define XVME_TX_PEND 0x01 /* transmit interrupt currently pending */ - -#define XVME_RX_INT 0x20 /* int exable RX only */ -#define XVME_RX_PEND 0x01 /* receive interrupt currently pending */ - -#define XVME_NO_INT 0 /* disable all interrupts */ - -/****************************************************************************** - * - * status register format - * - * +----+----+----+----+----+----+----+----+ - * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bits - * +----+----+----+----+----+----+----+----+ - * X X X STF LBP TFF RFNE IRQP - * - * STF = "1"= self-test failed - * "0"= passed - * - * LBP = "1"= last data byte was last of package - * "0"= 1+ bytes left - * - * TFF = "1"= only one more byte may be written to TFIFO - * "0"= 1+ more bytes may be written - * - * RFNE = "1"= Receive Fifo Not Empty - * "0"= Receive Fifo empty - * - * IRQP = "1"= no irq pending - * "0"= irq pending - * - * - *****************************************************************************/ -#define XVME_RCMD 0x08 /* Command has been received */ -#define XVME_RFNE 0x02 /* Receive Fifo is Not Empty */ -#define XVME_TFNF 0x04 /* Transmit FIFO is Not Full */ -#define XVME_FSVALID 0x1f /* these are the only valid status bits */ -/* ???????????? */ -#define XVME_FSIDLE 0x01 /* fifo_stat & FSVALID = 0x1 when it is idle */ -#define XVME_RESET 0x80 /* Write this and you reset the XVME card */ - -/****************************************************************************** - * - * The xvmeLink structure holds all the xvme-card specific data required - * for the operation of the link. - * - ******************************************************************************/ -struct xvmeLink { - WDOG_ID watchDogId; /* watchdog for timeouts */ - SEM_ID watchDogSem; /* set by the watch dog int handler */ - - unsigned char abortFlag; /* set to 1 if link is being reset by the dog */ - unsigned char txAbortAck; /* set to 1 by txTask to ack abort Sequence */ - unsigned char rxAbortAck; /* set to 1 by rxTask to ack abort Sequence */ - - struct xvmeRegs *bbRegs;/* pointer to board registers */ - - SEM_ID rxInt; /* given when rx interrupts occur */ - - struct bbLink *pbbLink; -}; diff --git a/src/drv/drvRs232.c b/src/drv/drvRs232.c deleted file mode 100644 index 41176e8a8..000000000 --- a/src/drv/drvRs232.c +++ /dev/null @@ -1,550 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 04-13-92 - * EPICS R/S-232 driver for the VxWorks's tty driver - * - * 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 09-30-91 jrw created - * - */ - -#define DRVRS232_C - -#include -#include -#if 0 /* COMMENTED OUT SOME INCLUDES */ -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* COMMENTED OUT SOME INCLUDES */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int drv232Debug = 0; - -static void callbackAbortSerial(); -static void dogAbortSerial(); - -/****************************************************************************** - * - ******************************************************************************/ -#define RSLINK_PRI 50 -#define RSLINK_OPT VX_FP_TASK|VX_STDIO -#define RSLINK_STACK 5000 - - -/****************************************************************************** - * - ******************************************************************************/ -static long -report() -{ - printf("Report for RS-232 driver\n"); - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -static long -init(pparms) -msgDrvIniParm *pparms; -{ - if (drv232Debug) - printf("Init for RS-232 driver\n"); - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgXact structure. - * - * It is also responsible for filling in the msgXact.phwpvt pointer. - * - ******************************************************************************/ -static long -genXact(p) -msgDrvGenXParm *p; -{ - long stat = -1; - char message[100]; - devTy232Link *pdevTy232Link; - - if (drv232Debug) - printf("RS-232 genXact entered for link %d, addr %d, parm %s\n", p->plink->value.gpibio.link, p->plink->value.gpibio.addr, p->plink->value.gpibio.parm); - - p->pmsgXact->phwpvt = p->pmsgXact->pparmBlock->pmsgHwpvt; - - - while ((p->pmsgXact->phwpvt != NULL) && (stat == -1)) - { - pdevTy232Link = (devTy232Link *)(p->pmsgXact->phwpvt->pmsgLink->p); - - if ((pdevTy232Link->link == p->plink->value.gpibio.link) - && (pdevTy232Link->port == p->plink->value.gpibio.addr)) - { - if (pdevTy232Link->pparmBlock != p->pmsgXact->pparmBlock) - { - sprintf(message, "%s: Two different devices on same RS-232 port\n", p->pmsgXact->prec->name); - errMessage(S_db_badField, message); - return(ERROR); - } - else - stat = 0; /* Found the correct hwpvt structure */ - } - else - p->pmsgXact->phwpvt = p->pmsgXact->phwpvt->next; - } - if (stat != 0) - { /* Could not find a msgHwpvt for the right link, create a new one */ - if ((p->pmsgXact->phwpvt = drvMsg_genHwpvt(p->pmsgXact->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - p->pmsgXact->callback.callback = NULL; - p->pmsgXact->psyncSem = NULL; - if (sscanf(p->plink->value.gpibio.parm,"%d", &(p->pmsgXact->parm)) != 1) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid parameter string >%s<\n", p->pmsgXact->prec->name, p->plink->value.gpibio.parm); - errMessage(S_db_badField, message); - return(ERROR); - } - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgHwpvt structure. - * - * It is also responsible for filling in the msgHwpvt.pmsgLink pointer. - * - ******************************************************************************/ -static long -genHwpvt(p) -msgDrvGenHParm *p; -{ - int stat = ERROR; - - if (drv232Debug) - printf("rs232-genHwpvt entered\n"); - - p->pmsgHwpvt->pmsgLink = drv232Block.pmsgLink; - while ((p->pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR)) - { - if ((((devTy232Link *)(p->pmsgHwpvt->pmsgLink->p))->link == p->plink->value.gpibio.link) - && (((devTy232Link *)(p->pmsgHwpvt->pmsgLink->p))->port == p->plink->value.gpibio.addr)) - stat = OK; - else - p->pmsgHwpvt->pmsgLink = p->pmsgHwpvt->pmsgLink->next; - } - if (stat != OK) - { - if ((p->pmsgHwpvt->pmsgLink = drvMsg_genLink(p->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgLink structure. - * - ******************************************************************************/ -static long -genLink(p) -msgDrvGenLParm *p; -{ - char name[20]; - char message[100]; - devTy232Link *pdevTy232Link; - - if (drv232Debug) - printf("In RS-232's genLink, link = %d, addr = %d\n", p->plink->value.gpibio.link,p->plink->value.gpibio.addr); - - switch (p->op) { - case MSG_GENLINK_CREATE: - - if ((p->pmsgLink->p = malloc(sizeof(devTy232Link))) == NULL) - return(ERROR); - - pdevTy232Link = (devTy232Link *)(p->pmsgLink->p); - - pdevTy232Link->link = p->plink->value.gpibio.link; - pdevTy232Link->port = p->plink->value.gpibio.addr; - pdevTy232Link->pparmBlock = p->pparmBlock; - - if ((pdevTy232Link->doggie = wdCreate()) == NULL) - { - printf("RS-232 driver can't create a watchdog\n"); - /* errMessage(******, message); */ - return(ERROR); - } - - sprintf(name, "/tyCo/%d", p->plink->value.gpibio.addr); - - if (drv232Debug) - printf ("in genlink opening >%s<, baud %d\n", name, ((devTy232ParmBlock *)(p->pparmBlock->p))->baud); - - if ((((devTy232Link *)(p->pmsgLink->p))->ttyFd = open(name, O_RDWR, 0)) != -1) - { - if (drv232Debug) - printf("Successful open w/fd=%d\n", pdevTy232Link->ttyFd); - - /* set baud rate and unbuffered mode */ - (void) ioctl (pdevTy232Link->ttyFd, FIOBAUDRATE, ((devTy232ParmBlock *)(p->pparmBlock->p))->baud); - (void) ioctl (pdevTy232Link->ttyFd, FIOSETOPTIONS, ((devTy232ParmBlock *)(p->pparmBlock->p))->ttyOptions); - - pdevTy232Link->callback.callback = callbackAbortSerial; - pdevTy232Link->callback.priority = priorityHigh; - pdevTy232Link->callback.user = (void *) pdevTy232Link; - - return(OK); - } - else - { - printf("RS-232 genLink failed to open the tty port\n"); - free(p->pmsgLink->p); - return(ERROR); - } - - case MSG_GENLINK_ABORT: - if (drv232Debug) - printf("RS-232 genLink called with abort status\n"); - - pdevTy232Link = (devTy232Link *)(p->pmsgLink->p); - /* free(p->pmsgLink->p); Don't forget to take it out of the list */ - return(OK); - } - return(ERROR); -} - -/****************************************************************************** - * - * This function is called to allow the device to indicate that a device-related - * event has occurred. If an event had occurred, it would have to place the - * address of a valid transaction structure in pxact. This xact structure - * will then be processed by the message link task as indicated by the - * return code of this function. - * - * MSG_EVENT_NONE = no event has occurred, pxact not filled in. - * MSG_EVENT_WRITE = event occurred, process the writeOp assoc'd w/pxact. - * MSG_EVENT_READ = event occurred, process the readOp assoc'd w/pxact. - * - * Note that MSG_EVENT_READ only makes sense when returned with a transaction - * that has deferred readback specified for its readOp function. Because if - * it is NOT a deferred readback, it will be done immediately after the writeOp. - * Even if that writeOp was due to a MSG_EVENT_WRITE from this function. - * - ******************************************************************************/ -static long -checkEvent(p) -msgChkEParm *p; -{ - return(MSG_EVENT_NONE); -} - - -static void -dogAbortSerial(pdevTy232Link) -devTy232Link *pdevTy232Link; -{ - logMsg("RS-232 driver watch-dog timeout on link %d, port %d, fd=%d\n", pdevTy232Link->link, pdevTy232Link->port, pdevTy232Link->ttyFd); - - /* Annoying vxWorks implementation... can't IOCTL from here */ - callbackRequest(&(pdevTy232Link->callback)); -} - -static void -callbackAbortSerial(p) -CALLBACK *p; -{ - ((devTy232Link *)(p->user))->dogAbort = TRUE; - - ioctl(((devTy232Link *)(p->user))->ttyFd, FIOCANCEL); - /* I am not sure if I should really do this, but... */ - ioctl(((devTy232Link *)(p->user))->ttyFd, FIOFLUSH); -} - -/****************************************************************************** - * - * This function is used to write a string of characters out to an RS-232 - * device. - * - ******************************************************************************/ -static long -drvWrite(pxact, pwrParm) -msgXact *pxact; -msgStrParm *pwrParm; -{ - devTy232Link *pdevTy232Link = (devTy232Link *)(pxact->phwpvt->pmsgLink->p); - int len; - char *out; - char in; - - if (wdStart(pdevTy232Link->doggie, ((devTy232ParmBlock *)(pxact->pparmBlock->p))->dmaTimeout, dogAbortSerial, pdevTy232Link) == ERROR) - { - printf("RS-232 driver can not start watchdog timer\n"); - /* errMessage(***,message); */ - pxact->status = XACT_IOERR; - return(pxact->status); - } - - if (((devTy232ParmBlock *)(pxact->pparmBlock->p))->flags & ECHO) - { /* ping-pong the characters out */ - - /*BUG ??? This will only work if we are sure that the RX buffer is clean */ - ioctl(pdevTy232Link->ttyFd, FIORFLUSH); - - out = pwrParm->buf; - while ((*out != '\0') && (pxact->status == XACT_OK)) - { - if (drv232Debug > 5) - printf("out >%c<\n", *out); - if (write(pdevTy232Link->ttyFd, out, 1) != 1) - { - printf("RS-232 write error on link %d, port %d\n", pdevTy232Link->link, pdevTy232Link->port); - pxact->status = XACT_IOERR; - } - else - { - if (read(pdevTy232Link->ttyFd, &in, 1) != 1) - { -printf("Read problem encountered in echo reading mode of a write operation\n"); - if (pdevTy232Link->dogAbort) - pxact->status = XACT_TIMEOUT; - else - pxact->status = XACT_IOERR; - } - else - { - if (*out != in) - printf("echo response out of sync! sent >%c< got >%c<\n", *out, in); - - if (drv232Debug > 5) - printf("in >%c<\n", in); - - if ((*out == '\r') && (((devTy232ParmBlock *)(pxact->pparmBlock->p))->flags & CRLF)) - { - if (read(pdevTy232Link->ttyFd, &in, 1) != 1) - { -printf("Read problem encountered in echo reading mode of a write operation\n"); - if (pdevTy232Link->dogAbort) - pxact->status = XACT_TIMEOUT; - else - pxact->status = XACT_IOERR; - } - else - { - if (drv232Debug > 5) - printf("in >%c<\n", in); - } - } - } - } - out++; - } - } - else - { - if (pwrParm->len == -1) - len = strlen(pwrParm->buf); - else - len = pwrParm->len; - - if (drv232Debug > 4) - printf("block-writing >%s<\n", pwrParm->buf); - - if (write(pdevTy232Link->ttyFd, pwrParm->buf, len) != len) - { - printf("RS-232 write error on link %d, port %d\n", pdevTy232Link->link, pdevTy232Link->port); - pxact->status = XACT_IOERR; - } - } - if (wdCancel(pdevTy232Link->doggie) == ERROR) - printf("Can not cancel RS-232 watchdog timer\n"); - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to read a string of characters from an RS-232 device. - * - ******************************************************************************/ -static long -drvRead(pxact, prdParm) -msgXact *pxact; -msgStrParm *prdParm; -{ - devTy232Link *pdevTy232Link = (devTy232Link *)(pxact->phwpvt->pmsgLink->p); - int len; - int clen; - char *ch; - int flags; - int eoi; - devTy232ParmBlock *pdevTy232ParmBlock = (devTy232ParmBlock *)(pxact->pparmBlock->p); - - pdevTy232Link->dogAbort = FALSE; - if (wdStart(pdevTy232Link->doggie, pdevTy232ParmBlock->dmaTimeout, dogAbortSerial, pdevTy232Link) == ERROR) - { - printf("RS-232 driver can not start watchdog timer\n"); - /* errMessage(***,message); */ - pxact->status = XACT_IOERR; - return(pxact->status); - } - - ch = prdParm->buf; - len = prdParm->len - 1; - - flags = pdevTy232ParmBlock->flags; -/* BUG -- This should have a timeout check specified in here */ - if ((pdevTy232ParmBlock->eoi != -1) || (flags & KILL_CRLF)) - { - eoi = 0; - while ((!eoi) && (len > 0)) - { - if (read(pdevTy232Link->ttyFd, ch, 1) != 1) - { -printf("Read problem encountered in eoi/KILL_CRLF reading mode\n"); - if (pdevTy232Link->dogAbort) - pxact->status = XACT_TIMEOUT; - else - pxact->status = XACT_IOERR; - eoi = 1; - } - else - { - if (drv232Debug > 6) - printf("in >%c<\n", *ch); - - if (*ch == pdevTy232ParmBlock->eoi) - eoi = 1; - - if (!(flags & KILL_CRLF) || ((*ch != '\n') && (*ch != '\r'))) - { - ch++; - len--; /* To count the \n's and \r's or not to count... */ - } - } - } - if (len == 0) - { - printf("buffer length overrun during read operation\n"); - pxact->status = XACT_LENGTH; - } - - *ch = '\0'; - } - else - { /* Read xact->rxLen bytes from the device */ - while(len) - { - clen = read(pdevTy232Link->ttyFd, ch, len); - if (pdevTy232Link->dogAbort) - { -printf("Read problem encountered in raw mode\n"); - pxact->status = XACT_TIMEOUT; - len = 0; - } - else - { - len -= clen; - ch += clen; - } - } - *ch = '\0'; - } - if (drv232Debug) - printf("drvRead: got >%s<\n", prdParm->buf); - - if (wdCancel(pdevTy232Link->doggie) == ERROR) - printf("Can not cancel RS-232 watchdog timer, dogAbort=%d \n", pdevTy232Link->dogAbort); - - return(pxact->status); -} - -static long -drvIoctl(cmd, pparm) -int cmd; -void *pparm; -{ - switch (cmd) { - case MSGIOCTL_REPORT: - return(report()); - case MSGIOCTL_INIT: - return(init(pparm)); - case MSGIOCTL_INITREC: - printf("drv232Block.drvIoctl got a MSGIOCTL_INITREC request!\n"); - return(ERROR); - case MSGIOCTL_GENXACT: - return(genXact(pparm)); - case MSGIOCTL_GENHWPVT: - return(genHwpvt(pparm)); - case MSGIOCTL_GENLINK: - return(genLink(pparm)); - case MSGIOCTL_CHECKEVENT: - return(checkEvent(pparm)); - case MSGIOCTL_COMMAND: /* BUG -- finish this routine! */ - return(ERROR); - } - return(ERROR); -} - - -msgDrvBlock drv232Block = { - "RS232", - RSLINK_PRI, - RSLINK_OPT, - RSLINK_STACK, - NULL, - drvWrite, - drvRead, - drvIoctl -}; diff --git a/src/drv/drvStc.c b/src/drv/drvStc.c deleted file mode 100644 index 0a48ab78d..000000000 --- a/src/drv/drvStc.c +++ /dev/null @@ -1,290 +0,0 @@ -/* drvStc.c */ -/* base/src/drv $Id$ */ -/* - * The following are specific driver routines for the AMD STC - * - * NOTE: if multiple threads use these routines at once you must provide locking - * so command/data sequences are gauranteed. See mz8310_driver.c for examples. - * - * - * Author: Jeff Hill - * Date: Feb 89 - * - * 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: - * ----------------- - * - * joh 022089 Init Release - * joh 042889 Added read back - * joh 111789 Fixed reset goes to byte mode bug - * joh 121090 Fixed confusion about the polarity of internal/external - * clock between DB and the drivers. - * joh 110791 Prevent the stc from generating tc prior to the trigger - * in delayed pulse mode by forcing edge 0 delays of zero to be - * a delay of one instead. - * joh 010491 force all edge 0 delays less than two to two - * joh 082493 ANSI C and EPICS return codes - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - - - -/* - * stc_io_report() - */ -stcStat stc_io_report( -volatile uint8_t *pcmd, -volatile uint16_t *pdata -) -{ - uint8_t cmd; - uint16_t data; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - - /* - * addd AMD STC status here - */ - - return STC_SUCCESS; -} - - - -/* - * stc_init() - */ -stcStat stc_init( -volatile uint8_t *pcmd, -volatile uint16_t *pdata, -unsigned master_mode -) -{ - uint8_t cmd; - uint16_t data; - unsigned channel; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - - /* - * go to 16 bit mode in order to test the master mode register - */ - STC_BUS16; - if(master_mode != STC_MASTER_MODE){ - - /* - * start in a known state - */ - STC_RESET; - - /* - * required since the reset puts it in byte mode - */ - STC_BUS16; - STC_SET_MASTER_MODE(master_mode); - for(channel=0; channel=CHANONCHIP) - return S_dev_badSignalNumber; - - STC_CTR_READ(mode, edge0, edge1); - - /* - * Only return values if the counter is in the proper mode - * see stc_one_shot() for info on conversions and functions selected - * by these bit fields - */ - if(mode == 0xc16a){ - *int_source = FALSE; - *preset = TRUE; - *edge0_count = ~edge0; - *edge1_count = ~edge1+1; - } - else if(mode == 0xc162){ - *int_source = FALSE; - *preset = FALSE; - *edge0_count = edge0-1; - *edge1_count = edge1; - } - else if(mode == 0xcb6a){ - *int_source = TRUE; - *preset = TRUE; - *edge0_count = ~edge0; - *edge1_count = ~edge1+1; - } - else if(mode == 0xcb62){ - *int_source = TRUE; - *preset = FALSE; - *edge0_count = edge0-1; - *edge1_count = edge1; - } - else - return S_dev_internal; - - return STC_SUCCESS; -} - - - -/* - * stc_one_shot() - */ -stcStat stc_one_shot( -unsigned preset, -unsigned edge0_count, -unsigned edge1_count, -volatile uint8_t *pcmd, -volatile uint16_t *pdata, -unsigned channel, -unsigned int_source -) -{ - uint8_t cmd; - uint16_t data; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - if(channel>=CHANONCHIP) - return S_dev_badSignalNumber; - - /* - * joh 110791 - * Prevent the stc from generating tc prior to the trigger - * in delayed pulse mode by forcing edge 0 delays of zero to be - * a delay of one instead. - * - * 010492 - * Strange extra edges occur when the delay is 0 or 1 - * and the counter is reinitialized to a width of - * zero so I have disabled a delay of one also - * - * These extra edges occur when TC is set - */ - - if(edge0_count < 2) - edge0_count = 2; - - STC_DISARM; - - /* - * active positive going edge (gate input) - * count on the rising edge of source - * ctr source: (F1- internal) (SRC1- external) - * mode L - Hardware triggered delayed pulse one-shot - * binary count - * count down (count up if preset is TRUE) - * TC toggled output - * - * see chapter 7 of the Am9513 STC tech man concerning count + 1 - * - */ - - /* - * NOTE: I must be able to read back the state of the preset later - * so I encode this information in the count down/up bit. - * count up on TRUE preset - * count down on FALSE preset - * - * see stc_one_shot_read() above - */ - if(int_source){ - if(preset) - STC_CTR_INIT(0xcb6a, ~edge0_count, ~edge1_count+1) - else - STC_CTR_INIT(0xcb62, edge0_count+1, edge1_count); - }else{ - if(preset) - STC_CTR_INIT(0xc16a, ~edge0_count, ~edge1_count+1) - else - STC_CTR_INIT(0xc162, edge0_count+1, edge1_count); - } - - STC_LOAD; - /* - *see chapter 7 of the Am9513 STC tech man concerning this step - */ - - STC_STEP; - - STC_SET_TC(preset); - - /* - * Only arm counter if the pulse has a finite duration - */ - if(edge1_count != 0){ - STC_ARM; - } - - return STC_SUCCESS; -} - - - diff --git a/src/drv/drvStc.h b/src/drv/drvStc.h deleted file mode 100644 index 5d4a6203b..000000000 --- a/src/drv/drvStc.h +++ /dev/null @@ -1,107 +0,0 @@ -/* drvStc.h */ -/* base/src/drv $Id$ */ -/* - * The following are specific driver routines for the AMD STC - * - * NOTE: if multiple threads use these routines at once you must provide locking - * so command/data sequences are gauranteed. See mz8310_driver.c for examples. - * - * - * Author: Jeff Hill - * Date: Feb 89 - * - * 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: - * ----------------- - * - * joh 022089 Init Release - * joh 082493 ANSI C and EPICS return codes - */ - -/* - * AMD STC constants - */ -#define CHANONCHIP 5U -#define CHIPCHAN (channel%CHANONCHIP) -#define CHIPNUM (channel/CHANONCHIP) - -#define STC_RESET *pcmd = 0xffU -#define STC_BUS16 *pcmd = 0xefU -#define STC_SET_MASTER_MODE(D) {*pcmd = 0x17U; *pdata=(D);} -#define STC_MASTER_MODE (*pcmd = 0x17U, *pdata) - -#define STC_CTR_INIT(MODE,LOAD,HOLD)\ -{*pcmd = CHIPCHAN+1; *pdata = (MODE); *pdata = (LOAD); *pdata= (HOLD);} - -#define STC_CTR_READ(MODE,LOAD,HOLD)\ -{*pcmd = CHIPCHAN+1; (MODE) = *pdata; (LOAD) = *pdata; (HOLD) = *pdata;} - -#define STC_SET_TC(D) *pcmd = 0xe0U | ((D)?8:0)|(CHIPCHAN+1U) - -#define STC_LOAD *pcmd = 0x40U | 1<<(CHIPCHAN) -#define STC_STEP *pcmd = 0xf0U | (CHIPCHAN+1U) -#define STC_ARM *pcmd = 0x20U | 1< -#include - -#include - -struct pulse{ -double offset; -double width; -}; - - - -/* - * - * time_driver_read() - * - * - */ -time_driver_read - ( - card, /* 0 through ... */ - channel, /* 0 through chans on card */ - card_type, /* module type as stored in GTA DB */ - int_source, /* (TRUE)External/ (FALSE)Internal source */ - preset, /* TRUE or COMPLEMENT logic */ - pulses, /* ptr to array of structure describing pulses */ - npulses, /* N elements found */ - npulmax /* N elements in the caller's array */ - ) -unsigned int card; -unsigned int channel; -unsigned int card_type; -unsigned int *int_source; -int *preset; -struct pulse *pulses; -unsigned int *npulses; -unsigned int npulmax; -{ - int status; - - *npulses=0; - - switch(card_type){ - case MZ8310: - if(npulmax<1) - return ERROR; - status = mz8310_one_shot_read ( - preset, - &pulses->offset, - &pulses->width, - card, - channel, - int_source - ); - if(status==0) - *npulses=1; - - return status; - case VXI_AT5_TIME: - if(npulmax<1) - return ERROR; - status = at5vxi_one_shot_read ( - preset, - &pulses->offset, - &pulses->width, - card, - channel, - int_source - ); - if(status==0) - *npulses=1; - - return status; - case DG535: - break; - default: - break; - } - logMsg("time_driver: No support for that type of timing card\n"); - return ERROR; -} - - -time_driver ( - card, /* 0 through ... */ - channel, /* 0 through chans on card */ - card_type, /* module type as stored in GTA DB */ - int_source, /* (TRUE)External/ (FALSE)Internal source */ - preset, /* TRUE or COMPLEMENT logic */ - pulses, /* ptr to array of structure describing pulses */ - npulses, /* N elements in this array */ - eventrtn, /* routine to run on events */ - eventrtnarg /* argument to above rtn */ - ) -unsigned int card; -unsigned int channel; -unsigned int card_type; -unsigned int int_source; -int preset; -struct pulse *pulses; -unsigned int npulses; -void (*eventrtn)(); -unsigned int eventrtnarg; -{ - - switch(card_type){ - case MZ8310: - if(npulses != 1) - return ERROR; - return mz8310_one_shot ( - preset, - pulses->offset, - pulses->width, - card, - channel, - int_source, - eventrtn, - eventrtnarg - ); - case VXI_AT5_TIME: - if(npulses != 1) - return ERROR; - return at5vxi_one_shot ( - preset, - pulses->offset, - pulses->width, - card, - channel, - int_source, - eventrtn, - eventrtnarg - ); - case DG535: - break; - default: - break; - } - logMsg("time_driver: No support for that type of timing card\n"); - return ERROR; -} - - - -time_test() -{ - unsigned int card=0; - unsigned int channel=0; - unsigned int card_type=MZ8310; - unsigned int int_source=1; - int preset=1; - static struct - pulse pulses={.00001,.00001}; - unsigned int npulses = 1; - - unsigned int t_int_source; - int t_preset; - struct pulse t_pulses; - unsigned int t_npulses; - - int status; - - status = - time_driver ( - card, /* 0 through ... */ - channel, /* 0 through chans on card */ - card_type, /* module type as stored in GTA DB */ - int_source, /* (TRUE)External/ (FALSE)Internal source */ - preset, /* TRUE or COMPLEMENT logic */ - &pulses, /* ptr to array of structure describing pulses */ - npulses, /* N elements in this array */ - NULL, /* routine to run on events */ - NULL /* argument to above rtn */ - ); - if(status==ERROR) - return ERROR; - - - status = - time_driver_read( - card, /* 0 through ... */ - channel, /* 0 through chans on card */ - card_type, /* module type as stored in GTA DB */ - &t_int_source, /* (TRUE)External/ (FALSE)Internal source */ - &t_preset, /* TRUE or COMPLEMENT logic */ - &t_pulses, /* ptr to array of structure describing pulses */ - &t_npulses, /* N elements found */ - 1 /* max N elements in this array */ - ); - if(status==ERROR) - return ERROR; - - - logMsg( "wrote: preset %x internal-clk %x delay %f width %f \n", - preset, - int_source, - pulses.offset, - pulses.width); - logMsg( "read: preset %x internal-clk %x delay %f width %f count %x\n", - t_preset, - t_int_source, - t_pulses.offset, - t_pulses.width, - t_npulses); - return OK; -} diff --git a/src/drv/drvVmi4100.c b/src/drv/drvVmi4100.c deleted file mode 100644 index 3df1ebbec..000000000 --- a/src/drv/drvVmi4100.c +++ /dev/null @@ -1,203 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * subroutines that are used to interface to the vme analog output cards - * - * Author: Bob Dalesio - * Date: 9-26-88 - * - * 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-09-88 lrd add LED light status to Ziomek-085 - * .02 02-08-89 lrd addresses from module_types.h - * use 085 structure - * .03 03-17-89 lrd add ao_read routine - * .04 03-29-89 lrd return correct status on write - * .05 11-20-89 joh added call to the at5 vxi driver - * .06 06-08-90 mrk fixed bug (R Daly found) for VMI4100 - * .07 10-31-91 bg broke vmi4100 driver out of ao_driver.c - * broke vmi4100 code out of io_report and - * created vmi400_io_report() - * .08 01-10-92 bg Added levels to io_report and warning message - * that raw values cannot be read from vmi4100 - * card even it the level is 1. - * .09 08-05-92 joh arguments to init routine now conform with the - * standard - * .10 08-05-92 joh added EPICS driver dispatch table - * .11 08-05-92 joh moved parameters from ao_driver.h to here - * .12 08-11-92 joh num of cards now dyn configurable - * .13 08-24-93 mrk removed use of variable base_addr - */ - -static char *sccsID = "@(#)drvVmi4100.c 1.5\t8/27/93"; - -#include -#include -#include -#include -#include "module_types.h" - -/* VMIVME 4100 defines */ -#define MAX_AO_VMI_CARDS (ao_num_cards[VMI4100]) -#define VMI_MAXCHAN (ao_num_channels[VMI4100]) -#define VMI_ENABLE_OUT 0xc100 /*Fail LED off, enable P3 output.*/ - -/* memory structure of the Xycom 4100 Interface */ - -union aoVMI{ - unsigned short csr; - unsigned short data[16]; -}; - -long vmi4100_io_report(); -long vmi4100_init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvVmi4100={ - 2, - vmi4100_io_report, - vmi4100_init}; - -LOCAL -unsigned short **pao_vmi4100; - -LOCAL -int vmi4100_addr; - - -/* - * vmi4100_init - * - * intialize the VMI analog outputs - */ -long vmi4100_init() -{ - register unsigned short **pcards_present; - short shval; - int status; - register union aoVMI *pcard; - register short i; - - pao_vmi4100 = (unsigned short **) - calloc(MAX_AO_VMI_CARDS, sizeof(*pao_vmi4100)); - if(!pao_vmi4100){ - return ERROR; - } - - pcards_present = pao_vmi4100; - - if ((status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,ao_addrs[VMI4100], &vmi4100_addr)) != OK){ - printf("Addressing error in vmi4100 driver\n"); - return ERROR; - } - - pcard = (union aoVMI *)((int)vmi4100_addr); - - - /* mark each card present into the card present array */ - for (i = 0; i < ao_num_cards[VMI4100]; i++, pcard+= VMI_MAXCHAN, pcards_present += 1) { - - if (vxMemProbe(pcard,READ,sizeof(short),&shval) == OK) { - *pcards_present = (unsigned short *)pcard; - pcard->csr = VMI_ENABLE_OUT; - } - else{ - *pcards_present = 0; - - } - } - - return OK; -} - - -/* - * vmi4100_driver - * - * VMI4100 analog output driver - */ -vmi4100_driver(card,chan,prval,prbval) -register unsigned short card; -register unsigned short chan; -unsigned short *prval; -unsigned short *prbval; -{ - register union aoVMI *paoVMI; - - /* check on the card and channel number as kept in module_types.h */ - - if ((paoVMI= (union aoVMI *)pao_vmi4100[card]) == 0) - return(-1); - paoVMI->data[chan] = *prval; - - return (0); -} - - -/* - * vmi4100_read - * - * VME analog output driver - */ -vmi4100_read(card,chan,pval) -register unsigned short card; -register unsigned short chan; -unsigned short *pval; -{ - register unsigned short *pcard; - - /* check on the card and channel number as kept in module_types.h */ - - *pval = 0; /* can't read the VMIC 4100 - good design! */ - return (-1); -} - -/* - * vmi4100_io_report - * - * VME analog output driver - */ - -long vmi4100_io_report(level) - short int level; - { - register int i; - - for (i = 0; i < MAX_AO_VMI_CARDS; i++){ - if (pao_vmi4100[i]){ - printf("AO: VMI4100: card %d ",i); - if(level >0){ - printf("VMI4100 card cannot be read.\n"); - } - else - printf("\n"); - - } - } - - return OK; - } - diff --git a/src/drv/drvXy010.c b/src/drv/drvXy010.c deleted file mode 100644 index b280ad0d8..000000000 --- a/src/drv/drvXy010.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * initialize the Xycom SRM010 bus controller card - */ -/* base/src/drv $Id$ */ -/* Author: Betty Ann Gunther - * Date: 06-30-29 - * Initialize xy010 bus controller - * - * 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: - * ----------------- - * .00 08-11-92 joh Verify the xy010's id to prevent confusion - * with the mv167's GCSR which with an unmodified - * sysLib.c will show up in the xy010's addr - * space - * .01 08-11-92 joh Moved base addr to module_types.h - * ... - */ - -static char *sccsID = "@(#)drvXy010.c 1.3\t6/3/93"; - -#include -#include - -#include -#include - - -/* - * These will hopefully go away - * as the drivers become more autonomous - */ - -static long xy010_id_check(char *); -static long xy010_io_report(int); -static long xy010_init(void); -static long xy010_map(void); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvXy010={ - 2, - xy010_io_report, - xy010_init}; - - -#define CSR_ADDR 0x81 -#define XY010_ID "VMEIDXYC010" -#define XY_LED 0x3 /* set the Xycom status LEDs to OK */ - -LOCAL char *xy010_addr; - - -/* - * initialize the Xycom SRM010 bus controller card - */ -long -xy010_init() -{ - char *pctlreg; - - if(xy010_map()<0){ - return ERROR; - } - - if(xy010_id_check(xy010_addr)<0){ - return OK; - } - - /* Pointer to status control register. */ - pctlreg = xy010_addr + CSR_ADDR; - *pctlreg = XY_LED; - - return OK; -} - - -/* - * - * xy010_map() - * - * - */ -LOCAL -long xy010_map() -{ - int status; - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - xy010ScA16Base, - &xy010_addr); - - if (status < 0){ - printf("%s: xy010 A16 base addr map failed\n", __FILE__); - return ERROR; - } - - return OK; -} - - -/* - * - * xy010_id_check() - * - * - */ -LOCAL -long xy010_id_check(pBase) -char *pBase; -{ - char *pID; - char *pCmp; - char ID; - int status; - - pID = pBase; - pCmp = XY010_ID; - while(*pCmp){ - pID++; /* ID chars stored at odd addr */ - status = vxMemProbe(pID, READ, sizeof(ID), &ID); - if(status < 0){ - return ERROR; - } - if(*pCmp != ID){ - return ERROR; - } - pID++; - pCmp++; - } - return OK; -} - - -/* - * - * xy010_io_report() - * - * - */ -long xy010_io_report(int level) -{ - char id; - - if(xy010_map()<0){ - return ERROR; - } - - if (xy010_id_check(xy010_addr) == OK) { - printf("SC: XY010:\tcard 0\n"); - } - - return OK; -} - - diff --git a/src/drv/drvXy210.c b/src/drv/drvXy210.c deleted file mode 100644 index e02c61ebc..000000000 --- a/src/drv/drvXy210.c +++ /dev/null @@ -1,185 +0,0 @@ -/* xy210_driver.c */ -/* base/src/drv $Id$ */ -/* - * subroutines that are used to interface to the binary input cards - * - * Author: Bob Dalesio - * Date: 6-13-88 - * - * 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 02-09-89 lrd moved I/O addresses to module_types.h - * .02 11-20-89 joh added call to at5vxi driver - * .03 09-11-91 bg added bi_io_report - * .04 03-09-92 bg added levels to xy210_io_report. Gave - * xy210_io_report the ability to read raw - * values from card if level > 1 - * .05 08-10-92 joh merged include file - * .06 08-25-92 mrk made masks a macro - * .07 08-25-92 mrk replaced bi_driver by xy210_driver - * .08 09-15-93 mrk Made report shorter - */ - -/* - * Code Portions: - * - * bi_driver_init Finds and initializes all binary input cards present - * bi_driver Interfaces to the binary input cards present - */ - - -#include -#include -#include -#include - -static long report(); -static long init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvXy210={ - 2, - report, - init}; - -static long report(level) - int level; -{ - xy210_io_report(level); - return(0); -} - -static long init() -{ - - xy210_driver_init(); - return(0); -} - - -static char SccsId[] = "@(#)drvXy210.c 1.5\t9/20/93"; - -#define MAX_XY_BI_CARDS (bi_num_cards[XY210]) - -/* Xycom 210 binary input memory structure */ -/* Note: the high and low order words are switched from the io card */ -struct bi_xy210{ - char begin_pad[0xc0]; /* nothing until 0xc0 */ -/* unsigned short csr; */ /* control status register */ -/* char pad[0xc0-0x82]; */ /* get to even 32 bit boundary */ - unsigned short low_value; /* low order 16 bits value */ - unsigned short high_value; /* high order 16 bits value */ - char end_pad[0x400-0xc0-4]; /* pad until next card */ -}; - - -/* pointers to the binary input cards */ -struct bi_xy210 **pbi_xy210s; /* Xycom 210s */ - -/* test word for forcing bi_driver */ -int bi_test; - -static char *xy210_addr; - - -/* - * BI_DRIVER_INIT - * - * intialization for the binary input cards - */ -xy210_driver_init(){ - int bimode; - int status; - register short i; - struct bi_xy210 *pbi_xy210; - - pbi_xy210s = (struct bi_xy210 **) - calloc(MAX_XY_BI_CARDS, sizeof(*pbi_xy210s)); - if(!pbi_xy210s){ - return ERROR; - } - - /* initialize the Xycom 210 binary input cards */ - /* base address of the xycom 210 binary input cards */ - if ((status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,bi_addrs[XY210],&xy210_addr)) != OK){ - printf("Addressing error in xy210 driver\n"); - return ERROR; - } - pbi_xy210 = (struct bi_xy210 *)xy210_addr; - /* determine which cards are present */ - for (i = 0; i high_value << 16) /* high */ - + pbi_xy210s[card]->low_value; /* low */ - - /* apply mask */ - - *prval = work & mask; - - return (0); -} - -void xy210_io_report(level) - short int level; - { - int card; - unsigned int value; - - for (card = 0; card < bi_num_cards[XY210]; card++){ - if (pbi_xy210s[card]){ - value = (pbi_xy210s[card]->high_value << 16) /* high */ - + pbi_xy210s[card]->low_value; /* low */ - printf("BI: XY210: card %d value=0x%08.8x\n",card,value); - } - } -} diff --git a/src/drv/drvXy220.c b/src/drv/drvXy220.c deleted file mode 100644 index db17fb713..000000000 --- a/src/drv/drvXy220.c +++ /dev/null @@ -1,220 +0,0 @@ -/* xy220_driver.c */ -/* base/src/drv $Id$ */ -/* - * subroutines that are used to interface to the binary output cards - * - * Author: Bob Dalesio - * Date: 5-26-88 - * - * 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 10-31-91 bg broke xy220 driver out of bo_driver.c - * broke xy220 code out of io_report and - * created xy220_io_report(). - * Added sysBusToLocalAdrs. - * .02 02-03-92 bg Gave xy220_io_report the ability to - * read raw values from card if level > 1. - * .03 08-10-92 joh merged potions of bo_driver.h - * .04 08-25-92 mrk made masks a macro - */ - -static char SccsId[] = "@(#)drvXy220.c 1.6\t9/20/93"; - -/* - * Code Portions: - * - * bo_drv_init Finds and initializes all binary output cards present - * bo_driver Interfaces to the binary output cards present - */ - -#include -#include -#include "module_types.h" -#include - -static long report(); -static long init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvXy220={ - 2, - report, - init}; -static long report(level) - int level; -{ - xy220_io_report(level); - return(0); -} - -static long init() -{ - - xy220_driver_init(); - return(0); -} - - -#define XY_LED 0x3 /* set the Xycom status LEDs to OK */ -#define XY_SOFTRESET 0x10 /* reset the IO card */ - -/* maximum number of VME binary output cards per IOC */ -#define MAX_XY220_BO_CARDS bo_num_cards[XY220] - -/* Xycom 220 binary output memory structure */ -struct bo_xy220{ - char begin_pad[0x80]; /* nothing until 0x80 */ - short csr; /* control status register */ - unsigned short low_value; /* low order 16 bits value */ - unsigned short high_value; /* high order 16 bits value */ - char end_pad[0x400-0x80-6]; /* pad until next card */ -}; - - -/* pointers to the binary output cards */ -struct bo_xy220 **pbo_xy220s; /* Xycom 220s */ - - -/* - * XY220_DRIVER_INIT - * - * intialization for the xy220 binary output cards - */ -int xy220_driver_init(){ - int bomode; - int status; - register short i; - struct bo_xy220 *pbo_xy220; - - pbo_xy220s = (struct bo_xy220 **) - calloc(MAX_XY220_BO_CARDS, sizeof(*pbo_xy220s)); - if(!pbo_xy220s){ - return ERROR; - } - - /* initialize the Xycom 220 binary output cards */ - /* base address of the xycom 220 binary output cards */ - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - bo_addrs[XY220], - &pbo_xy220); - if (status != OK){ - printf("%s: xy220 A16 base map failure\n", __FILE__); - return ERROR; - } - - /* determine which cards are present */ - for (i = 0; i < MAX_XY220_BO_CARDS; i++,pbo_xy220++){ - if (vxMemProbe(pbo_xy220,READ,sizeof(short),&bomode) == OK){ - pbo_xy220s[i] = pbo_xy220; - pbo_xy220s[i]->csr = XY_SOFTRESET; - pbo_xy220s[i]->csr = XY_LED; - }else{ - pbo_xy220s[i] = 0; - } - } - return(0); -} - -/* - * XY220_DRIVER - * - * interface to the xy220 binary outputs - */ - -int xy220_driver(card,val,mask) -register unsigned short card; -register unsigned int *val; -unsigned int mask; -{ - register unsigned int work; - - /* verify card exists */ - if (!pbo_xy220s[card]) - return (-1); - - /* use structure to handle high and low short swap */ - /* get current output */ - work = (pbo_xy220s[card]->high_value << 16) - + pbo_xy220s[card]->low_value; - - /* alter specified bits */ - work = (work & ~mask) | ((*val) & mask); - - /* write new output */ - pbo_xy220s[card]->high_value = (unsigned short)(work >> 16); - pbo_xy220s[card]->low_value = (unsigned short)work; - -return (0); -} - -/* - * xy220_read - * - * read the binary output - */ -int xy220_read(card,mask,pval) -register unsigned short card; -unsigned int mask; -register unsigned int *pval; -{ - register unsigned int work; - - /* verify card exists */ - if (!pbo_xy220s[card]) - return (-1); - /* readback */ - *pval = (pbo_xy220s[card]->high_value << 16) + pbo_xy220s[card]->low_value; - - *pval &= mask; - - return(0); - -} - -#define masks(K) ((1<high_value << 16) /* high */ - + pbo_xy220s[card]->low_value; /* low */ - printf("BO: XY220: card %d value=0x%08.8x\n",card,value); - } - } - - } diff --git a/src/drv/drvXy240.c b/src/drv/drvXy240.c deleted file mode 100644 index c38c5e950..000000000 --- a/src/drv/drvXy240.c +++ /dev/null @@ -1,526 +0,0 @@ -/* xy240_driver.c */ -/* base/src/drv $Id$ */ -/* - * routines used to test and interface with Xycom240 - * digital i/o module - * - * Author: B. Kornke - * Date: 11/20/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 06-25-92 bg Added driver to code. Added xy240_io_report - * to it. Added copyright disclaimer. - * .02 08-10-92 joh merged xy240_driver.h into this source - * .03 08-11-92 joh fixed use of XY240 where XY240_BI or XY240_BO - * should have been used - * .04 08-11-92 joh now allows for runtime reconfiguration of - * the addr map - * .05 08-25-92 mrk added DSET; made masks a macro - * .06 08-26-92 mrk support epics I/O event scan - * .07 08-26-92 joh task params from task params header - * .08 08-26-92 joh removed STDIO task option - * .09 08-26-92 joh increased stack size for V5 - * .10 08-26-92 joh increased stack size for V5 - * .11 08-27-92 joh fixed no status return from bo driver - * .12 09-03-92 joh fixed wrong index used when testing for card - * present - * .13 09-03-92 joh fixed structural problems in the io - * report routines which caused messages to - * be printed even when no xy240's are present - * .14 09-17-92 joh io report now tabs over detailed info - * .15 09-18-92 joh documentation - * .16 08-02-93 mrk Added call to taskwdInsert - * .17 08-04-93 mgb Removed V5/V4 and EPICS_V2 conditionals - */ - -#include "vxWorks.h" -#include "taskLib.h" -#include "vme.h" -#include "module_types.h" -#include "task_params.h" -#include -#include -#include -#include - -#define XY240_ADDR0 (bi_addrs[XY240_BI]) -#define XY240_MAX_CARDS (bi_num_cards[XY240_BI]) -#define XY240_MAX_CHANS (bi_num_channels[XY240_BI]) - -#define masks(K) ((1<dptr; - -} -#endif - -/* - * - *dio_scan - * - *task to check for change of state - * - */ -dio_scan() - -{ - int i; - int first_scan,first_scan_complete; - - for(;;){ - if(interruptAccept) break; - taskDelay(vxTicksPerSecond/30); - } - first_scan_complete = FALSE; - first_scan = TRUE; - for (;;) - { - for (i = 0; i < XY240_MAX_CARDS; i++) - { - if (dio[i].dptr) - if (((dio[i].dptr->port0_1) ^ (dio[i].sport0_1)) || - ((dio[i].dptr->port2_3) ^ (dio[i].sport2_3)) - || first_scan) - { - /* printf("io_scanner_wakeup for card no %d\n",i); */ - scanIoRequest(dio[i].ioscanpvt); - dio[i].sport0_1 = dio[i].dptr->port0_1; - dio[i].sport2_3 = dio[i].dptr->port2_3; - } - } - if (first_scan){ - first_scan = 0; - first_scan_complete = 1; - } - taskDelay(vxTicksPerSecond/30); - } -} - - - -/*DIO DRIVER INIT - * - *initialize xy240 dig i/o card - */ -xy240_init() -{ - short junk; - register short i; - struct dio_xy240 *pdio_xy240; - int tid; - int status; - int at_least_one_present = FALSE; - - /* - * allow for runtime reconfiguration of the - * addr map - */ - dio = (struct dio_rec *) calloc(XY240_MAX_CARDS, sizeof(*dio)); - if(!dio){ - return ERROR; - } - - status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,XY240_ADDR0,&pdio_xy240); - if (status != OK){ - printf("%s: Unable to map the XY240 A16 base addr\n", __FILE__); - return ERROR; - } - - for (i = 0; i < XY240_MAX_CARDS; i++, pdio_xy240++){ - - if (vxMemProbe(pdio_xy240,READ,2,&junk) != OK){ - dio[i].dptr = 0; - continue; - } - - /* - * register initialization - */ - pdio_xy240->csr = 0x3; - pdio_xy240->iclr_vec = 0x00; /*clear interrupt input register latch*/ - pdio_xy240->flg_dir = 0xf0; /*ports 0-3,input;ports 4-7,output*/ - dio[i].sport2_3 = pdio_xy240->port2_3; /*read and save high values*/ - dio[i].dptr = pdio_xy240; - at_least_one_present = TRUE; - scanIoInit(&dio[i].ioscanpvt); - } - - if (at_least_one_present) - { - if ((tid = taskNameToId(XY240_NAME)) != ERROR){ - taskwdRemove(tid); - taskDelete(tid); - } - - status = taskSpawn( - XY240_NAME, - XY240_PRI, - XY_240_OPT, - XY_240_STACK, - dio_scan); - if (status == ERROR){ - printf("Unable to create XY240 scan task\n"); - } - else taskwdInsert(status,NULL,NULL); - } - - - - return OK; - -} - -xy240_getioscanpvt(card,scanpvt) -short card; -IOSCANPVT *scanpvt; -{ - if ((card >= XY240_MAX_CARDS) || (!dio[card].dptr)) return(0); - *scanpvt = dio[card].ioscanpvt; - return(0); -} - - -/* - * XY240_BI_DRIVER - * - *interface to binary inputs - */ - -xy240_bi_driver(card,mask,prval) -register short card; -unsigned int mask; -register unsigned int *prval; -{ - register unsigned int work; - - if ((card >= XY240_MAX_CARDS) || (!dio[card].dptr)) - return -1; - work = (dio[card].dptr->port0_1 << 16) - + dio[card].dptr->port2_3; - *prval = work & mask; - - return(0); -} - -/* - * - *XY240_BO_READ - * - *interface to binary outputs - */ - -xy240_bo_read(card,mask,prval) -register short card; -unsigned int mask; -register unsigned int *prval; -{ - register unsigned int work; - - if ((card >= XY240_MAX_CARDS) || (!dio[card].dptr)){ - return -1; - } - - /* printf("%d\n",dio[card].num); */ - work = (dio[card].dptr->port4_5 << 16) - + dio[card].dptr->port6_7; - - *prval = work &= mask; - - return(0); - } - -/* XY240_DRIVER - * - *interface to binary outputs - */ - -xy240_bo_driver(card,val,mask) -register short card; -unsigned int mask; -register unsigned int val; -{ - register unsigned int work; - - if ((card >= XY240_MAX_CARDS) || (!dio[card].dptr)) - return ERROR; - - /* use structure to handle high and low short swap */ - /* get current output */ - - work = (dio[card].dptr->port6_7 << 16) - + dio[card].dptr->port4_5; - - work = (work & ~mask) | (val & mask); - - dio[card].dptr->port6_7 = (unsigned short)(work >> 16); - dio[card].dptr->port4_5 = (unsigned short)work; - - return OK; - } - - -/*dio_out - * - *test routine for xy240 output - */ -dio_out(card,port,val) -short card,port,val; -{ - - if ((card > XY240_MAX_CARDS-1)) /*test to see if card# is allowable*/ - { - printf("card # out of range\n"); - return -1; - } - else if (!dio[card].dptr) /*see if card exists*/ - { - printf("can't find card %d\n", card); - return -2; - } - else if ((port >7) || (port <4)) /*make sure they're output ports*/ - { - printf("use ports 4-7\n"); - return -3; - } - else if (port == 4) - { - dio[card].dptr->port4_5 = val<< 8; - return -4; - } - else if (port == 5) - { - dio[card].dptr->port4_5 = val; - return -5; - } - else if (port == 6) - { - dio[card].dptr->port6_7 = val<< 8; - return -6; - } -else if (port == 7) - { - dio[card].dptr->port6_7 = val; - return -7; - } -else{ - printf("use ports 4-7\n"); - return -8; - } -} - -/*XY240_WRITE - * - *command line interface to test bo driver - * - */ -xy240_write(card,val) - short card; - unsigned int val; - { - return xy240_bo_driver(card,val,0xffffffff); - } - - - -long -xy240_io_report(level) -short int level; -{ - int card; - - for (card = 0; card < XY240_MAX_CARDS; card++){ - - if(dio[card].dptr){ - printf("B*: XY240:\tcard %d\n",card); - if (level >= 1){ - xy240_bi_io_report(card); - xy240_bo_io_report(card); - } - } - } - -} - - -void xy240_bi_io_report(int card) -{ - short int num_chans,j,k,l,m,status; - int ival,jval,kval,lval,mval; - unsigned int *prval; - - num_chans = XY240_MAX_CHANS; - - if(!dio[card].dptr){ - return; - } - - printf("\tXY240 BINARY IN CHANNELS:\n"); - for( j=0,k=1,l=2,m=3; - j < num_chans,k < num_chans, l< num_chans, m < num_chans; - j+=IOR_MAX_COLS,k+= IOR_MAX_COLS,l+= IOR_MAX_COLS, m += IOR_MAX_COLS){ - - - if(j < num_chans){ - xy240_bi_driver(card,masks(j),&jval); - if (jval != 0) - jval = 1; - printf("\tChan %d = %x\t ",j,jval); - } - if(k < num_chans){ - xy240_bi_driver(card,masks(k),&kval); - if (kval != 0) - kval = 1; - printf("Chan %d = %x\t ",k,kval); - } - if(l < num_chans){ - xy240_bi_driver(card,masks(l),&lval); - if (lval != 0) - lval = 1; - printf("Chan %d = %x \t",l,lval); - } - if(m < num_chans){ - xy240_bi_driver(card,masks(m),&mval); - if (mval != 0) - mval = 1; - printf("Chan %d = %x \n",m,mval); - } - } -} - - -void xy240_bo_io_report(int card) -{ - short int num_chans,j,k,l,m,status; - int ival,jval,kval,lval,mval; - unsigned int *prval; - - num_chans = XY240_MAX_CHANS; - - if(!dio[card].dptr){ - return; - } - - printf("\tXY240 BINARY OUT CHANNELS:\n"); - - for( j=0,k=1,l=2,m=3; - j < num_chans,k < num_chans, l < num_chans,m < num_chans; - j+=IOR_MAX_COLS,k+= IOR_MAX_COLS,l+= IOR_MAX_COLS, m += IOR_MAX_COLS){ - - if(j < num_chans){ - xy240_bo_read(card,masks(j),&jval); - if (jval != 0) - jval = 1; - printf("\tChan %d = %x\t ",j,jval); - } - if(k < num_chans){ - xy240_bo_read(card,masks(k),&kval); - if (kval != 0) - kval = 1; - printf("Chan %d = %x\t ",k,kval); - } - if(l < num_chans){ - xy240_bo_read(card,masks(l),&lval); - if (lval != 0) - lval = 1; - printf("Chan %d = %x \t",l,lval); - } - if(m < num_chans){ - xy240_bo_read(card,masks(m),&mval); - if (mval != 0) - mval = 1; - printf("Chan %d = %x \n",m,mval); - } - } -} - diff --git a/src/drv/drvXy566.c b/src/drv/drvXy566.c deleted file mode 100644 index 7d2d5a706..000000000 --- a/src/drv/drvXy566.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* base/src/drv $Id$ */ -/* drvXy566.c - Driver Support Routines for xy566 - * - * Author: Bob Dalesio - * Date: 6-13-88 - * - * 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: - * ----------------- - * .00 09-14-88 lrd check for IGEN card present before initing - * .01 9-27-88 lrd removed test code - * .02 09-27-88 lrd removed call to xy_mem_init - * .03 10-04-88 lrd remove IGEN support - * .04 10-07-88 lrd add support for the Xycom 085 arm mechanism - * added external latched AI and made - * others scan continuously - * .05 11-10-88 lrd change addresses per HW Tech Note #2 - * .06 02-08-89 lrd moved module addresses into a table in - * module_types.h from ai_driver.h - * .07 02-24-89 lrd modify for vxWorks 4.0 - * changed sysSetBCL to sysIntEnable - * .08 04-17-89 lrd add callback mechanism for data take complete - * .09 05-10-89 lrd increased performance for xycom 566 interface - * by keeping the address of the memory buffers - * thus removing the need to calculate on each - * read - * .10 07-27-89 lrd modified to use channel 0 not channel 1 - * .11 11-20-89 joh added call to the at5vxi ai driver - * .12 02-15-90 lrd modified for new 085 card - * 02/04/91 ges Change taskDelay from 6 to 2 in - * "xy566DoneTask". Allows rearm and data reads - * for successive waveform scans up thru - * 10 Hz rates. - * .13 08-27-91 bg broke the 566 driver out of ai_driver.c - * and moved it to this file. Moved io_report code - * to this file. - * added arguments and raw value read out - * for analog in cards. - * .14 10/30/91 bg Combined the xy566 waveform driver with the - * xy566 analog in drivers. Changed addressing to - * use sysBusToLocalAddrs and VME_AM_STD_SUP or - * VME_AM_SUP_SHORT_IO - * .15 11-30-91 bg Added sysBusToLocalAdrs to both ai and - * waveform sections. - * .16 02-05-92 bg Changed io_report so it has an argument - * level and so if the level > 1, the raw - * value from the card will be printed out - * for analog ins only. - * .17 03/20/92 bg Added the argument level to io_report, - * but so far it doesn't do anything. Will - * add ability to report ability to read out - * raw value if there is a demand. - * .18 08-10-92 joh cleaned up the merge of the xy566 wf and ai - * drivers - * .19 08-25-92 mrk replaced call to ai_driver by ai_xy566_driver - * .20 08-26-92 mrk support epics I/O event scan - * .21 08-27-92 joh fixed routines which return with and without - * status - * .22 08-27-92 joh fixed nonexsistant EPICS init - * .23 08-02-93 mrk Added call to taskwdInsert - * .24 08-04-93 mgb Removed V5/V4 and EPICS_V2 conditionals - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static char SccsId[] = "@(#)drvXy566.c 1.14\t8/4/93 "; - -/* - * Code Portions - * - * xy566DoneTask Task to handle data take completion for the 566 waveform - * xy566_init Initializes the 566 waveform cards - * senb/senw Writes to the 566 where the call provides a req'd delay - */ - -/* If any of the following does not exist replace it with #define <> NULL */ - - -static long report(); -static long init(); - -#if 0 -static long xy566_io_report(); -static long ai_566_init(); -#endif - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvXy566={ - 2, - report, - init}; - -static long init() -{ - ai_566_init(); - xy566_init(); - return(0); -} - -static long report() -{ - ai_xy566_io_report(); - xy566_io_report(); -} - -#define MAX_SE_CARDS (ai_num_cards[XY566SE]) -#define MAX_DI_CARDS (ai_num_cards[XY566DI]) -#define MAX_DIL_CARDS (ai_num_cards[XY566DIL]) - -#define XY566_MEM_INCR 0x10000 /* size of data memory area */ - -/* memory structure of the 566 interface */ -struct ai566 { /* struct XVME 566 */ - char dum[0x80]; /* odd bytes 1 - 3f contain - module identification */ - unsigned short a566_csr; /* control status register */ - unsigned char soft_start; /* software start register */ - unsigned char int_vect; /* interrupt vector register */ - unsigned short dram_ptr; /* pointer to data ram */ - char dum1; /* unused */ - unsigned char sram_ptr; /* sequence ram pointer */ - char dum2[0xc0 - 0x88]; - unsigned short stc_data; /* timing chip data port */ - unsigned short stc_control; /* timing chip control port */ - char dum3[0x101 - 0xc4]; - unsigned char gram_base; /* base of gain ram 101,103 to 13f */ - char dum5[0x201 - 0x102]; - unsigned char sram_base; /* base of sequence ram 210,203 to 3ff */ - char dum6[0x3ff -0x202]; - unsigned char card_number; /* logical card number */ -}; - -/* memory structure of the 566 interface */ -struct wf085 { /* struct XVME 566 */ - char dum[0x80]; /* odd bytes 1 - 3f contain - module identification */ - unsigned short csr; /* control status register */ - unsigned char soft_start; /* software start register */ - unsigned char int_vect; /* interrupt vector register */ - unsigned short dram_ptr; /* pointer to data ram */ - char dum1; /* unused */ - unsigned char sram_ptr; /* sequence ram pointer */ - char dum2[0xc0 - 0x88]; - unsigned short stc_data; /* timing chip data port */ - unsigned short stc_control; /* timing chip control port */ - char dum3[0x101 - 0xc4]; - unsigned char gram_base; /* base of gain ram 101,103,.. - ... to 13f */ - char dum5[0x201 - 0x102]; - unsigned char sram_base; /* base of sequence ram 210,203, - ... to 3ff */ - char dum6[0x400 -0x202]; -}; - -/* arrays which keep track of which cards are found at initialization */ -struct ai566 **pai_xy566se; -struct ai566 **pai_xy566di; -struct ai566 **pai_xy566dil; -unsigned short **pai_xy566se_mem; -unsigned short **pai_xy566di_mem; -unsigned short **pai_xy566dil_mem; -static IOSCANPVT *paioscanpvt; - - -/* reset the counter interrupt 0x8000 */ -/* reset the sequence interrupt 0x2000 */ -/* enable the sequence interrupt 0x1000 */ -/* reset the trigger clock interrupt 0x0800 */ -/* enable the sequence controller 0x0100 */ -/* read values into first 32 words on each read 0x0040 */ -/* read in sequential mode (bit 0x0020 == 0) 0x0000 */ -/* interrupt enable 0x0008 */ -/* leds green-on red-off 0x0003 */ - -#define XY566L_CSR 0xb94b -#define XY566_INT_LEVEL 6 - - -/* max card and channel definitions move to module types.h */ -#define MAX_WF_XY_CARDS (wf_num_cards[XY566WF]) - -/* card interface */ -#define WF_XY566_BASE (wf_addrs[XY566WF]) /* XYCOM 566 waveform */ -#define WF_XY085_BASE (wf_armaddrs[XY566WF]) /* XYCOM 085 arm */ - -/* Data RAM area into which the 566 stores the latched data */ -/* This needs to be different for each type of IO card */ -#define WF_XY566_MEMBASE ((unsigned short *)0x1080000) - -/* figure out what these are */ -#define WF566_MEM_INCR 0x10000 /* 65535 bytes per waveform */ -#define WF566_VNUM 0xf1 /* this is currently incorrect */ - - -#define WF_READ 0x00 /* read a waveform */ -#define WF_ARM 0x01 /* arm a waveform */ -#define WF_LATCH 0x02 /* latch a waveform */ -#define WF_SETUP 0x03 /* set up a waveform */ - -/* xycom 085 encoder pulse mechanism */ -#define XY_ARM 0x10 /* arm the encoder pulse circuitry */ -#define XY_BUSY 0x20 /* indicates the waveform is still being taken */ -#define XY_LED 0x3 /* set the Xycom status LEDs to OK */ -#define XY_SOFTRESET 0x10 /* reset the IO card */ - - -/* arrays which keep track of which cards are found at initialization */ -struct ai566 **pwf_xy566; -struct wf085 **pwf_xy085; -char **pwf_mem; - -/* the routine to call when the data is read and the argument to send */ -unsigned int **pargument; -unsigned int **proutine; - -/* VME memory Short Address Space is set up in gta_init */ - -int wfDoneId; /* waveform done task ID */ - -/* forward references */ -static void senw(); -static VOID xy566_reset(); -static int ai_xy566_init(); -static int ai_xy566l_init(); -static VOID rval_convert(); -static VOID xy566_rval_report(); - - -static acro_intr(ap) -register struct acroregs *ap; -{ -} - -/* The following two subroutines introduce a delay between - * successive writes to the 566. This is necessary for some - * parts of the card (i.e. the AM9513). It also insures - * that a value is actually written, instead of compiler - * generated bset or bclr instructions. - */ -static void senw (addr, val) -unsigned short *addr; -unsigned short val; -{ - *addr = val; -} - -senb (addr, val) -unsigned char *addr; -unsigned char val; -{ - *addr = val; -} - -ai566_intr(i) -short i; -{ - register struct ai566 *ap; - - ap = pai_xy566dil[i]; - - scanIoRequest(paioscanpvt[i]); - - /* reset the CSR - needed to allow next interrupt */ - senw(&ap->a566_csr,XY566L_CSR); - -} - -/* - * ai_566_init () - * - * Initialize all VME analog input cards - */ - -long ai_566_init() -{ - /* intialize the Xycom 566 Unipolar Single Ended Analog Inputs */ - ai_xy566_init(&pai_xy566se,ai_addrs[XY566SE],ai_num_channels[XY566SE], - ai_num_cards[XY566SE],ai_memaddrs[XY566SE],&pai_xy566se_mem); - - /* intialize the Xycom 566 Unipolar Differential Analog Inputs */ - ai_xy566_init(&pai_xy566di,ai_addrs[XY566DI],ai_num_channels[XY566DI], - ai_num_cards[XY566DI],ai_memaddrs[XY566DI],&pai_xy566di_mem); - - - /* intialize the Xycom 566 Unipolar Differential Analog Inputs Latched */ - ai_xy566l_init(&pai_xy566dil,ai_addrs[XY566DIL],ai_num_channels[XY566DIL], - ai_num_cards[XY566DIL],ai_memaddrs[XY566DIL],&pai_xy566dil_mem); - - return (0); -} - - -/* - * ai_XY566_INIT - * - * intialize the xycom 566 analog input card - */ -int ai_xy566_init(pppcards_present,base_addr,num_channels,num_cards,paimem,pppmem_present) -register struct ai566 ***pppcards_present; -register unsigned short *base_addr; -register short num_channels; -short num_cards; -register char *paimem; /* mem loc of I/O buffer */ -register short ***pppmem_present; -{ - short shval; - register short i,n; - struct ai566 *pai566; /* memory location of cards */ - char *pai566io; /* mem loc of I/O buffer */ - short status; - struct ai566 **ppcards_present; - short **ppmem_present; - - *pppcards_present = (struct ai566 **) - calloc(num_cards, sizeof(**pppcards_present)); - if(!*pppcards_present){ - return ERROR; - } - - *pppmem_present = (short **) - calloc(num_cards, sizeof(**pppmem_present)); - if(!*pppmem_present){ - return ERROR; - } - - ppcards_present = *pppcards_present; - ppmem_present = *pppmem_present; - - /* map the io card into the VRTX short address space */ - status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, base_addr, &pai566); - if(status != OK){ - logMsg("%s: failed to map XY566 A16 base addr A16=%x\n", - __FILE__, - base_addr); - return ERROR; - } - - /* map the io card into the standard address space */ - status = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA,paimem, &pai566io); - if(status != OK){ - logMsg( "%s: failed to map XY566 A24 base addr A24=%x\n", - __FILE__, - paimem); - return ERROR; - } - - /* mark each card present into the card present array */ - for (i = 0; i < num_cards; - i++, pai566++, ppcards_present++, pai566io+=XY566_MEM_INCR,ppmem_present++) { - if (vxMemProbe(pai566,READ,sizeof(short),&shval) != OK){ - *ppcards_present = 0; - continue; - } - if (vxMemProbe(pai566io,READ,sizeof(short),&shval) != OK){ - *ppcards_present = 0; - continue; - } - - *ppcards_present = pai566; - *ppmem_present = (short *)pai566io; - - /* reset the Xycom 566 board */ - senw(&pai566->a566_csr,0x00); /* off seq control */ - senw(&pai566->a566_csr,XY_SOFTRESET); /* reset */ - senw(&pai566->a566_csr,XY_LED); /* reset off,red off,green on */ - - /* Am9513 commands */ - /* initialize the Am9513 chip on the XY566 */ - senw(&pai566->stc_control,0xffff); /* master reset */ - senw(&pai566->stc_control,0xff5f); /* disarm all counters */ - senw(&pai566->stc_control,0xffef); /* 16 bit mode */ - - /* master mode register */ - senw(&pai566->stc_control,0xff17); /* select master mode reg */ - senw(&pai566->stc_data,0x2200); /* 16 bit, divide by 4 */ - - /* counter two is used to set the time between sequences */ - senw(&pai566->stc_control,0xff02); /*sel counter 2 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffea); /* TC output high */ - - /* counter four is used as time between sequence elements */ - senw(&pai566->stc_control,0xff04); /* sel counter 4 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffec); /* TC output high */ - - /* counter five is used as an event counter */ - senw(&pai566->stc_control,0xff05); /* sel counter 5 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffed); /* TC output high */ - - /* set time between sequences */ - senw(&pai566->stc_control,0xff04); /* sel counter 4 */ - senw(&pai566->stc_data,0x9525); /* see Am9513A manual */ - senw(&pai566->stc_data,0x0014); /* downcount value */ - senw(&pai566->stc_control,0xff68); /* load & arm cntr 4 */ - - senw(&pai566->stc_control,0xff05); /* sel counter 4 */ - senw(&pai566->stc_data,0x97ad); /* see Am9513A manual */ - senw(&pai566->stc_data,0x0100); /* downcount value */ - senw(&pai566->stc_control,0xff70); /* load & arm cntr 4 */ - /* end of the Am9513 commands */ - - /* for each channel set gain and place into the scan list */ - for (n=0; n < num_channels; n++) { - senb((&pai566->gram_base + n*2),0); /* gain == 1 */ - /* end of sequnce = 0x80 | channel */ - /* stop = 0x40 | channel */ - senb((&pai566->sram_base+n*2),(n==num_channels-1)? n|0x80:n); - } - senw(&pai566->dram_ptr, 0); /* data ram at 0 */ - senb(&pai566->sram_ptr, 0); /* seq ram also at 0 */ - - /* set the Xycom 566 board */ - /* reset the counter interrupt 0x8000 */ - /* reset the sequence interrupt 0x2000 */ - /* reset the trigger clock interrupt 0x0800 */ - /* enable the sequence controller 0x0100 */ - /* read values into first 32 words on each read 0x0040 */ - /* read in sequential mode (bit 0x0020 == 0) 0x0000 */ - /* leds green-on red-off 0x0003 */ - senw(&pai566->a566_csr,0xa943 ); /* init csr */ - - /* latch in the first bunch of data and start continuous scan */ - senb(&pai566->soft_start,0); - } - - return OK; -} - -/* - * AI_XY566L_INIT - * - * intialize the xycom 566 latched analog input card - */ -int ai_xy566l_init(pppcards_present,base_addr,num_channels,num_cards,paimem,pppmem_present) -register struct ai566 ***pppcards_present; -register unsigned short *base_addr; -register short num_channels; -short num_cards; -register char *paimem; /* mem loc of I/O buffer */ -register short ***pppmem_present; -{ - short shval; - register short i,n; - struct ai566 *pai566; /* memory location of cards */ - char *pai566io; /* mem loc of I/O buffer */ - int status; - struct ai566 **ppcards_present; - short **ppmem_present; - - *pppcards_present = (struct ai566 **) - calloc(num_cards, sizeof(**pppcards_present)); - if(!*pppcards_present){ - return ERROR; - } - - paioscanpvt = (IOSCANPVT *)calloc(num_cards, sizeof(*paioscanpvt)); - if(!paioscanpvt) { - return ERROR; - } - { - int i; - for(i=0; icard_number,i); - - /* set up the interrupt vector */ - /* taken from the XYCOM-566 Manual. Figure 4-6 Page 4-19 */ - pai566->int_vect = AI566_VNUM + i; - - intConnect((AI566_VNUM + i) * 4, ai566_intr, i); - sysIntEnable(XY566_INT_LEVEL); - - /* reset the Xycom 566 board */ - senw(&pai566->a566_csr,0x00); /* off seq control */ - senw(&pai566->a566_csr,XY_SOFTRESET); /* reset */ - senw(&pai566->a566_csr,XY_LED); /* reset off,red off,green on */ - - /* Am9513 commands */ - /* initialize the Am9513 chip on the XY566 */ - senw(&pai566->stc_control,0xffff); /* master reset */ - senw(&pai566->stc_control,0xff5f); /* disarm all counters */ - senw(&pai566->stc_control,0xffef); /* 16 bit mode */ - - /* master mode register */ - senw(&pai566->stc_control,0xff17); /* select master mode reg */ - senw(&pai566->stc_data,0x2200); /* 16 bit, divide by 4 */ - - /* counter two is used to set the time between sequences */ - senw(&pai566->stc_control,0xff02); /*sel counter 2 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffea); /* TC output high */ - - /* counter four is used as time between sequence elements */ - senw(&pai566->stc_control,0xff04); /* sel counter 4 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffec); /* TC output high */ - - /* counter five is used as an event counter */ - senw(&pai566->stc_control,0xff05); /* sel counter 5 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffed); /* TC output high */ - - /* set time between sequences */ - senw(&pai566->stc_control,0xff04); /* sel counter 4 */ - senw(&pai566->stc_data,0x9525); /* see Am9513A manual */ - senw(&pai566->stc_data,0x0014); /* downcount value */ - senw(&pai566->stc_control,0xff68); /* load & arm cntr 4 */ - - senw(&pai566->stc_control,0xff05); /* sel counter 4 */ - senw(&pai566->stc_data,0x97ad); /* see Am9513A manual */ - senw(&pai566->stc_data,0x0100); /* downcount value */ - senw(&pai566->stc_control,0xff70); /* load & arm cntr 4 */ - /* end of the Am9513 commands */ - - /* for each channel set gain and place into the scan list */ - for (n=0; n < num_channels; n++) { - senb((&pai566->gram_base + n*2), 0); /* gain == 1 */ - - /* end of sequnce = 0x80 | channel */ - /* stop = 0x40 | channel */ - /* interrupt = 0x20 | channel */ - senb((&pai566->sram_base+n*2),(n==num_channels-1)? n|0xe0:n); - } - senw(&pai566->dram_ptr,0); /* data ram at 0 */ - senb(&pai566->sram_ptr,0); /* seq ram also at 0 */ - - /* initialize the control status register */ - /* reset the sequence interrupt 0x2000 */ - /* enable the sequence interrupt 0x1000 */ - /* reset the trigger clock interrupt 0x0800 */ - /* enable the sequence controller 0x0100 */ - /* read values into first 32 words on each read 0x0040 */ - /* read in sequential mode (bit 0x0020 == 0) 0x0000 */ - /* interrupt enable 0x0008 */ - /* leds green-on red-off 0x0003 */ - senw(&pai566->a566_csr,XY566L_CSR); - - } - - return OK; -} - -ai_xy566_getioscanpvt(card,scanpvt) -unsigned short card; -IOSCANPVT *scanpvt; -{ - if((card<=(unsigned short)MAX_DIL_CARDS) && paioscanpvt[card]) *scanpvt = paioscanpvt[card]; - return(0); -} - -ai_xy566_driver(card,chan,type,prval) -register short card; -short chan; -register unsigned int type; -register unsigned short *prval; -{ - /* the register short i is used to calculate the delay for the */ - /* conversion of the XYCOM 566. Make sure it stays a register */ - register unsigned short *pcard; - register unsigned short i; - - /* check on the card and channel number as kept in module_types.h */ - if (card >= ai_num_cards[type]) return(-1); - if (chan >= ai_num_channels[type]) return(-2); - - switch (type){ - - case (XY566SE): - { - register struct ai566 *pai566; - - /* check card specified exists */ - if (pai_xy566se[card] == 0) return(-1); - - /* read the value from the Xycom data RAM area */ - *prval = pai_xy566se_mem[card][chan]; - - return (0); - } - - case (XY566DI): - { - register struct ai566 *pai566; - - /* check card specified exists */ - if (pai_xy566di[card] == 0) return(-1); - - /* read the value form the Xycom data RAM area */ - - *prval = pai_xy566di_mem[card][chan]; - - rval_convert(prval); - return (0); - } - - case (XY566DIL): - { - register struct ai566 *pai566; - - /* check card specified exists */ - if (pai_xy566dil[card] == 0) return(-1); - - /* read the value form the Xycom data RAM area */ - *prval = pai_xy566dil_mem[card][chan]; - - rval_convert(prval); - return (0); - } - - - } - - return (-3); -} - -/* - * rval_convert - * For 566_card - values for XY566DI and XY566DIL - * come from the card as signed hex numbers( -0x7ff to +0x7ff). - * This subrountine converts them to unsigned hex numbers (0x0 - - * 0x7ff. Then it strips off the sign bit. - * -*/ -VOID rval_convert(rval) - unsigned short *rval; -{ - - *rval = *rval + 0x800; - - /* remove the sign bits. */ - - *rval &= 0xfff; -} - -/* - * - * xy566_reset- Called for ctl X reboot. The idea is to disable - * bits 3 and 12 of the CSR. - * -*/ - -VOID xy566_reset(){ - unsigned short csr_val,shval; - short int i; - struct ai566 *pai566; /* memory location of cards */ - short int status; - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - ai_addrs[XY566DIL], - &pai566); - if (status != OK){ - logMsg("%s: unable to map A16 XY566 base\n", __FILE__); - return; - } - - for (i=0;ia566_csr = csr_val; - } -} - - - - -/* - * io_report (or dbior) subroutine for 566 card. - * - * - */ -long ai_xy566_io_report(level) - char level; -{ - short i,j; - unsigned short rval; - - - for (i = 0; i < MAX_SE_CARDS; i++){ - if (pai_xy566se[i]){ - printf("AI: XY566-SE:\tcard %d\n",i); - if (level == 1){ - xy566_rval_report(i,XY566SE); - } - - } - } - for (i = 0; i < MAX_DI_CARDS; i++){ - if (pai_xy566di[i]){ - printf("AI: XY566-DI:\tcard %d\n",i); - if (level == 1){ - xy566_rval_report(i,XY566DI); - } - } - - } - - for (i = 0; i < MAX_DIL_CARDS; i++){ - if (pai_xy566dil[i]){ - printf("AI: XY566-DIL:\tcard %d\n",i); - if (level == 1){ - xy566_rval_report(i,XY566DIL); - } - } - } - return OK; -} - -/* - * xy566_rval_report -reports the raw value for every channel on the card - * - * called by ai_xy566_io_report if level is 1 - * - */ -VOID xy566_rval_report(card,type) - short int card,type; - { - short i,j,k,l,m,num_chans; - unsigned short jrval,krval,lrval,mrval; - - printf("\n"); - - num_chans = ai_num_channels[type]; - - for(j=0,k=1,l=2,m=3;j < num_chans,k < num_chans, l < num_chans,m < num_chans; - j+=IOR_MAX_COLS,k+=IOR_MAX_COLS,l+= IOR_MAX_COLS,m +=IOR_MAX_COLS){ - if(j < num_chans){ - if( ai_xy566_driver(card,j,type,&jrval) == 0){ - printf("Chan %d = %x \t",j,jrval); - }else - printf("READ_ALARM\n"); - } - - if(k < num_chans){ - if(ai_xy566_driver(card,k,type,&krval) == 0){ - printf("Chan %d = %x \t",k,krval); - } else - printf("READ_ALARM\n"); - } - if(l < num_chans){ - if( ai_xy566_driver(card,l,type,&lrval) == 0){ - printf("Chan %d = %x \t",l,lrval); - } else - printf("READ_ALARM\n"); - } - if(m < num_chans){ - if( ai_xy566_driver(card,m,type,&mrval) == 0){ - printf("Chan %d = %x \n",m,mrval); - } - else - printf("READ_ALARM\n"); - } - } - } - - - -/* forward references */ - - -/* - * xy566_driver - * - */ -xy566_driver(slot,pcbroutine,parg) -register unsigned short slot; -register unsigned int *pcbroutine; -register unsigned int *parg; /* number of values read */ -{ - register struct ai566 *pwf566; - register struct wf085 *pwf085; - - /* slot range checking occurs in wf_driver.c */ - - /* is the Xycom 566 card present */ - if ((pwf566 = pwf_xy566[slot]) == 0) - return(-1); - if ((pwf085 = pwf_xy085[slot]) == 0) - return(-1); - - /* armed already by someone else */ - if (proutine[slot] != 0) - return(-2); /* by someone else */ - - /* set the Xycom 566 board */ - senw(&pwf566->dram_ptr,0); /* RAM pointer to 0 */ - senw(&pwf566->sram_ptr,0); /* sequence pointer to 0 */ - - /* keep the pointer to the value field */ - proutine[slot] = pcbroutine; - pargument[slot] = parg; - - /* arm the encoder pulse mechanism */ - senw(&pwf085->csr,XY_ARM | XY_LED | 0x20); /* set high */ - senw(&pwf085->csr,XY_LED | 0x20); /* set low */ - - return(0); -} - -/* - * xy566DoneTask - * - * polls the busy bit on the Xycom 566 latched waveform records - * The busy bit is set externally when data collection is completed - */ -xy566DoneTask() -{ - register unsigned int **pproutines; - register unsigned int (*pcbroutine)(); - register short i; - - while(TRUE){ - pproutines = proutine; - for (i=0; icsr & XY_BUSY) == 0){ - /* callback routine when data take completed */ - (unsigned int *)pcbroutine = *pproutines; - (*pcbroutine) - (pargument[i],pwf_xy566[i]->dram_ptr,pwf_mem[i]); - - /* reset for someelse to claim */ - *pproutines = 0; - pargument[i] = 0; - } - } - - /* sleep for .1 second - system degrade will slow this task */ - /* that's OK */ - taskDelay(2); /* ges: changed from 6 ticks to 2 ticks 2/4/91 */ - } -} - -/* - * XY566_INIT - * - * intialize the xycom 566 waveform input card - */ -xy566_init() -{ - register struct ai566 **pcards_present = pwf_xy566; - register struct wf085 **parms_present = pwf_xy085; - register char **pmem_present = pwf_mem; - - short shval,status; - register short i,got_one; - struct ai566 *pwf566; /* VME location of cards */ - struct wf085 *pwf085; /* VME location of arm */ - char *pwfMem; /* VME 566 memory buffer */ - - pwf_xy566 = (struct ai566 **) - calloc(wf_num_cards[XY566WF], sizeof(*pwf_xy566)); - if(!pwf_xy566){ - return ERROR; - } - pwf_xy085 = (struct wf085 **) - calloc(wf_num_cards[XY566WF], sizeof(*pwf_xy085)); - if(!pwf_xy085){ - return ERROR; - } - pwf_mem = (char **) - calloc(wf_num_cards[XY566WF], sizeof(*pwf_mem)); - if(!pwf_mem){ - return ERROR; - } - pargument = (unsigned int **) - calloc(wf_num_cards[XY566WF], sizeof(*pargument)); - if(!pargument){ - return ERROR; - } - proutine = (unsigned int **) - calloc(wf_num_cards[XY566WF], sizeof(*proutine)); - if(!proutine){ - return ERROR; - } - - pcards_present = pwf_xy566; - parms_present = pwf_xy085; - pmem_present = pwf_mem; - - /* map the io card into the VME short address space */ - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - WF_XY566_BASE, - &pwf566); - if(status<0){ - logMsg("%s: unable to map A16 XY566 base\n", __FILE__); - return ERROR; - } - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - WF_XY085_BASE, - &pwf085); - if(status<0){ - logMsg("%s: unable to map A16 XY085 base\n", __FILE__); - return ERROR; - } - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - wf_memaddrs[XY566WF], - &pwfMem); - if (status != OK){ - logMsg("%s: unable to map A24 XY566 base\n", __FILE__); - return ERROR; - } - - /* mark each card present into the card present array */ - got_one = 0; - for (i = 0; - i < wf_num_cards[XY566WF]; - i++, pwf566++,pwf085++,pwfMem += XY566_MEM_INCR, pcards_present += 1) { - - /* is the Xycom 566 here */ - if (vxMemProbe(pwf566,READ,sizeof(short),&shval) != OK){ - *pcards_present = 0; - continue; - } - /* is the Xycom 566 memory here */ - if (vxMemProbe(pwfMem,READ,sizeof(short),&shval) != OK){ - *pcards_present = 0; - continue; - } - /* is the Xycom 085 used as the arming mechanism present */ - if (vxMemProbe(pwf085,READ,sizeof(short),&shval) != OK){ - *pcards_present = 0; - continue; - } - - got_one = 1; - *pcards_present = pwf566; - *parms_present = pwf085; - *pmem_present = pwfMem; - - /* taken from the XYCOM-566 Manual. Figure 4-6 Page 4-19 */ - /* reset the Xycom 566 board */ - senw (&pwf566->a566_csr,0x00); /* off seq control */ - senw (&pwf566->a566_csr,XY_SOFTRESET); /* reset */ - senw (&pwf566->a566_csr,XY_LED); /* reset off,red off,green on */ - - /* Am9513 commands */ - /* initialize the Am9513 chip on the XY566 */ - senw (&pwf566->stc_control, 0xffff); /* master reset */ - senw(&pwf566->stc_control, 0xff5f); /* disarm all counters */ - senw(&pwf566->stc_control, 0xffef); /* 16 bit mode */ - - /* master mode register */ - senw(&pwf566->stc_control, 0xff17); /* select master mode reg */ - senw(&pwf566->stc_data, 0x2200); /* 16 bit, divide by 4 */ - - /* counter two is used to set the time between sequences */ - senw(&pwf566->stc_control, 0xff02); /*sel counter 2 */ - senw(&pwf566->stc_data, 0x0b02); /* TC toggle mode */ - senw(&pwf566->stc_control, 0xffea); /* TC output high */ - - /* counter four is used as time between sequence elements */ - senw(&pwf566->stc_control, 0xff04); /* sel counter 4 */ - senw(&pwf566->stc_data, 0x0b02); /* TC toggle mode */ - senw(&pwf566->stc_control, 0xffec); /* TC output high */ - - /* counter five is used as an event counter */ - senw(&pwf566->stc_control, 0xff05); /* sel counter 5 */ - senw(&pwf566->stc_data, 0x0b02); /* TC toggle mode */ - senw(&pwf566->stc_control, 0xffed); /* TC output high */ - - /* set counter 4 */ - /* active high level gate N 0x8000 */ - /* count on the falling edge 0x1000 */ - /* SRC 5 0x0500 */ - /* disable special gate 0x0080 = 0 */ - /* reload from load 0x0040 = 0 */ - /* count repetitively 0x0020 = 1 */ - /* binary count 0x0010 = 0 */ - /* count down 0x0008 = 0 */ - /* active low terminal count pulse 0x0007 = 5 */ - senw(&pwf566->stc_control,0xff04); /* sel counter 4 */ - senw(&pwf566->stc_data,0x9525); /* see comment above*/ - senw(&pwf566->stc_data,0x0014); /* downcount value */ - senw(&pwf566->stc_control,0xff68); /* load & arm cntr 4 */ - - /* set counter 5 */ - /* active high level gate N 0x8000 */ - /* count on the falling edge 0x1000 */ - /* GATE 2 0x0700 */ - /* enable special gate 0x0080 = 1 */ - /* reload from load 0x0040 = 0 */ - /* count repetitively 0x0020 = 1 */ - /* binary count 0x0010 = 0 */ - /* count up 0x0008 = 1 */ - /* active low terminal count pulse 0x0007 = 5 */ - senw(&pwf566->stc_control,0xff05); /* sel counter 5 */ - senw(&pwf566->stc_data,0x97ad); /* see comment above */ - senw(&pwf566->stc_data,0x0100); /* count value */ - senw(&pwf566->stc_control,0xff70); /* load & arm cntr 5*/ - /* end of the Am9513 commands */ - - /* Xycom gain RAM */ - senb(&pwf566->gram_base,0); /* set gain to 1 ch0*/ - - /* Xycom sequence RAM */ - senb(&pwf566->sram_base,0xc0); /* read only the 0th channel */ - - /* Xycom data RAM index */ - senw(&pwf566->dram_ptr,0); /* data ram at 0 */ - - /* Xycom sequential RAM index */ - senb(&pwf566->sram_ptr,0); /* seq ram also at 0 */ - - /* set the Xycom 566 board */ - /* reset the counter interrupt 0x8000 */ - /* reset the sequence interrupt 0x2000 */ - /* reset the trigger clock interrupt 0x0800 */ - /* enable the sequence controller 0x0100 */ - /* read values into data RAM contiguously (bit 0x0040 == 0) 0x0000 */ - /* read in sequential mode (bit 0x0020 == 0) 0x0000 */ - /* leds green-on red-off 0x0003 */ - senw(&pwf566->a566_csr,0xa903); /* init csr */ - - /* initialize the xycom 085 used as the arming mechanism */ - /* leds green-on red-off 0x0003 */ - senw(&pwf085->csr,XY_LED | 0x20); /* init csr */ - } - - /* start the 566 waveform readback task */ - if (got_one) - wfDoneId = - taskSpawn( - WFDONE_NAME, - WFDONE_PRI, - WFDONE_OPT, - WFDONE_STACK, - xy566DoneTask); - taskwdInsert(wfDoneId,NULL,NULL); - - return 0; -} - - -/* - * XY566_IO_REPORT - * - * - * - * - */ -long -xy566_io_report(level) -short int level; -{ - int i,xy566_bytes; - - /* report all of the xy566 waveform inputs present */ - for (i = 0; i < wf_num_cards[XY566WF]; i++) - if (pwf_xy566[i]){ - printf("WF: XY566: card %d\n",i); - } - -} - - diff --git a/src/drv/module_types.c b/src/drv/module_types.c deleted file mode 100644 index 09996959b..000000000 --- a/src/drv/module_types.c +++ /dev/null @@ -1,241 +0,0 @@ -/* module_types.c */ -/* base/src/drv $Id$ */ -/* - * Author: Marty Kraimer - * Date: 08-23-93 - * - * 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-23-93 mrk Initial Version - */ - -#include - -module_types() -{ - -ai_num_cards[AB1771IL] = 12; -ai_num_cards[AB1771IFE] = 12; -ai_num_cards[AB1771IXE] = 12; -ai_num_cards[XY566SE] = 2; -ai_num_cards[XY566DI] = 2; -ai_num_cards[XY566DIL] = 2; -ai_num_cards[VXI_AT5_AI] = 32; -ai_num_cards[AB1771IFE_SE] = 12; -ai_num_cards[AB1771IFE_4to20MA] = 12; -ai_num_cards[DVX2502] = 1; -ai_num_cards[AB1771IFE_0to5V] = 12; -ai_num_cards[KSCV215] = 32; - -ai_num_channels[AB1771IL] = 8; -ai_num_channels[AB1771IFE] = 8; -ai_num_channels[AB1771IXE] = 8; -ai_num_channels[XY566SE] = 32; -ai_num_channels[XY566DI] = 16; -ai_num_channels[XY566DIL] = 16; -ai_num_channels[VXI_AT5_AI] = 8; -ai_num_channels[AB1771IFE_SE] = 16; -ai_num_channels[AB1771IFE_4to20MA] = 8; -ai_num_channels[DVX2502] = 127; -ai_num_channels[AB1771IFE_0to5V] = 8; -ai_num_channels[KSCV215] = 32; - -ai_addrs[AB1771IL] = 0; -ai_addrs[AB1771IFE] = 0; -ai_addrs[AB1771IXE] = 0; -ai_addrs[XY566SE] = 0x6000; -ai_addrs[XY566DI] = 0x7000; -ai_addrs[XY566DIL] = 0x7800; -ai_addrs[VXI_AT5_AI] = 0xc014; -ai_addrs[AB1771IFE_SE] = 0; -ai_addrs[AB1771IFE_4to20MA] = 0; -ai_addrs[DVX2502] = 0xff00; -ai_addrs[AB1771IFE_0to5V] = 0; -ai_addrs[KSCV215] = 0; - -ai_memaddrs[AB1771IL] = 0; -ai_memaddrs[AB1771IFE] = 0; -ai_memaddrs[AB1771IXE] = 0; -ai_memaddrs[XY566SE] = 0x000000; -ai_memaddrs[XY566DI] = 0x040000; -ai_memaddrs[XY566DIL] = 0x0c0000; -ai_memaddrs[VXI_AT5_AI] = 0; -ai_memaddrs[AB1771IFE_SE] = 0; -ai_memaddrs[AB1771IFE_4to20MA] = 0; -ai_memaddrs[DVX2502] = 0x100000; -ai_memaddrs[AB1771IFE_0to5V] = 0; -ai_memaddrs[KSCV215] = 0; - -ao_num_cards[AB1771OFE] = 12; -ao_num_cards[VMI4100] = 4; -ao_num_cards[ZIO085] = 1; -ao_num_cards[VXI_AT5_AO] = 32; - -ao_num_channels[AB1771OFE] = 4; -ao_num_channels[VMI4100] = 16; -ao_num_channels[ZIO085] = 32; -ao_num_channels[VXI_AT5_AO] = 16; - -ao_addrs[AB1771OFE] = 0; -ao_addrs[VMI4100] = 0x4100; -ao_addrs[ZIO085] = 0x0800; -ao_addrs[VXI_AT5_AO] = 0xc000; - -bi_num_cards[ABBI_08_BIT] = 12; -bi_num_cards[ABBI_16_BIT] = 12; -bi_num_cards[BB910] = 4; -bi_num_cards[XY210] = 2; -bi_num_cards[VXI_AT5_BI] = 32; -bi_num_cards[HPE1368A_BI] = 32; -bi_num_cards[AT8_FP10S_BI] = 8; -bi_num_cards[XY240_BI] = 2; - -bi_num_channels[ABBI_08_BIT] = 8; -bi_num_channels[ABBI_16_BIT] = 16; -bi_num_channels[BB910] = 32; -bi_num_channels[XY210] = 32; -bi_num_channels[VXI_AT5_BI] = 32; -bi_num_channels[HPE1368A_BI] = 16; -bi_num_channels[AT8_FP10S_BI] = 32; -bi_num_channels[XY240_BI] = 32; - -bi_addrs[ABBI_08_BIT] = 0; -bi_addrs[ABBI_16_BIT] = 0; -bi_addrs[BB910] = 0xb800; -bi_addrs[XY210] = 0xa000; -bi_addrs[VXI_AT5_BI] = 0xc000; -bi_addrs[HPE1368A_BI] = 0xc000; -bi_addrs[AT8_FP10S_BI] = 0x0e00; -bi_addrs[XY240_BI] = 0x3000; - -bo_num_cards[ABBO_08_BIT] = 12; -bo_num_cards[ABBO_16_BIT] = 12; -bo_num_cards[BB902] = 4; -bo_num_cards[XY220] = 1; -bo_num_cards[VXI_AT5_BO] = 32; -bo_num_cards[HPE1368A_BO] = 32; -bo_num_cards[AT8_FP10M_BO] = 2; -bo_num_cards[XY240_BO] = 2; - -bo_num_channels[ABBO_08_BIT] = 8; -bo_num_channels[ABBO_16_BIT] = 16; -bo_num_channels[BB902] = 32; -bo_num_channels[XY220] = 32; -bo_num_channels[VXI_AT5_BO] = 32; -bo_num_channels[HPE1368A_BO] = 16; -bo_num_channels[AT8_FP10M_BO] = 32; -bo_num_channels[XY240_BO] = 32; - -bo_addrs[ABBO_08_BIT] = 0; -bo_addrs[ABBO_16_BIT] = 0; -bo_addrs[BB902] = 0x0400; -bo_addrs[XY220] = 0xa800; -bo_addrs[VXI_AT5_BO] = 0xc000; -bo_addrs[HPE1368A_BO] = 0xc000; -bo_addrs[AT8_FP10M_BO] = 0xc000; -bo_addrs[XY240_BO] = 0x3000; - -sm_num_cards[CM57_83E] = 4; -sm_num_cards[OMS_6AXIS] = 4; - -sm_num_channels[CM57_83E] = 1; -sm_num_channels[OMS_6AXIS] = 6; - -sm_addrs[CM57_83E] = 0x8000; -sm_addrs[OMS_6AXIS] = 0x4000; - -wf_num_cards[XY566WF] = 2; -wf_num_cards[CAMAC_THING] = 4; -wf_num_cards[JGVTR1] = 4; -wf_num_cards[COMET] = 4; - -wf_num_channels[XY566WF] = 1; -wf_num_channels[CAMAC_THING] = 1; -wf_num_channels[JGVTR1] = 1; -wf_num_channels[COMET] = 4; - -wf_addrs[XY566WF] = 0x9000; -wf_addrs[CAMAC_THING] = 0; -wf_addrs[JGVTR1] = 0xB000; -wf_addrs[COMET] = 0xbc00; - -wf_armaddrs[XY566WF] = 0x5400; -wf_armaddrs[CAMAC_THING]= 0; -wf_armaddrs[JGVTR1] = 0; -wf_armaddrs[COMET] = 0; - -wf_memaddrs[XY566WF] = 0x080000; -wf_memaddrs[CAMAC_THING]= 0; -wf_memaddrs[JGVTR1] = 0xb80000; -wf_memaddrs[COMET] = 0xe0000000; - -tm_num_cards[MZ8310] = 4; -tm_num_cards[DG535] = 1; -tm_num_cards[VXI_AT5_TIME] = 32; - -tm_num_channels[MZ8310] = 10; -tm_num_channels[DG535] = 1; -tm_num_channels[VXI_AT5_TIME] = 10; - -tm_addrs[MZ8310] = 0x1000; -tm_addrs[DG535] = 0; -tm_addrs[VXI_AT5_TIME] = 0xc000; - -AT830X_1_addrs = 0x0400; -AT830X_1_num_cards = 2; -AT830X_addrs = 0xaa0000; -AT830X_num_cards = 2; - -xy010ScA16Base = 0x0000; - -EPICS_VXI_LA_COUNT = 32; -EPICS_VXI_A24_BASE = (char *) 0x900000; -EPICS_VXI_A24_SIZE = 0x100000; -EPICS_VXI_A32_BASE = (char *) 0x90000000; -EPICS_VXI_A32_SIZE = 0x10000000; - - -AI566_VNUM = 0xf8; -DVX_IVEC0 = 0xd0; -MD_INT_BASE = 0xf0; -MZ8310_INT_VEC_BASE = 0xe8; -AB_VEC_BASE = 0x60; -JGVTR1_INT_VEC = 0xe0; -AT830X_1_IVEC0 = 0xd4; -AT830X_IVEC0 = 0xd6; -AT8FP_IVEC_BASE = 0xa2; -AT8FPM_IVEC_BASE= 0xaa; - -BB_SHORT_OFF = 0x1800; -BB_IVEC_BASE = 0xa0; -BB_IRQ_LEVEL = 5; -PEP_BB_SHORT_OFF= 0x1c00; -PEP_BB_IVEC_BASE= 0xe8; - -NIGPIB_SHORT_OFF = 0x5000; -NIGPIB_IVEC_BASE = 100; -NIGPIB_IRQ_LEVEL = 5; - -return(0); -} diff --git a/src/drv/old/VXI_SETUP_README b/src/drv/old/VXI_SETUP_README deleted file mode 100644 index 42c6507a2..000000000 --- a/src/drv/old/VXI_SETUP_README +++ /dev/null @@ -1,30 +0,0 @@ - -The CPU030 may need to have the nivxi path set correctly: - From the vxWorks shell type "vxitedit" - take option 2 - take option 3 - type list - type modify 0 - type in the correct path when promped - (the path should end in nivxi - and should traverse the niCpu030 - directories shipped with the 030 - ie somethin of the form "???/config/niCPU030/nivxi" - type save - type exit - . - . - . - - -You may may need to setup front panel to backplane trigger -routing: - -To take a TTL input and map it to VXI backplane ECL trigger 0 -type in (to the vxWorks shell): - -epvxiRouteTriggerECL(, 1, 0) - -where specifies the card with the -front panel trigger connection. - diff --git a/src/drv/old/drvAt5Vxi.c b/src/drv/old/drvAt5Vxi.c deleted file mode 100644 index da5af8840..000000000 --- a/src/drv/old/drvAt5Vxi.c +++ /dev/null @@ -1,1482 +0,0 @@ -/* base/src/drv $Id$ */ - -/* - * - * driver for at5 designed VXI modules - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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 joh 021490 first release - * .02 joh 040490 took out init of binary outs as requested by AT5 - * .03 joh 040490 KLUDGED so DC is invarient of model number - * .04 joh 072590 fixed case where a missing SC module could - * be accessed before checking to prevent bus error - * .05 joh 102990 slightly improved sync to busy in init - * .06 joh 032191 added code to implement a new register - * interface from AT5 - * .07 joh 080291 disable ints during control X reboot - * .08 joh 080291 fixed ints on before handler installed problem - * introduced by .06 - * .09 joh 080291 synch source with sorce release control version - * .10 joh 080891 delinting - * .11 joh 090591 converted to v5 vxWorks - * .12 joh 120591 reorganized for use with new vxi support and removed - * KLUDGE introduced in .03 - * .13 joh 042492 removed support for (ifdefs for) the old - * style register map - * .14 joh 071792 added model name registration - * .15 joh 072992 print more raw values in io report - * .16 joh 081092 merged at5vxi_models.h into this source - * .17 joh 081992 function name change - * .18 joh 082792 converted to ansi C - * .19 joh 111392 removed shifts on analog IO - * .20 joh 071593 fixed comment - * .21 joh 081193 took out EPICS_V2 compile switches - * - * Notes: - * ------ - * .01 Dont use C bitfields to write the AT5VXI CSR - * directly because some bits have different meanings - * for read than for write (bitfields writes generate RMW - * instructions- performing reads with C bitfields - * from an IO module works fine however). - * - * To avoid this I write all bits in the CSR with - * each write. See the codes defined by at5vxi_init(). - */ - -/* - * Improvements: - * - * Dont allow them to connect an interrupt if another device is - * installed there ! Perhaps intConnectSafe() should be written? - */ - - - -/* - * Code Portions - * - * AT5VXI_INIT initialize all at5vxi cards - * AT5VXI_INIT_CARD initialize single at5vxi card - * AT5VXI_INT_SERVICE update card busy writes, notify IO scanner - * AT5VXI_ONE_SHOT setup AMD9513 STC with a one shot - * AT5VXI_ONE_SHOT_READ read back timing from an AMD 9513 STC - * AT5VXI_STAT print status for a single at5 vxi card - * AT5VXI_READ_TEST diagnostic - * AT5VXI_AI_DRIVER analog input driver - * AT5VXI_AO_DRIVER analog output driver - * AT5VXI_AO_READ analog output read back - * AT5VXI_BI_DRIVER binary input driver - * AT5VXI_BO_DRIVER binary output driver - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char SccsId[] = "@(#)drvAt5Vxi.c 1.19\t8/27/93"; - -typedef long at5VxiStatus; - -LOCAL void at5vxi_int_service( - int addr -); - -LOCAL void at5vxi_init_card( - unsigned addr -); - -LOCAL int at5vxi_shutdown(void); - -LOCAL void at5vxi_shutdown_card( - unsigned la -); - -LOCAL at5VxiStatus at5vxi_report_timing( - unsigned card, - unsigned channel -); - -LOCAL void at5vxi_stat( - unsigned card, - int level -); - -/* - * these should be in a header file - */ -LOCAL at5VxiStatus at5vxi_init( - void -); - -at5VxiStatus at5vxi_one_shot( - int preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int int_source, /* (FALSE)External/(TRUE)Internal source */ - void *event_rtn, /* subroutine to run on events */ - int event_rtn_param /* parameter to pass to above routine */ -); - -at5VxiStatus at5vxi_one_shot_read( - int *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -); - -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -); - -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -); - -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -); - -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -); - -at5VxiStatus at5vxi_getioscanpvt( - unsigned card, - IOSCANPVT *scanpvt -); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvAt5Vxi={ - 2, - NULL, /* VXI io report takes care of this */ - at5vxi_init}; - -#define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */ - -/* - * Set this flag if you wish for the driver to - * to disable the busy period and operate - * without periodic interrupts - * -#define CONTINUOUS_OPERATION - * - */ - -/* - * all AT5VXI cards will use this VME interrupt level - */ -#ifdef CONTINUOUS_OPERATION -# define AT5VXI_INT_LEVEL 0 -# define AT5VXI_INT_ENABLE FALSE -# define AT5VXI_BUSY_ENABLE FALSE -#else -# define AT5VXI_INT_LEVEL 5 -# define AT5VXI_INT_ENABLE TRUE -# define AT5VXI_BUSY_ENABLE TRUE -#endif - -#define abort(A) taskSuspend(0) - -/* - * bit fields allocated starting with the ms bit - */ -struct at5vxi_status{ - unsigned pad0:1; - unsigned modid_cmpl:1; - unsigned dev255:1; - unsigned busy:1; - unsigned pad1:2; - unsigned timer_bank:1; - unsigned ipend:1; - unsigned ienable:1; - unsigned ilevel:3; - unsigned ready:1; - unsigned passed:1; - unsigned sfinh:1; - unsigned sreset:1; -}; - - -#define PSTATUS(PCSR)\ -(&((struct vxi_csr *)PCSR)->dir.r.status) - -struct at5vxi_control{ - unsigned pad0:3; - unsigned busy_enable:1; - unsigned pad1:2; - unsigned timer_bank:1; - unsigned softint:1; - unsigned ienable:1; - unsigned ilevel:3; - unsigned pad2:2; - unsigned sfinh:1; - unsigned sreset:1; -}; - -/* - * Insert or extract a bit field using the standard - * masks and shifts defined below - */ -#ifdef __STDC__ -# define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S)) -# define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M)) -#else -# define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S)) -# define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M)) -#endif - -/* - * in the constants below _M is a right justified mask - * and _S is a shift required to right justify the field - */ -#define FD_INT_ENABLE_M (0x1) -#define FD_INT_ENABLE_S (7) -#define FD_BUSY_ENABLE_M (0x1) -#define FD_BUSY_ENABLE_S (12) -#define FD_BUSY_STATUS_M (0x1) -#define FD_BUSY_STATUS_S (12) -#define FD_INT_LEVEL_M (0x7) -#define FD_INT_LEVEL_S (4) -#define FD_TIMER_BANK_M (0x1) -#define FD_TIMER_BANK_S (9) - -#define BUSY(PCSR)\ -(((struct vxi_csr *)PCSR)->dir.r.status & INSERT(BUSY_STATUS,1)) - -/* - * Some constants for the CSR. - * - */ -#ifndef CONTINUOUS_OPERATION -# define INTDISABLE\ - ( \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_ENABLE, FALSE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) -#endif - -/* - * Used to initialize the control register. - * (enables interrupts) - */ -#define CSRINIT\ - ( \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_ENABLE, AT5VXI_INT_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) - -/* - * Use bank zero of the timing. - */ -#define BANK0\ - ( \ - INSERT(TIMER_BANK, 0) | \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) -/* - * Use bank one of the timing. - */ -#define BANK1\ - ( \ - INSERT(TIMER_BANK, 1) | \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) - -/* - * Some constants for the CSR. - * set at initialization for better readability - */ -#define PCONTROL(PCSR)\ -(&((struct vxi_csr *)PCSR)->dir.w.control) - - - - -#define AT5VXI_TIMER_BANKS_PER_MODULE 2 -#define AT5VXI_CHANNELS_PER_TIMER_BANK 5 -#define AT5VXI_NTIMER_CHANNELS\ - (AT5VXI_TIMER_BANKS_PER_MODULE*AT5VXI_CHANNELS_PER_TIMER_BANK) - - -struct at5vxi_dd{ - vxi16_t bio[2]; - vxi16_t tdata; - vxi8_t pad; - vxi8_t tcmd; - vxi16_t ai[8]; - vxi16_t ao[16]; -}; - - -struct at5vxi_setup{ -# define UNITY 0 -# define TIMES2 1 - unsigned gainA:1; - unsigned gainB:1; - unsigned gainC:1; - unsigned gainD:1; -# define UNIPOLAR 0 -# define BIPOLAR 1 - unsigned modeA:1; - unsigned modeB:1; - unsigned modeC:1; - unsigned modeD:1; - unsigned ch2enbl:1; - unsigned ch2select:3; - unsigned ch1enbl:1; - unsigned ch1select:3; -}; - - -#define AT5VXI_BUSY_PERIOD 2 - -struct bo_val { - volatile int32_t val; - volatile int32_t mask; -}; - -struct ao_val { - volatile int16_t mdt; - volatile int16_t val; -}; - -struct time_val { - volatile unsigned preset; - volatile int16_t iedge0_delay; - volatile int16_t iedge1_delay; - volatile char mdt; - volatile char valid; -}; - -struct at5vxi_config{ - FAST_LOCK lock; /* mutual exclusion */ - struct bo_val bv; /* binary out values */ - struct ao_val av[16]; /* analog out values */ - struct time_val tv[10]; /* delayed pulse values */ - volatile char mdt; /* modified data tag */ - struct vxi_csr *pcsr; /* vxi device hdr ptr */ - struct at5vxi_dd *pdd; /* at5 device dep ptr */ - IOSCANPVT ioscanpvt; -}; - -LOCAL unsigned long at5vxiDriverID; - -#define AT5VXI_PCONFIG(CARD, PTR) \ -epvxiFetchPConfig(CARD, at5vxiDriverID, PTR) - -#define AT5VXI_CORRECT_MAKE(PCSR) (VXIMAKE(PCSR)==VXI_MAKE_AT5) - -struct at5vxi_model{ - char *name; /* AT5 VXI module name */ - char *drawing; /* AT5 VXI assembly drawing number */ -}; - -#define AT5VXI_INDEX_FROM_MODEL(MODEL) ((unsigned)((MODEL)&0xff)) -#define AT5VXI_MODEL_FROM_INDEX(INDEX) ((unsigned)((INDEX)|0xf00)) - -/* - * NOTE: The macro AT5VXI_INDEX_FROM_MODEL(MODEL) defined above - * should return an index into the correct data given the - * VXI device's model code. - */ -struct at5vxi_model at5vxi_models[] = { - {"INTERFACE SIMULATOR", "112Y-280158"}, - {"I CONTROLLER", "112Y-280176"}, - {"CONTROL PREDISTORTER", "112Y-280172"}, - {"VECTOR DETECTOR", "112Y-280230"}, - {"VECTOR MODULATOR", "112Y-280177"}, - {"425MHz ENVELOPE DETECTOR", "112Y-280169"}, - {"425MHz DOWNCONVERTER", "112Y-280165"}, - {"POLAR DETECTOR", "112Y-280567"}, - {"UPCONVERTER", "112Y-280225"}, - {"MONITOR TRANSMITTER", "112Y-280187"}, - {"TIMING DISTRIBUTION", "112Y-280582"}, - {"LINE CONDITIONER", "112Y-280305"}, - {"BEAM FEEDFORWARD", "112Y-280564"}, - {"TIMING RECEIVER", "112Y-280243"}, - {"FAST PROTECTION", "112Y-280246"}, - {"ADAPTIVE FEEDFORWARD", "112Y-280563"}, - {"CABLE CONTROLLER", "112Y-280307"}, - {"Q CONTROLLER", "112Y-280180"}, - {"ENVELOPE DETECTOR", "112Y-280249"}, - {"DOWNCONVERTER", "112Y-280456"}, - {"COAX MONITOR TRANSMITTER", "112Y-280587"}, - {"CAVITY SIMULATOR", "112Y-280232"}, - {"CABLE CONTROLLER (2 CHANNEL)","112Y-280539"}, - {"BREADBOARD", "112Y-280358"}, - {"I/O INTERFACE", "112Y-280359"}, - {"DIAGNOSTIC - BPM", "112Y-280422-1"}, - {"FAST ENVELOPE DETECTOR", "112Y-280421"}, - {"DIAGNOSTIC - CM", "112Y-280422-2"}, - {"DIAGNOSTIC - MISC", "112Y-280422-3"}, - {"FAST VECTOR DETECTOR", "112Y-280651"}, - {"SINGLE-WIDE VECTOR DETECTOR", "112Y-280672"}, - {"FM / AM", "112Y-280xxx"} -}; - -#define AT5VXI_VALID_MODEL(MODEL) \ -(AT5VXI_INDEX_FROM_MODEL(MODEL)dir.w.control = INTDISABLE; -#endif -} - - - -/* - * AT5VXI_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL -void at5vxi_init_card( - unsigned addr -) -{ - at5VxiStatus r0; - struct at5vxi_config *pc; - struct time_val *ptv; - unsigned chan; - int i; - int model; - - r0 = epvxiOpen( - addr, - at5vxiDriverID, - (unsigned long) sizeof(*pc), - at5vxi_stat); - if(r0){ - errPrintf( - r0, - __FILE__, - __LINE__, - "AT5VXI: device open failed %d\n", addr); - return; - } - - r0 = AT5VXI_PCONFIG(addr, pc); - if(r0){ - errMessage(r0, NULL); - epvxiClose(addr, at5vxiDriverID); - return; - } - - pc->pcsr = VXIBASE(addr); - pc->pdd = (struct at5vxi_dd *) &pc->pcsr->dir.r.dd; - - FASTLOCKINIT(&pc->lock); - - scanIoInit(&pc->ioscanpvt); - - - /* - * revert to power up control - * (temporarily disable the busy period) - */ - pc->pcsr->dir.w.control = 0; - - -#ifndef CONTINUOUS_OPERATION - /* - * wait 5 sec for the end of current busy cycle as required - * (busy period is temporarily disabled - * - */ - for(i=0; i<5 && BUSY(pc->pcsr); i++) - taskDelay(sysClkRateGet()); - if(BUSY(pc->pcsr)){ - epvxiClose(addr, at5vxiDriverID); - return; - } -#endif - -#if defined(INIT_BINARY_OUTS) - /* - * Set AD 664 default - */ - { - struct at5vxi_setup su; - - su.gainA = TIMES2; - su.gainB = TIMES2; - su.gainC = TIMES2; - su.gainD = TIMES2; - - su.modeA = BIPOLAR; - su.modeB = BIPOLAR; - su.modeC = BIPOLAR; - su.modeD = BIPOLAR; - - su.ch2enbl = FALSE; - su.ch1enbl = FALSE; - - (* (struct at5vxi_setup *) &pc->pdd->bio[1]) = su; - } -#endif - - /* - * Init AMD 9513 for - * - * binary division - * data ptr seq enbl - * 16 bit bus - * FOUT on - * FOUT divide by 16 - * FOUT source (F1) - * Time of day disabled - */ -# define MASTER_MODE ((uint16_t)0x2000) - *PCONTROL(pc->pcsr) = BANK0; - r0 = stc_init( &pc->pdd->tcmd, - &pc->pdd->tdata, - MASTER_MODE); - if(r0!=STC_SUCCESS){ - epvxiClose(addr, at5vxiDriverID); - return; - } - - *PCONTROL(pc->pcsr) = BANK1; - r0 = stc_init( - &pc->pdd->tcmd, - &pc->pdd->tdata, - MASTER_MODE); - if(r0!=STC_SUCCESS){ - epvxiClose(addr, at5vxiDriverID); - return; - } - - for(chan=0, ptv = pc->tv; chantv); chan++, ptv++){ - unsigned int_source; - - if(chan/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pc->pcsr) = BANK1; - } - else{ - *PCONTROL(pc->pcsr) = BANK0; - } - - /* - * casting below discards volatile - * (ok in this case) - */ - r0 = stc_one_shot_read( - (unsigned *)&ptv->preset, - (uint16_t *)&ptv->iedge0_delay, - (uint16_t *)&ptv->iedge1_delay, - &pc->pdd->tcmd, - &pc->pdd->tdata, - chan, - &int_source); - if(r0 == STC_SUCCESS && int_source == FALSE) - ptv->valid = TRUE; - else - ptv->valid = FALSE; - } - -# ifndef CONTINUOUS_OPERATION - r0 = intConnect( - INUM_TO_IVEC(addr), - at5vxi_int_service, - addr); - if(r0 == ERROR) - return; - - sysIntEnable(AT5VXI_INT_LEVEL); -# endif - - /* - * init the csr - * (see at5vxi_init() for field definitions) - * interrupts enabled if not compiled for continuous operation - */ - *PCONTROL(pc->pcsr) = CSRINIT; - - model = VXIMODEL(pc->pcsr); - if(AT5VXI_VALID_MODEL(model)){ - r0 = epvxiRegisterModelName( - VXIMAKE(pc->pcsr), - model, - at5vxi_models[AT5VXI_INDEX_FROM_MODEL(model)].name); - if(r0){ - errMessage(r0,NULL); - } - - r0 = epvxiRegisterMakeName(VXI_MAKE_AT5, "LANL AT5"); - if(r0){ - errMessage(r0,NULL); - } - } - - return; -} - - -/* - * - * AT5VXI_INT_SERVICE - * - * update card busy writes and notify the IO interrupt scanner - */ -void at5vxi_int_service( - int addr -) -{ - struct at5vxi_config *pconfig; - at5VxiStatus r0; - - r0 = AT5VXI_PCONFIG(addr, pconfig); - if(r0){ - logMsg( "AT5VXI: int before init\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - return; - } - - /* - * wake up the I/O event scanner - */ - scanIoRequest(pconfig->ioscanpvt); - - /* - * Update outputs while it is safe to do so - */ - if(pconfig->mdt){ - struct at5vxi_dd *pdd; - struct vxi_csr *pcsr; - unsigned chan; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - for(chan=0; chantv); chan++){ - unsigned chip_chan; - - if(!pconfig->tv[chan].mdt) - continue; - - - if(chan/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - } - else{ - *PCONTROL(pcsr) = BANK0; - } - - chip_chan = chan% - AT5VXI_CHANNELS_PER_TIMER_BANK; - - r0 = stc_one_shot( - pconfig->tv[chan].preset, - pconfig->tv[chan].iedge0_delay, - pconfig->tv[chan].iedge1_delay, - &pdd->tcmd, - &pdd->tdata, - chip_chan, - FALSE); - if(r0 != STC_SUCCESS){ - logMsg( "AT5 VXI- AMD9513 load fail\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - } - else{ - pconfig->tv[chan].valid = TRUE; - } - - /* - * reenable interrupts - */ - *PCONTROL(pcsr) = CSRINIT; - - pconfig->tv[chan].mdt = FALSE; - } - - for(chan=0; chanav); chan++){ - if(!pconfig->av[chan].mdt) - continue; - pdd->ao[chan] = pconfig->av[chan].val; - pconfig->av[chan].mdt = FALSE; - } - - if(pconfig->bv.mask){ - uint32_t work; - - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | - pdd->bio[0]); - - /* alter specified bits */ - work = (work & ~pconfig->bv.mask) | - (pconfig->bv.val & pconfig->bv.mask); - - pdd->bio[0] = work; - pdd->bio[1] = work>>(NBBY*sizeof(uint16_t)); - - pconfig->bv.mask = 0; - } - - if(BUSY(pcsr)) - logMsg( "AT5 VXI INT- finished with card busy\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - - pconfig->mdt = FALSE; - } - -} - - - -/* - * - * AT5VXI_ONE_SHOT - * - * setup AMD 9513 STC for a repeated two edge timing signal - */ -at5VxiStatus at5vxi_one_shot( - int preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int int_source, /* (FALSE)External/(TRUE)Internal source */ - void *event_rtn, /* subroutine to run on events */ - int event_rtn_param /* parameter to pass to above routine */ -) -{ - at5VxiStatus status; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - status = AT5VXI_PCONFIG(card, pconfig); - if(status){ - return status; - } - - pcsr = pconfig->pcsr; - -/* AT5VXI does not support internal source for now -*/ if(int_source){ - status = S_dev_badRequest; - errMessage( - status, - "AT5VXI does not support internal trigger source"); - return status; - } - -/* AT5VXI does not support interrupts on timing channels for now -*/ if(event_rtn){ - status = S_dev_badRequest; - errMessage(status, "AT5VXI does not support interrupts on timing channels"); - return status; - } - - if(channel>=AT5VXI_NTIMER_CHANNELS) - return S_dev_badSignalNumber; - -/* dont overflow unsigned short in STC -*/ if(edge0_delay >= devCreateMask(NBBY*sizeof(uint16_t))/EXT_TICKS) - return S_dev_highValue; - if(edge1_delay >= devCreateMask(NBBY*sizeof(uint16_t))/EXT_TICKS) - return S_dev_highValue; - if(edge0_delay < 0.0) - return S_dev_lowValue; - if(edge1_delay < 0.0) - return S_dev_lowValue; - - FASTLOCK(&pconfig->lock); - -# ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - if(channel/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - }else{ - *PCONTROL(pcsr) = BANK0; - } - channel = channel%AT5VXI_CHANNELS_PER_TIMER_BANK; - - status = stc_one_shot( - preset, - (uint16_t) (edge0_delay * EXT_TICKS), - (uint16_t) (edge1_delay * EXT_TICKS), - &pdd->tcmd, - &pdd->tdata, - channel, - FALSE); - - /* - * not required for now but safe - * against future mods - */ - *PCONTROL(pcsr) = CSRINIT; - } -# else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->tv[channel].preset = preset; - pconfig->tv[channel].iedge0_delay = - (edge0_delay * EXT_TICKS); - pconfig->tv[channel].iedge1_delay = - (edge1_delay * EXT_TICKS); - pconfig->tv[channel].mdt = TRUE; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; - - status = STC_SUCCESS; -# endif - - FASTUNLOCK(&pconfig->lock); - - if(status!=STC_SUCCESS){ - return status; - } - - return VXI_SUCCESS; -} - - -/* - * - * AT5VXI_ONE_SHOT_READ - * - * read back two edge timing from an AMD 9513 STC - */ -at5VxiStatus at5vxi_one_shot_read( - int *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int *int_source /* (FALSE)External/(TRUE)Internal src */ -) -{ -#ifdef CONTINUOUS_OPERATION - uint16_t iedge0; - uint16_t iedge1; -#endif - at5VxiStatus status; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - status = AT5VXI_PCONFIG(card, pconfig); - if(status) - return status; - - pcsr = pconfig->pcsr; - - if(channel>=AT5VXI_NTIMER_CHANNELS) - return S_dev_badSignalNumber; - - -# ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - FASTLOCK(&pconfig->lock); - - if(channel/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - }else{ - *PCONTROL(pcsr) = BANK0; - } - channel = channel%AT5VXI_CHANNELS_PER_TIMER_BANK; - status = stc_one_shot_read( - preset, - &iedge0, - &iedge1, - &pdd->tcmd, - &pdd->tdata, - channel, - int_source); - /* - * not required for noe but safe - * against future mods - */ - *PCONTROL(pcsr) = CSRINIT; - FASTUNLOCK(&pconfig->lock); - - if(status==STC_SUCCESS){ - /* - * AT5VXI does not support external - * source for now - */ - if(int_source) - return S_dev_badRequest; - - *edge0_delay = iedge0 / EXT_TICKS; - *edge1_delay = iedge1 / EXT_TICKS; - } - - - return status; - } -# else - if(!pconfig->tv[channel].valid) - return S_dev_badRequest; - - FASTLOCK(&pconfig->lock); - - *preset = pconfig->tv[channel].preset; - *edge0_delay = pconfig->tv[channel].iedge0_delay - /EXT_TICKS; - *edge1_delay = pconfig->tv[channel].iedge1_delay - /EXT_TICKS; - *int_source = FALSE; - - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -# endif -} - - - -/* - * - * AT5VXI_STAT - * - * print status for a single at5 vxi card - * - * - */ -void at5vxi_stat( - unsigned card, - int level -) -{ - struct vxi_csr *pcsr; - register struct at5vxi_dd *pdd; - struct at5vxi_status status; - unsigned channel; - at5VxiStatus r0; - struct at5vxi_config *pconfig; - - static char *busy_status[] = {"","busy"}; - static char *modid_status[] = {"modid-on",""}; - static char *ipend_status[] = {"","int-pending"}; - static char *ienable_status[] = {"int-disabled","int-enabled"}; - static char *ext_st_status[] = {"extended-self-testing",""}; - static char *st_status[] = {"self-testing",""}; - static char *sfinh_status[] = {"","sys-fail-inhibit"}; - static char *sreset_status[] = {"","sys-reset"}; - static char *addr_mode_status[] = {"SC","DC"}; - - if(level==0) - return; - - r0 = AT5VXI_PCONFIG(card, pconfig); - if(r0){ - errMessage(r0,NULL); - return; - } - - pcsr = VXIBASE(card); - pdd = pconfig->pdd; - - r0 = vxMemProbe( (char *)&pcsr->dir.r.status, - READ, - sizeof(status), - (char *)&status); - if(r0 != OK) - return; - - if(VXIMAKE(pcsr) != VXI_MAKE_AT5) - return; - - if(AT5VXI_VALID_MODEL(VXIMODEL(pcsr))){ - printf( "\tDrawing: %s\n", - at5vxi_models[AT5VXI_INDEX_FROM_MODEL(VXIMODEL(pcsr))].drawing); - } - - printf( - "\tcard=%d address-mode=%s %s %s %s %s ilevel=%d %s %s %s %s\n", - card, - addr_mode_status[status.dev255], - busy_status[ status.busy ], - modid_status[ status.modid_cmpl ], - ipend_status[ status.ipend ], - ienable_status[ status.ienable ], - status.ilevel, - ext_st_status[ status.ready ], - st_status[ status.passed ], - sfinh_status[ status.sfinh ], - sreset_status[ status.sreset ]); - - if(pconfig){ - if(pconfig->mdt){ - printf("\toutput update is pending for interrupt\n"); - } - } - - if(level <= 1) - return; - - for(channel=0; channelai); channel++){ - printf( - "\tAI: channel %d value %x\n", - channel, - pdd->ai[channel]); - } - - for(channel=0; channelao); channel++){ - printf( - "\tAO: channel %d value %x\n", - channel, - pdd->ao[channel]); - } - - { - uint32_t work; - - work = ((uint32_t)pdd->bio[1]) << (sizeof(uint16_t)*NBBY); - work |= pdd->bio[0]; - printf("\tBIO: value %x\n", work); - } - - for(channel=0; channeltv); channel++){ - at5vxi_report_timing(card, channel); - } - - return; -} - - -/* - * - * - * AT5VXI_REPORT_TIMING - * - * diagnostic - */ -LOCAL -at5VxiStatus at5vxi_report_timing( - unsigned card, - unsigned channel -) -{ - int preset; - double edge0_delay; - double edge1_delay; - int int_source; - at5VxiStatus status; - char *clk_src[] = {"external-clk", "internal-clk"}; - - status = - at5vxi_one_shot_read( - &preset, - &edge0_delay, - &edge1_delay, - card, - channel, - &int_source); - if(status == VXI_SUCCESS) - printf( - "\tTI: channel %d preset %d delay %f width %f %s\n", - channel, - preset, - edge0_delay, - edge1_delay, - clk_src[int_source?1:0]); - - return status; -} - - -/* - * - * - * AT5VXI_AI_DRIVER - * - * analog input driver - */ -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -) -{ - at5VxiStatus s; - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ai)) - return S_dev_badSignalNumber; - - *prval = pdd->ai[chan]; - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_AO_DRIVER - * - * analog output driver - */ -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -) -{ - struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ao)) - return S_dev_badSignalNumber; - -#ifdef CONTINUOUS_OPERATION - pdd->ao[chan] = *prval; - *prbval = pdd->ao[chan]; -#else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->av[chan].val = *prval; - pconfig->av[chan].mdt = TRUE; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; - - *prbval = *prval; -#endif - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_AO_READ - * - * analog output read back - */ -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -) -{ - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s){ - return s; - } - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ao)) - return S_dev_badSignalNumber; - - *pval = pdd->ao[chan]; - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_BI_DRIVER - * - * binary input driver - */ -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -) -{ - register uint32_t work; - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - FASTLOCK(&pconfig->lock); - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | pdd->bio[0]); - *prval = mask & work; - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_BO_DRIVER - * - * binary output driver - */ -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -) -{ -#ifdef CONTINUOUS_OPERATION - register uint32_t work; -#endif - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - - FASTLOCK(&pconfig->lock); - -#ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | pdd->bio[0]); - - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - pdd->bio[0] = work; - pdd->bio[1] = work>>(NBBY*sizeof(uint16_t)); - } -#else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->bv.val = (pconfig->bv.val & ~mask) | (val & mask); - pconfig->bv.mask |= mask; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; -#endif - - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -} - - -/* - * - * at5vxi_getioscanpvt() - * - * - */ -at5VxiStatus at5vxi_getioscanpvt( -unsigned card, -IOSCANPVT *scanpvt -) -{ - struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s == VXI_SUCCESS){ - *scanpvt = pconfig->ioscanpvt; - } - return s; -} - diff --git a/src/drv/old/drvAt5Vxi.h b/src/drv/old/drvAt5Vxi.h deleted file mode 100644 index 97e4a23b3..000000000 --- a/src/drv/old/drvAt5Vxi.h +++ /dev/null @@ -1,93 +0,0 @@ -/* base/src/drv $Id$ */ - -/* - * - * driver for at5 designed VXI modules - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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: - * ----------------- - */ - -typedef long at5VxiStatus; - -at5VxiStatus at5vxi_one_shot( - int preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int int_source, /* (FALSE)External/(TRUE)Internal source - */ - void *event_rtn, /* subroutine to run on events */ - int event_rtn_param /* parameter to pass to above routine */ -); - -at5VxiStatus at5vxi_one_shot_read( - int *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - int *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -); - -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -); - -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -); - -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -); - -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -); - -at5VxiStatus at5vxi_getioscanpvt( - unsigned card, - IOSCANPVT *scanpvt -); - diff --git a/src/drv/old/drvCaenV265.c b/src/drv/old/drvCaenV265.c deleted file mode 100644 index ed42f1f3b..000000000 --- a/src/drv/old/drvCaenV265.c +++ /dev/null @@ -1,807 +0,0 @@ -/* share/src/drv @(#)drvCaenV265.c 1.1 9/2/94 */ -/* drvCaenV265.c - Driver/Device Support Routines for CAEN V265 - * - * Author: Jeff Hill (johill@lanl.gov) - * Date: 8-11-94 - * - * 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 - * MIT Bates Lab - * - * Modification Log: - * ----------------- - */ - -/* - * ANSI C Includes - */ -#include -#include -#include -#include - -/* - * vxWorks includes - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * EPICS include - */ -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * base address, base interrupt vector, - * number of cards, & interrupt level - */ -#define CAIN_V265_A24_BASE (0x000000) -#define CAIN_V265_INTVEC_BASE (0xA0) -#define CAIN_V265_MAX_CARD_COUNT (8) -#define CAIN_V265_INT_LEVEL (6) - - - - -/* - * all device registers declared - * ANSI C volatile so we dont need to - * use the -fvolatile flag (and dont - * limit the optimizer) - */ -typedef volatile int16_t devReg; - -struct caenV265 { - devReg csr; - devReg clear; - devReg DAC; - devReg gate; - const devReg data; - const devReg pad1[(0xf8-0x8)/2]; - const devReg fixed; - const devReg identifier; - const devReg version; -}; -#define CAENV265ID 0x0812 - -/* - * Insert or extract a bit field using the standard - * masks and shifts defined below - */ -#ifdef __STDC__ -#define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S)) -#define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M)) -#else /*__STDC__*/ -#define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S)) -#define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M)) -#endif /*__STDC__*/ - -/* - * in the constants below _M is a right justified mask - * and _S is a shift required to right justify the field - */ - -/* - * csr register - */ -#define FD_FULL_M (0x1) -#define FD_FULL_S (14) -#define FD_READY_M (0x1) -#define FD_READY_S (15) -#define FD_BUSY_FULL_M (0x3) -#define FD_BUSY_FULL_S (14) -#define FD_IVEC_M (0xff) -#define FD_IVEC_S (0) -#define FD_ILEVEL_M (0x7) -#define FD_ILEVEL_S (8) - -/* - * series/version register - */ -#define FD_SERIES_M (0xfff) -#define FD_SERIES_S (0) -#define FD_VERSION_M (0xf) -#define FD_VERSION_S (12) - -/* - * data register - */ -#define FD_CHANNEL_M (0x7) -#define FD_CHANNEL_S (13) -#define FD_RANGE_M (1) -#define FD_RANGE_S (12) -#define FD_DATA_M (0xfff) -#define FD_DATA_S (0) - -struct channel{ - int16_t signal; - char newData; -}; - -enum adc_range {adc_12, adc_15, NUMBER_OF_ADC_RANGES}; -#define NUMBER_OF_SIGNALS 8 -#define NUMBER_OF_FIFO_ENTRIES (16*NUMBER_OF_SIGNALS*NUMBER_OF_ADC_RANGES) -LOCAL struct caenV265Config{ - struct caenV265 *pCaenV265; /* pointer to the card */ - struct channel chan[NUMBER_OF_SIGNALS][NUMBER_OF_ADC_RANGES]; - IOSCANPVT scanpvt; - WDOG_ID wdid; -}caenV265Info[CAIN_V265_MAX_CARD_COUNT]; - -#ifdef __STDC__ -#define SHOW_OFFSET(STRUCT,FIELD) \ -printf( "%s.%s is at 0x%X\n", \ - #STRUCT, \ - #FIELD, \ - offsetof(struct STRUCT, FIELD)) -#endif - -LOCAL void caenV265ISR(unsigned card); -LOCAL int caenV265Shutdown(void); -LOCAL int caenV265IdTest(struct caenV265 *pCaenV265); -int caenV265Test(unsigned card); -LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config); -LOCAL int caenV265TestVal(unsigned card, unsigned dacVal); -LOCAL int caenV265IntEnable(unsigned card); - -/* - * device support entry table - */ -LOCAL long caenV265InitRecord(struct aiRecord *pai); -LOCAL long caenV265AiRead(struct aiRecord *pai); -LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after); -LOCAL long caenV265GetIoIntInfo(int cmd, struct aiRecord *pai, IOSCANPVT *ppvt); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} devCaenV265 ={ - 6, - NULL, - NULL, - caenV265InitRecord, - caenV265GetIoIntInfo, - caenV265AiRead, - caenV265SpecialLinconv}; - -/* - * driver support entry table - */ -LOCAL long caenV265Init(void); -LOCAL long caenV265IOReport(int level); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvCaenV265 ={ - 2, - caenV265IOReport, - caenV265Init}; - - - -/* - * verify that register - * offsets match the doc. - */ -#ifdef DEBUG -void offsettest() -{ - SHOW_OFFSET(caenV265, version); - SHOW_OFFSET(caenV265, identifier); - SHOW_OFFSET(caenV265, fixed); - SHOW_OFFSET(caenV265, data); - SHOW_OFFSET(caenV265, gate); - SHOW_OFFSET(caenV265, DAC); - SHOW_OFFSET(caenV265, clear); - SHOW_OFFSET(caenV265, csr); - - return; -} -#endif - - -/* - * caenV265InitRecord() - */ -LOCAL long caenV265InitRecord(struct aiRecord *pai) -{ - struct vmeio *pvmeio; - - /* ai.inp must be an VME_IO */ - switch (pai->inp.type) { - case (VME_IO): - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiXy566Se (init_record) Illegal INP field"); - return(S_db_badField); - } - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad signal or card number - */ - if ( pvmeio->signal >= NUMBER_OF_SIGNALS || - pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 bad card or signal number"); - return -1; - } - - if(!caenV265Info[pvmeio->card].pCaenV265){ - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 card does not exist"); - return -1; - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M; - - return(0); -} - - -/* - * caenV265AiRead() - */ -LOCAL long caenV265AiRead(struct aiRecord *pai) -{ - int16_t value; - struct vmeio *pvmeio; - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad signal or card number - */ - if ( pvmeio->signal >= NUMBER_OF_SIGNALS || - pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - - recGblSetSevr(pai, READ_ALARM, INVALID_ALARM); - return -1; - } - - /* - * uninitialized data? - */ - if (!caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].newData) { - recGblSetSevr(pai, READ_ALARM, INVALID_ALARM); - return -1; - } - - value = caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].signal; - pai->rval = value; - - return 0; -} - - -/* - * caenV265SpecialLinconv() - */ -LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after) -{ - if(!after) { - return 0; - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M; - return 0; -} - - -/* - * caenV265GetIoIntInfo() - */ -LOCAL long caenV265GetIoIntInfo( -int cmd, -struct aiRecord *pai, -IOSCANPVT *ppvt) -{ - struct vmeio *pvmeio; - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad card number - */ - if ( pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - logMsg( - "%s.%d:devCaenV265 bad card number %d %s\n", - (int)__FILE__, - __LINE__, - pvmeio->card, - (int)pai->name,0,0); - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 bad card number"); - return -1; - } - - *ppvt = &caenV265Info[pvmeio->card].scanpvt; - - return 0; -} - - -/* - * caenV265Init() - */ -LOCAL long caenV265Init(void) -{ - unsigned card; - struct caenV265 *pCaenV265; - int status; - - status = rebootHookAdd(caenV265Shutdown); - if(status){ - errMessage(S_dev_internal,"reboot hook add failed"); - return ERROR; - } - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - CAIN_V265_A24_BASE, - (char **)&pCaenV265); - if(status!=OK){ - errPrintf( - S_dev_badA24, - __FILE__, - __LINE__, - "caenV265Init"); - return ERROR; - } - - for(card=0; cardclear = 0; /* any rw op resets the device */ - pCaenV265->DAC = 0; /* set test-signal "offset" to zero */ - - /* - * attach ISR - */ - vec = CAIN_V265_INTVEC_BASE+card; - status = intConnect( - INUM_TO_IVEC(vec), - caenV265ISR, - card); - assert(status>=0); - - /* - * Enable interrupts - */ - caenV265IntEnable(card); - } - status = sysIntEnable(CAIN_V265_INT_LEVEL); - assert(status>=0); - - return OK; -} - - -/* - * caenV265ISR() - */ -LOCAL void caenV265ISR(unsigned card) -{ - struct caenV265Config *pCaenV256Config = &caenV265Info[card]; - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - unsigned signal; - int16_t csr; - static unsigned ticks; - unsigned newTicks; - - /* - * If its full then its more efficient - * to read it out without checking - * in between each read - */ - csr = pCaenV265->csr; - if (EXTRACT(FULL,csr)) { - for( signal=0; - signalcsr; - } - - /* - * limit the EPICS scan rate - */ - newTicks = tickGet(); - if(newTicks == ticks){ - /* - * Disable Interrupts - */ - pCaenV265->csr = 0; - - /* - * start a watch dog after one tick - * so that we limit the int rate to - * the system tick rate. - */ - wdStart(pCaenV256Config->wdid, - 1, - caenV265IntEnable, - card); - - return; - } - else{ - ticks = newTicks; - } - - /* - * tell EPICS to scan on int - */ - scanIoRequest(&caenV265Info[card].scanpvt); - - return; -} - - -/* - * caenV265IntEnable - */ -LOCAL int caenV265IntEnable(unsigned card) -{ - struct caenV265Config *pCaenV256Config = &caenV265Info[card]; - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - unsigned vec; - int16_t newcsr; - - - vec = CAIN_V265_INTVEC_BASE+card; - newcsr = INSERT(IVEC, vec) | INSERT(ILEVEL, CAIN_V265_INT_LEVEL); - pCaenV265->csr = newcsr; - - return OK; -} - - -/* - * caenV265ReadData() - */ -LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config) -{ - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - int16_t val = pCaenV265->data; - int16_t data = EXTRACT(DATA, val); - unsigned range = EXTRACT(RANGE, val); - unsigned signal = EXTRACT(CHANNEL, val); - - if(range>=NUMBER_OF_ADC_RANGES){ - logMsg("caenV265ReadData: bad range number\n",0,0,0,0,0,0); - return; - } - if(signal>=NUMBER_OF_SIGNALS){ - logMsg("caenV265ReadData: bad signal number\n",0,0,0,0,0,0); - return; - } - pCaenV256Config->chan[signal][range].signal=data; - pCaenV256Config->chan[signal][range].newData=TRUE; - - return; -} - - -/* - * caenV265IdTest() - */ -LOCAL int caenV265IdTest(struct caenV265 *pCaenV265) -{ - int status; - int16_t id; - - /* - * Is a card present - */ - status = vxMemProbe( - (char *)&pCaenV265->identifier, - READ, - sizeof(id), - (char *)&id); - if(status!=OK){ - return FALSE; - } - - /* - * Is the correct type of card present - */ - if(id!=CAENV265ID){ - errPrintf( - S_dev_wrongDevice, - __FILE__, - __LINE__, - "caenV265IdTest"); - return FALSE; - } - return TRUE; -} - - -/* - * caenV265Shutdown() - * turns off interrupts so that dont foul up the boot - */ -LOCAL int caenV265Shutdown(void) -{ - struct caenV265 *pCaenV265; - unsigned card; - - for(card=0; cardcsr=0; - } - } - return OK; -} - - -/* - * caenV265Test() - */ -int caenV265Test(unsigned card) -{ - unsigned dacVal; - struct caenV265Config cofigCpy; - unsigned range; - unsigned signal; - - - dacVal=0; - caenV265TestVal(card, dacVal); - while(dacValpCaenV265; - unsigned signal; - - if(!pCaenV265){ - return ERROR; - } - - if(!caenV265IdTest(pCaenV265)){ - return ERROR; - } - - /* - * clear the module - */ - pCaenV265->clear=0; - - /* - * generate a test signal - */ - pCaenV265->DAC=dacVal; - - /* - * generate a test gate - */ - for( signal=0; - signalgate=0; - taskDelay(1); - } - while(!caenV265Info[card].chan[signal][adc_12].newData){ - pCaenV265->gate=0; - taskDelay(1); - } - } - - /* - * turn off test signal - */ - pCaenV265->clear=0; - pCaenV265->DAC=0; - - return OK; -} - - -/* - * caenV265IOReport() - */ -LOCAL long caenV265IOReport(int level) -{ - struct caenV265 *pCaenV265; - unsigned card; - unsigned signal; - unsigned range; - char *pVersion[] = {"NIM","ECL"}; - char *pState[] = { - "FIFO empty", - "FIFO full", - "FIFO partially filled", - "FIFO full"}; - - for (card=0; cardversion)]); - printf("\tseries = %d\n", - EXTRACT(SERIES, pCaenV265->version)); - printf("\tstate = %s\n", - pState[EXTRACT(BUSY_FULL,pCaenV265->csr)]); - printf("\tint level = %d\n", - EXTRACT(ILEVEL,pCaenV265->csr)); - printf("\tint vec = 0x%02X\n", - EXTRACT(IVEC,pCaenV265->csr)); - printf( "\tbase addr= 0x%X on the %s\n", - (unsigned)caenV265Info[card].pCaenV265, - sysModel()); - - for( range=0; - range\n", - signal); - } - } - - } - } - return OK; -} diff --git a/src/drv/old/drvEpvxi.c b/src/drv/old/drvEpvxi.c deleted file mode 100644 index ed7c8d100..000000000 --- a/src/drv/old/drvEpvxi.c +++ /dev/null @@ -1,4448 +0,0 @@ -/* - * drvEpvxi.c - * - * base/src/drv $Id$ - * Routines for the VXI device support and resource management. - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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 joh 02-14-90 formal release - * .02 joh 04-04-90 as requested KLUDGED dynamic address so they - * dont have to specify model number in DCT - * .03 joh 04-04-90 as requested KLUDGED dynamic address so they - * dont have to specify model number in DCT - * .04 joh 07-26-90 changed from ttl trig 7 to ecl trig 0 - * .05 joh 07-27-90 added support for multiple slot0 cards - * .06 joh 08-08-91 delinting - * .07 joh 09-05-91 converted to v5 vxWorks - * .08 joh 12-05-91 split vxi_driver.c into vxi_driver.c and - * vxi_resman.c - * .09 joh 01-29-91 added MXI support & removed KLUDGE - * .10 joh 07-06-92 added A24 & A32 address config - * .11 joh 07-07-92 added routine to return A24 or A32 base - * .12 joh 07-13-92 merged in model hash support written by - * Richard Baker (summer intern) - * .13 joh 07-21-92 Now stores extender info in a hierarchical - * linked list - * .14 joh 07-29-92 vxi record topology needed check for - * device present - * .15 joh 07-29-92 added sccs id - * .16 joh 08-19-92 make name registration - * .17 joh 08-21-92 cleaned up A24/A32 MXI setup - * .18 joh 08-26-92 dont return error if a make or model - * has already been registered - * .19 joh 09-03-92 Use the correct routine in NIVXI - * for CPU030 trigger routing - * .20 joh 09-30-92 split epvxiOpen() into epvxiOpen() and - * epvxiDeviceVerify() - * .21 joh 10-30-92 NI CPU030 trigger routing was failing - * due to no entry for the 030 in the resman - * tables - it cant see itself in A16. - * A work around was installed. - * .22 joh 05-24-93 Fixed over-zealous parameter checks in - * TTL trigger route - * .23 joh 06-03-93 Fixed incorrect MXI BP TTL trigger enable - * .24 joh 07-12-93 Record the task id when opening a device - * .25 joh 07-21-93 Improved DC device allocation in MXI - * environment - * .26 joh 11-10-93 Now configures multiple DC devices per slot. - * Blocked address devices are preallocated - * where possible. Independently addressed - * multiple devices per slot are allocated on - * demand. - * - * RM unfinished items - * ------------------- - * 1. Assigning the cmdr/serv hierarchy from within a DC res man - * needs to be revisited - * 2. Should this module prevent two triggers from driving - * the same front panel connector at once? - * - * - * NOTES - * ----- - * - * - */ - -/* - * Code Portions - * - * local - * vxi_find_slot given a VXI modules addr find its slot - * vxi_init_ignore_list init list of interrupt handlers to ignore - * vxi_vec_inuse check to see if vector is in use - * vxi_configure_hierarchies setup commander servant hierarchies - * vxi_self_test test for dev self test passed - * open_slot0_device open slot zero devices - * nicpu030_init NI CPU030 controller setup - * nivxi_cpu030_set_modid set modid on the NICPU030 - * nivxi_cpu030_clr_all_modid clear all modid lines on the NICPU030 - * set_reg_modid set modid on a reg based slot0 device - * clr_all_reg_modid clr all modid on a reg based slot0 dev - * vxi_find_sc_devices find all SC devices and open them - * vxi_find_dc_devices find all DC devices and open them - * vxi_count_dc_devices determine the number of DC devices in - * this extender - * vxi_init_ignore_list find addresses of default int handlers - * vxi_vec_inuse test for int vector in use - * mxi_map mat the addresses on a MXI bus extender - * vxi_find_mxi_devices search for and open mxi bus repeaters - * map_mxi_inward map from a VXI crate towards the RM - * vxi_address_config setup A24 and A32 offsets - * open_vxi_device log VXI device info - * vxi_record_topology find slots and extenders for each device - * - * for use by IOC core - * epvxiResman entry for a VXI resource manager which - * also sets up the MXI bus - * epvxiIOReport call io device specific report routines - * for all registered devices and print - * information about device's configuration - * epvxiDeviceList print info useful when debugging drivers - * vxi_init backwards compatibility - * vxi_io_report backwards compatibility - * - * for use by vxi drivers - * epvxiLookupLA find LA given search pattern - * epvxiUniqueDriverID obtain a unique id each call - * epvxiOpen register a drivers use of a device - * epvxiClose disconnect from a device - * epvxiPConfig fetch a driver config block given a LA - * epvxiRouteTriggerECL route ECL trig to/from front panel - * epvxiRouteTriggerTTL route TTL trig to/from front panel - * - */ - -static char *sccsId = "$Id$\t$Date$"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if 0 -#include -#endif - -#include -#define SRCepvxiLib /* allocate externals here */ -#include -#include - -#define NICPU030 - -/* - * EPICS driver entry point table - */ -typedef long (*DRVSUPFUN) (); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvVxi={ - 2, - epvxiIOReport, - epvxiResman}; - - -/* - * so setting ECL triggers does not mess with the - * RM's address windows - */ -#define MXI_CONTROL_CONSTANT 0x4000 -#define INTX_INT_OUT_ENABLE 0x7f00 -#define INTX_INT_IN_ENABLE 0x7f7f - -#define abort(A) taskSuspend(0) - -#define VXIMSGINTLEVEL 1 - -#define BELL 7 - -#define UKN_LA (-1) -#define UKN_SLOT (-1) -#define UKN_CRATE (-1) - -#define DEFAULT_VXI_A24_BASE 0x90000 -#define DEFAULT_VXI_A24_SIZE 0x10000 -#define DEFAULT_VXI_A32_BASE 0x90000000 -#define DEFAULT_VXI_A32_SIZE 0x10000000 - -/* - * laPassLast and laPassFirst must be last/first respectively - * and have no purpose outside of being delimiters - */ -enum laPass { - laPassSC, - laPassAnchoredDC, - laPassFloatingDC, - laPassSetWindows}; - - -LOCAL char niCpu030Initialized; -LOCAL VXIE root_extender; -LOCAL ELLLIST crateList; - -LOCAL char *ignore_list[] = {"_excStub","_excIntStub"}; -LOCAL void *ignore_addr_list[NELEMENTS(ignore_list)]; -LOCAL unsigned char last_la; -LOCAL unsigned char first_la; - -#define SETMODID(PVXISZ, SLOT) \ -(*(PVXISZ)->set_modid)((PVXISZ), SLOT) - -#define CLRMODID(PVXISZ) \ -(*(PVXISZ)->clear_modid)(PVXISZ); - -LOCAL -SYMTAB *epvxiSymbolTable; -LOCAL -char epvxiSymbolTableDeviceIdString[] = "%03x:%03x"; -LOCAL -char epvxiSymbolTableMakeIdString[] = "%03x"; - -/* - * for the VXI symbol table - * just contains model names for now - */ -#define EPVXI_MODEL_NAME_SYMBOL 1 -#define EPVXI_MAKE_NAME_SYMBOL 2 -#define EPVXI_MAX_SYMBOLS_LOG2 8 -#define EPVXI_MAX_SYMBOLS (1<la_mapped){ - break; - } - vxi_find_dc_devices(pvxie); - break; - - - /* - * allocate DC devices - */ - case laPassAnchoredDC: - /* - * wait until laPassFloatingDC if - * nothing is mapped - */ - if(!pvxie->la_mapped){ - break; - } - vxi_find_dc_devices(pvxie); - break; - - default: - break; - } - - /* - * - * find any MXI bus repeaters - * - */ - vxi_find_mxi_devices( - pvxie, - pass); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_unmap_mxi_devices() - * - * close any MXI devices which have open windows but - * have not been encountered by this execution - * of the resource manager. - * - * This makes the MXI/VXI configure correctly after - * a control x (soft) reboot. - */ -LOCAL void vxi_unmap_mxi_devices(void) -{ - struct vxi_csr *pmxi; - EPVXISTAT status; - int16_t id; - unsigned addr; - - for(addr=first_la; addr<=last_la; addr++){ - /* - * only configure devices not seen before - */ - if(epvxiLibDeviceList[addr]){ - continue; - } - - pmxi = VXIBASE(addr); - - status = vxMemProbe( (char *)pmxi, - READ, - sizeof(id), - (char *)&id); - if(status<0){ - continue; - } - - if(!VXIMXI(pmxi)){ - continue; - } - - /* - * force all of these back to the hard reset state - */ - pmxi->dir.w.dd.mxi.la_window = 0; - pmxi->dir.w.dd.mxi.a16_window_low = 0; - pmxi->dir.w.dd.mxi.a16_window_high = 0; - pmxi->dir.w.dd.mxi.a24_window_low = 0; - pmxi->dir.w.dd.mxi.a24_window_high = 0; - pmxi->dir.w.dd.mxi.a32_window_low = 0; - pmxi->dir.w.dd.mxi.a32_window_high = 0; - } -} - - - -/* - * - * vxi_find_mxi_devices() - * - */ -LOCAL void vxi_find_mxi_devices( -VXIE *pvxie, -enum laPass pass -) -{ - struct vxi_csr *pmxi; - unsigned addr; - VXIDI *pvxidi; - VXIE *pnewvxie; - - for( addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - - /* - * only configure devices seen before - */ - if(!pvxidi){ - continue; - } - - /* - * skip MXI devices which are not - * in this extender - */ - if(pvxidi->pvxie != pvxie){ - continue; - } - - pmxi = VXIBASE(addr); - - pnewvxie = open_mxi_device( - addr, - pvxie, - ext_import_mxi_into_vxi); - if(!pnewvxie){ - continue; - } - - /* - * open the LA window outward over the entire LA range - */ - pmxi->dir.w.dd.mxi.control = - MXI_UPPER_LOWER_BOUNDS; - pmxi->dir.w.dd.mxi.la_window = - VXIADDRMASK | (VXIADDRMASK<la_mapped){ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, pnewvxie->la_low); - pvxie->la_high = max(pvxie->la_high, pnewvxie->la_high); - } - - /* - * disable the window until the last pass - */ - if(pass != laPassSetWindows){ - pmxi->dir.w.dd.mxi.la_window = - 0 | (0<la_mapped){ -# ifdef DEBUG - printf( "VXI resman: VXI to MXI(%x) %x-%x\n", - addr, - pnewvxie->la_low, - pnewvxie->la_high); -# endif - pmxi->dir.w.dd.mxi.la_window = - (pnewvxie->la_low<la_high+1); - - /* - * if INTX is installed gate the interrupts off of - * INTX - */ - if(MXIINTX(pmxi)){ - pmxi->dir.w.dd.mxi.INTX_interrupt = - INTX_INT_IN_ENABLE; - } - } - else{ - printf( "VXI resman: VXI to MXI LA=0x%X is empty\n", - addr); - pmxi->dir.w.dd.mxi.la_window = - 0 | (0<pvxieSelf){ - return pvxidi->pvxieSelf; - } - - pnewvxie = (VXIE *) calloc(1, sizeof(*pnewvxie)); - if(!pnewvxie){ - errMessage(S_epvxi_noMemory, "MXI device ignored"); - return NULL; - } - - pnewvxie->type = type; - pnewvxie->la = la; - pnewvxie->la_low = last_la; - pnewvxie->la_high = first_la; - pnewvxie->pParent = pvxie; - - pvxidi->pvxieSelf = pnewvxie; - - /* - * make sure PARENT window includes the MXI - * bus extender - */ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, la); - pvxie->la_high = max(pvxie->la_high, la); - ellAdd(&pvxie->extenders, &pnewvxie->node); - - epvxiRegisterModelName( - VXIMAKE(pmxi), - VXIMODEL(pmxi), - "MXI bus extender"); - - return pnewvxie; -} - - -/* - * MAP_MXI_INWARD - * - * for each MXI found that we have not seen before - * open the la window inward for all devices - * - */ -LOCAL EPVXISTAT map_mxi_inward( -VXIE *pvxie, -enum laPass pass -) -{ - VXIDI *pvxidi; - struct vxi_csr *pmxi_new; - unsigned addr; - EPVXISTAT status; - VXIE *pnewvxie; - - /* - * open all new MXI devices now - * so that we dont confuse them with - * SC devices when a MXI's window is - * completely open. - * - * If we attempt to communicate with a - * MXI device while another MXI device - * at the same level has its window open - * all the way we see VME bus conflicts. - */ - for(addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - if(!pvxidi){ - /* - * if it has not been seen before we know - * its a MXI device - */ - status = open_vxi_device(pvxie, addr); - if(status==VXI_SUCCESS){ - open_mxi_device( - addr, - pvxie, - ext_export_vxi_onto_mxi); - } - } - } - - /* - * now step through and open up all MXI devices found - */ - for(addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - - if(!pvxidi){ - continue; - } - - pnewvxie = pvxidi->pvxieSelf; - - /* - * dont bother with - * devices that are - * not extenders - * here - */ - if(!pnewvxie){ - continue; - } - - /* - * if it is an extender dont - * configure it unless - * it is a child of the - * current parent - */ - if(pvxidi->pvxie != pvxie){ - continue; - } - - pmxi_new = VXIBASE(addr); - - /* - * open the address window inward for all device - */ - pmxi_new->dir.w.dd.mxi.control = - MXI_UPPER_LOWER_BOUNDS; - pmxi_new->dir.w.dd.mxi.la_window = - 1 | (1<la_mapped){ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, pnewvxie->la_low); - pvxie->la_high = max(pvxie->la_high, pnewvxie->la_high); - } - - /* - * temporarily close the windows so that we can discover - * iproperly located SC devices - */ - if(pass != laPassSetWindows){ - pmxi_new->dir.w.dd.mxi.la_window = - 0 | (0<la_mapped){ -# ifdef DEBUG - printf( "VXI resman: MXI to VXI LA=%x %x-%x\n", - addr, - pnewvxie->la_low, - pnewvxie->la_high); -# endif - pmxi_new->dir.w.dd.mxi.la_window = - pnewvxie->la_low | - ((pnewvxie->la_high+1)<dir.w.dd.mxi.INTX_interrupt = - INTX_INT_OUT_ENABLE; - } - } - else{ - - printf( "VXI resman: MXI to VXI LA=0x%X is empty\n", - addr); - pmxi_new->dir.w.dd.mxi.la_window = - 0 | (0<node.next; - if(pvxisz->la == pnewvxie->la || - pvxisz->pvxie == pnewvxie){ - ellDelete(&crateList, &pvxisz->node); - } - pvxisz = next; - } -# endif /*REMOVE_UNUSED_SLOT_ZERO_DEVICES*/ - } - } - return VXI_SUCCESS; -} - - -/* - * - * open_vxi_device - * - * - */ -LOCAL EPVXISTAT open_vxi_device( -VXIE *pvxie, -unsigned la -) -{ - struct vxi_csr *pdevice; - VXIDI *plac; - int16_t id; - EPVXISTAT status; - - /* - * just return if this device is known about - */ - if(epvxiLibDeviceList[la]){ - return VXI_SUCCESS; - } - - pdevice = VXIBASE(la); - - status = vxMemProbe( (char *)pdevice, - READ, - sizeof(id), - (char *)&id); - if(status<0){ - return S_dev_noDevice; - } - - status = verify_valid_window(pvxie, la); - if(status){ - errMessage( - status, - "VXI resman: no access to SC device"); - errMessage( - status, - "VXI resman: without MXI LA window overlap."); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: SC device LA=0X%X", - la); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: extender LA=0X%X", - pvxie->la); - errMessage( - status, - "VXI resman: SC device ignored"); - return status; - } - - plac = (VXIDI *) calloc(1, sizeof(**epvxiLibDeviceList)); - if(!plac){ - errMessage(S_epvxi_noMemory,"... continuing"); - return S_epvxi_noMemory; - } - - plac->make = VXIMAKE(pdevice); - plac->model = VXIMODEL(pdevice); - plac->class = VXICLASS(pdevice); - plac->pvxie = pvxie; - epvxiLibDeviceList[la] = plac; - - pvxie->la_low = min(pvxie->la_low, la); - pvxie->la_high = max(pvxie->la_high, la); - pvxie->la_mapped = TRUE; - - if(vxi_vec_inuse(la)){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "SC VXI device at allocated int vec=0x%X", - la); - epvxiSetDeviceOffline(la); - } - else{ - if(VXISLOT0MODELTEST(plac->model)){ - plac->slot0_dev = TRUE; - open_slot0_device(pvxie, la); - } - } - -# ifdef DEBUG - printf("Found LA=0X%X extender LA=0X%X\n", la, pvxie->la); -# endif - - return VXI_SUCCESS; -} - - -/* - * - * verify_valid_window() - * - * determine if this la is within one - * of the other extenders at the same level - * - */ -LOCAL EPVXISTAT verify_valid_window( -VXIE *pvxie, -unsigned la -) -{ - VXIE *pChild; - - /* - * If its the root extender we dont care - */ - if(!pvxie->pParent){ - return VXI_SUCCESS; - } - - for( pChild = (VXIE *) pvxie->pParent->extenders.node.next; - pChild; - pChild = (VXIE *) pChild->node.next){ - - /* - * of course its ok to be in the - * current extender - */ - if(pChild == pvxie){ - continue; - } - - /* - * its not ok to overlap other extenders - * window - */ - if(pChild->la_mapped){ - if(la >= pChild->la_low && - la <= pChild->la_high){ - - return S_epvxi_badConfig; - } - } - } - - /* - * traverse the hierarchy - */ - return verify_valid_window(pvxie->pParent, la); -} - - -/* - * - * - * VXI_FIND_SC_DEVICES - * - */ -LOCAL void vxi_find_sc_devices( -VXIE *pvxie -) -{ - unsigned addr; - - /* - * Locate the slots of all SC devices - */ - for(addr=first_la; addr<=last_la; addr++){ - - /* - * dont configure devices seen before - */ - if(epvxiLibDeviceList[addr]){ - continue; - } - - (void) open_vxi_device(pvxie, addr); - } -} - - -/* - * - * vxi_record_topology() - * - * Record topological information after all MXIs - * and slot zero cards have been located since - * MXIs can appear in the address space prior - * to their slot zero cards ( so their slots - * cant be found initially ). - * - */ -LOCAL void vxi_record_topology(void) -{ - VXIDI **pplac; - struct vxi_csr *pdevice; - VXISZ *pvxisz; - unsigned la; - unsigned slot; - EPVXISTAT status; - - for( la=first_la, pplac = epvxiLibDeviceList; - la<=last_la; - la++, pplac++){ - - if(!*pplac){ - continue; - } - - pdevice = VXIBASE(la); - status = vxi_find_slot(pdevice, &slot, &pvxisz); - if(status==VXI_SUCCESS){ - (*pplac)->slot = slot; - (*pplac)->slot_zero_la = pvxisz->la; - (*pplac)->extender_la = pvxisz->pvxie->la; - - if(VXISLOT0MODEL(pdevice)){ - if((*pplac)->slot!=0){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI slot 0 found in slot %d? LA=0x%X", - (*pplac)->slot, - la); - } - } - } - else{ - errPrintf( - status, - __FILE__, - __LINE__, - "LA=0X%X", - la); - (*pplac)->slot = UKN_SLOT; - (*pplac)->slot_zero_la = UKN_LA; - (*pplac)->extender_la = UKN_LA; - } - } -} - - -/* - * - * - * VXI_FIND_DC_DEVICES - * - */ -LOCAL void vxi_find_dc_devices( -VXIE *pvxie -) -{ - int prealloc; - int16_t id; - EPVXISTAT status; - unsigned offset; - struct vxi_csr *pcsr; - VXISZ *pvxisz; - unsigned nDC; - int slot; - - /* - * dont move DC devices if SC device at address 0xff - */ - if(epvxiLibDeviceList[VXIDYNAMICADDR]){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI SC device recorded at dynamic address 0x%X", - VXIDYNAMICADDR); - errMessage( - S_epvxi_badConfig, - "VXI DC devices ignored"); - return; - } - - pcsr = VXIBASE(VXIDYNAMICADDR); - status = vxMemProbe( (char *)pcsr, - READ, - sizeof(id), - (char *)&id); - if(status == OK){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI SC device at dynamic address 0x%X", - VXIDYNAMICADDR); - errMessage( - S_epvxi_badConfig, - "VXI DC devices ignored"); - return; - } - - /* - * if unanchored force them to all be in one - * contiguous block - */ - prealloc = FALSE; - if(!pvxie->la_mapped){ - status = vxi_count_dc_devices(pvxie, &nDC); - if(status){ - return; - } - if(nDC < 1){ - return; - } - status = vxi_alloc_la( - pvxie, - nDC, - &offset); - if(status){ - errMessage( - status, - "VXI resman: unanchored DC VXI device block doesnt fit"); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: %d DC VXI devices in extender LA=0X%X ignored", - nDC, - pvxie->la); - return; - } - prealloc = TRUE; - } - - /* - * find all DC devices - */ - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - /* - * We wish to selectively configure DC devices - * accessed through the current extender. - * - * If the slot zero card is the extender then - * the LAs of the extender and the slot zero will - * match. Otherwise the slotzero card was found - * by opening up the window in the extender - * and the slot zeros extender will be the - * current extender. - */ - if(pvxisz->pvxie == pvxie || pvxisz->la == pvxie->la){ - for(slot=0;slotnode.next; - } -} - - -/* - * vxi_assign_dc_addresses() - */ -LOCAL EPVXISTAT vxi_assign_dc_addresses( -VXIE *pvxie, -struct vxi_csr *pcsr, -int prealloc, -unsigned *pOffset, -VXISZ *pvxisz, -int slot -) -{ - unsigned offset; - unsigned count; - EPVXISTAT status; - int16_t id; - - status = vxMemProbe( - (char *)pcsr, - READ, - sizeof(id), - (char *)&id); - if(status<0){ - return S_epvxi_noDevice; - } - - count = slot_la_count(pcsr); - - if(prealloc){ - offset = *pOffset; - } - else{ - status = vxi_alloc_la( - pvxie, - count, - &offset); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI: %d DC VXI device(s) do(es) not fit", - count); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI: DC VXI device(s) at slot %d in extender LA=0X%X ignored", - slot, - pvxie->la); - return S_epvxi_noMemory; - } - } - - /* - * blocked addr devices recv their - * addr assignements in unison - */ - pcsr->dir.w.addr = offset; - - while(count){ - count--; - status = open_vxi_device( - pvxie, - offset); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: DC dev assign to LA=0X%X failed", - offset); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: Slot Zero LA=0X%X", - pvxisz->la); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: DC VXI device ignored"); - } - offset++; - } - - if(prealloc){ - *pOffset = offset; - } - - return status; -} - - -/* - * - * - * VXI_COUNT_DC_DEVICES - * - */ -LOCAL EPVXISTAT vxi_count_dc_devices( -VXIE *pvxie, -unsigned *pCount -) -{ - int16_t id; - EPVXISTAT status; - struct vxi_csr *pcsr; - VXISZ *pvxisz; - int slot; - unsigned nDC; - - /* - * dont count DC devices if SC device at address 0xff - */ - if(epvxiLibDeviceList[VXIDYNAMICADDR]){ - status = S_epvxi_badConfig; - errMessage(status, "SC device at DC address"); - return status; - } - - pcsr = VXIBASE(VXIDYNAMICADDR); - status = vxMemProbe( (char *)pcsr, - READ, - sizeof(id), - (char *)&id); - if(status == OK){ - status = S_epvxi_badConfig; - errMessage(status, "SC device at DC address"); - return status; - } - - /* - * find all dynamic modules - */ - nDC=0; - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - /* - * We wish to selectively configure DC devices - * accessed through the current extender. - * - * If the slot zero card is the extender then - * the LAs of the extender and the slot zero will - * match. Otherwise the slotzero card was found - * by opening up the window in the extender - * and the slot zeros extender will be the - * current extender. - * - * Counts multiple blocked addr device per slot here. - * Does not try to count multiple independently - * addressed devices per slot here. Space is - * allocated for these DC devices on demand due to - * difficulties counting them ahead of time. - */ - if(pvxisz->pvxie == pvxie || - pvxisz->la == pvxie->la){ - - for(slot=0; slot=0){ - nDC += slot_la_count(pcsr); - } - } - CLRMODID(pvxisz); - } - - pvxisz = (VXISZ *) pvxisz->node.next; - } - *pCount = nDC; - return VXI_SUCCESS; -} - - -/* - * - * slot_la_count() - * - */ -LOCAL unsigned slot_la_count(struct vxi_csr *pcsr) -{ - unsigned blockedAddrCount; - - /* - * Rule F.2.6 - */ - blockedAddrCount = VXINDCDEVICES(pcsr); - if(blockedAddrCount==0 || blockedAddrCount==0xff){ - blockedAddrCount = 1; - } - return blockedAddrCount; -} - - -/* - * - * open slot 0 device - * - * - */ -LOCAL void open_slot0_device( -VXIE *pvxie, -unsigned la -) -{ - struct vxi_csr *pcsr; - EPVXISTAT status; - VXISZ *pvxisz; - - pcsr = VXIBASE(la); - - /* - * MXI's are device class extended - */ - if(VXICLASS(pcsr) != VXI_REGISTER_DEVICE){ - if(!VXIMXI(pcsr)){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, -"Only register based slot 0 devices currently supported LA=0x%X", - la); - return; - } - } - - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - if(pvxisz->pcsr == pcsr){ - return; - } - pvxisz = (VXISZ *) pvxisz->node.next; - } - - pvxisz = (VXISZ *) calloc(1, sizeof(*pvxisz)); - if(!pvxisz){ - errMessage( - S_epvxi_noMemory, - "continuing..."); - return; - } - pvxisz->reg = TRUE; - pvxisz->pcsr = pcsr; - pvxisz->set_modid = set_reg_modid; - pvxisz->clear_modid = clr_all_reg_modid; - pvxisz->pvxie = pvxie; - pvxisz->la = la; - - ellAdd(&crateList, &pvxisz->node); - - /* - * force the slot zero device into a known state - */ - CLRMODID(pvxisz); - - if(!epvxiLibDeviceList[la]){ - status = open_vxi_device(pvxie, la); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "attempted slot zero device open la=0X%X", - la); - return; - } - } -} - - - - - -/* - * - * NICPU030_INIT() - * check to see if this code is running on a - * national instruments cpu030 installed in - * slot zero. - * - */ -#ifdef NICPU030 -LOCAL EPVXISTAT nicpu030_init( -VXIE *pvxie -) -{ - int i; - EPVXISTAT status = S_epvxi_internal; - int16_t model; - UINT8 type; - UINT8 la; - - /* - * If we are running this code on the NI 030 - * we are the resource manager and the NI 030 will - * be the first slot zero card found. - */ - if(niCpu030Initialized){ - return VXI_SUCCESS; - } - - for(i=0; inicpu030 = TRUE; - pvxisz->set_modid = nivxi_cpu030_set_modid; - pvxisz->clear_modid = nivxi_cpu030_clr_all_modid; - pvxisz->la = la; - pvxisz->pvxie = pvxie; - - ellAdd(&crateList, &pvxisz->node); - } - return VXI_SUCCESS; -} -#endif - - - -/* - * - * vxi_alloc_la() - * - */ -LOCAL EPVXISTAT vxi_alloc_la( -VXIE *pvxie, -unsigned count, -unsigned *poffset -) -{ - EPVXISTAT status; - unsigned hla; - VXIDI *pvxidi; - unsigned peak = 0; - unsigned la; - - if(count<1){ - status = S_epvxi_internal; - errMessage(status,NULL); - return status; - } - - /* - * look inside the range thats mapped first - */ - if(pvxie->la_mapped){ - for(la=pvxie->la_low; la<=last_la; la++){ - - pvxidi = epvxiLibDeviceList[la]; - - /* - * skip all devices seen before - */ - if(pvxidi){ - /* - * LA window cant cross extender boundaries - * so just quit - */ - if(pvxidi->pvxie != pvxie){ - break; - } - peak= 0; - continue; - } - - if(vxi_la_occupied(la)){ - peak= 0; - continue; - } - - peak++; - - if(peak >= count){ - *poffset = ((int)la)-(count-1); - return VXI_SUCCESS; - } - } - - hla = pvxie->la_low; - } - else{ - hla = last_la; - } - - /* - * unachored DC device allocations go from high - * to low so that we avoid mc680xx reserved - * interrupt vectors - * - * stop before unsigned la=0 is decremented - * (shouldnt allocate the resource manager's LA anyways) - */ - peak=0; - for(la=hla; la>=max(VXI_RESMAN_LA+1,first_la); la--){ - - pvxidi = epvxiLibDeviceList[la]; - - /* - * skip all devices seen before - */ - if(pvxidi){ - /* - * LA window cant cross extender boundaries - * (if something is mapped already) so just quit - */ - if(pvxie->la_mapped){ - if(pvxidi->pvxie != pvxie){ - break; - } - } - - peak= 0; - continue; - } - - if(vxi_la_occupied(la)){ - peak= 0; - continue; - } - - peak++; - - if(peak >= count){ - *poffset = la; - return VXI_SUCCESS; - } - } - - return S_epvxi_internal; -} - - -/* - * - * vxi_la_occupied() - * - */ -LOCAL EPVXISTAT vxi_la_occupied(unsigned la) -{ - struct vxi_csr *pcsr; - int16_t *pi16; - int16_t i16; - EPVXISTAT s; - - /* - * dont allocate the resource manager's LA - */ - if(la == VXI_RESMAN_LA){ - return TRUE; - } - - /* - * Check to see if this LA belongs to - * the NI 030 CPU (that does not show - * in A16 when it is a VME BM) - */ - if(niCpu030Initialized){ - if(la == (*pnivxi_func[(unsigned)e_GetMyLA])()){ - return TRUE; - } - } - - /* - * Probe the entire LA space - */ - pcsr = VXIBASE(la); - for( pi16 = (int16_t *) &pcsr->dir.r.make; - pi16 <= (int16_t *) &pcsr->dir.r.dd.reg.ddx2e; - pi16++){ - - s = vxMemProbe( (char *)pi16, - READ, - sizeof(i16), - (char *)&i16); - if(s == OK){ - return TRUE; - } - } - - /* - * dont allow vxi int vec to overlap - * VME vectors in use - */ - if(vxi_vec_inuse(la)){ - return TRUE; - } - - return FALSE; -} - - - -/* - * - * VXI_FIND_SLOT - * given a VXI module's addr find its slot - * - */ -LOCAL EPVXISTAT vxi_find_slot( -struct vxi_csr *pcsr, -unsigned *pslot, -VXISZ **ppvxisz -) -{ - VXISZ *pvxisz; - EPVXISTAT status; - unsigned char slot; - - status = S_epvxi_slotNotFound; - - /* - * RULE C.2.7 - */ - if(VXIMODIDSTATUS(pcsr->dir.r.status)){ - errMessage(status, "device's MODID status is active & no MODID?"); - return status; - } - - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - - /* - * if it is a slot zero card - * then dont bother searching - */ - if(pvxisz->pcsr == pcsr){ - *pslot = 0; - *ppvxisz = pvxisz; - status = VXI_SUCCESS; - break; - } - - for(slot=0;slotdir.r.status)){ - *pslot = slot; - *ppvxisz = pvxisz; - status = VXI_SUCCESS; - break; - } - } - CLRMODID(pvxisz); - - if(status == VXI_SUCCESS) - break; - - pvxisz = (VXISZ *) pvxisz->node.next; - } - - return status; -} - - -/* - * - * VXI_RESET_DC - * force all dynamic devices back to address 0xff - * (In case this is a ctrl X restart) - * - * not tested with at5vxi modules - */ -#ifdef JUNKYARD -LOCAL EPVXISTAT vxi_reset_dc(void) -{ - register unsigned addr; - unsigned slot; - unsigned crate; - int16_t id; - EPVXISTAT status; - struct vxi_csr_w *pcr; - struct vxi_csr_r *psr; - - for(addr=first_la; addr<=last_la; addr++){ - - psr = (struct vxi_csr_r *) VXIBASE(addr); - pcr = (struct vxi_csr_w *) psr; - - status = vxMemProbe( psr, - READ, - sizeof(id), - &id); - if(status == ERROR) - continue; - - status = vxi_find_slot(psr, &slot, &crate); - if(status){ - return status; - } - - SETMODID(slot, crate); - - - pcr->addr = VXIDYNAMICADDR; - } - - return VXI_SUCCESS; -} -#endif - - -/* - * - * VXI_DC_TEST - * determine if a VXI module in the static address range is dynamic - * - */ -#ifdef JUNKYARD -LOCAL EPVXISTAT vxi_dc_test( -unsigned current_addr -) -{ - register unsigned addr; - unsigned slot; - unsigned crate; - int16_t id; - EPVXISTAT status; - struct vxi_csr_w *pcr; - struct vxi_csr_r *psr; - - static unsigned open_addr; - unsigned dynamic; - - for(addr=first_la; addr<=last_la; addr++){ - - status = vxMemProbe( VXIBASE(addr), - READ, - sizeof(id), - &id); - if(status == ERROR){ - open_addr = addr; - break; - } - } - - psr = (struct vxi_csr_r *) VXIBASE(current_addr); - pcr = (struct vxi_csr_w *) psr; - - status = vxi_find_slot(psr, &slot, &crate); - if(status){ - errMessage(status,NULL); - return status; - } - - SETMODID(slot, crate); - pcr->addr = open_addr; - - psr = (struct vxi_csr_r *) VXIBASE(open_addr); - pcr = (struct vxi_csr_w *) psr; - - status = vxMemProbe( psr, - READ, - sizeof(id), - &id); - - if(status==OK){ - dynamic = TRUE; - pcr->addr = current_addr; - } - else - dynamic = FALSE; - - status = vxMemProbe( VXIBASE(current_addr), - READ, - sizeof(id), - &id); - if(status == ERROR) - return S_epvxi_internal; - - - return dynamic; -} -#endif - - -/* - * - * VXI_CONFIGURE_HIERARCHIES - * - */ -LOCAL void vxi_configure_hierarchies( -unsigned commander_la, -unsigned servant_area -) -{ - EPVXISTAT status; - struct vxi_csr *pcsr; - unsigned long response; - VXIDI **ppvxidi; - VXIDI *pvxidi; - unsigned sla; - unsigned last_sla; - unsigned area; - - last_sla = servant_area+commander_la; - - if(last_sla >= NELEMENTS(epvxiLibDeviceList)){ - errPrintf( - S_epvxi_internal, - __FILE__, - __LINE__, - "VXI resman: Clipping servant area (LA=0x%X)", - commander_la); - last_sla = NELEMENTS(epvxiLibDeviceList)-1; - } - - sla = commander_la+1; - ppvxidi = &epvxiLibDeviceList[sla]; - for( ; - sla<=last_sla; - sla += area+1, ppvxidi += area+1){ - - pvxidi = *ppvxidi; - area = 0; - - if(!pvxidi){ - continue; - } - - pvxidi->commander_la = commander_la; - - if(!pvxidi->st_passed){ - continue; - } - - pcsr = VXIBASE(sla); - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - if(commander_la != VXI_RESMAN_LA){ - status = epvxiCmdQuery( - commander_la, - (unsigned long)MBC_GRANT_DEVICE | sla, - &response); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: GD failed (LA=0x%X)", - sla); - } - else{ - printf( - "VXI resman: gd resp %x\n", - response); - } - } - if(VXICMDR(pcsr)){ - status = epvxiCmdQuery( - sla, - (unsigned long)MBC_READ_SERVANT_AREA, - &response); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: RSA failed (LA=0x%X)", - sla); - } - else{ - area = response & MBR_READ_SERVANT_AREA_MASK; - - printf( "The servant area was %d (LA=0x%X)\n", - area, - sla); - - vxi_configure_hierarchies( - sla, - area); - } - } - } -} - - -/* - * - * VXI_BEGIN_NORMAL_OPERATION - * - */ -LOCAL void vxi_begin_normal_operation(void) -{ - EPVXISTAT status; - unsigned la; - VXIDI **ppvxidi; - VXIDI *pvxidi; - struct vxi_csr *pcsr; - - for( la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - unsigned cmdr; - unsigned long cmd; - unsigned long resp; - - pvxidi = *ppvxidi; - - if(!pvxidi){ - continue; - } - - pcsr = VXIBASE(la); - - if(!pvxidi->st_passed){ - continue; - } - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - cmdr = VXICMDR(pcsr); - - cmd = MBC_BEGIN_NORMAL_OPERATION; -/* - * this will send the begin nml op command to servants which - * have a commander - * - * more work needs to be done here if this situation occurs - * see below - */ - if(cmdr){ - cmd |= MBC_TOP_LEVEL_CMDR; - } - status = epvxiCmdQuery(la, cmd, &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: Device rejected BEGIN_NORMAL_OPERATION LA=0x%X (reason=%d)", - la, - status); - } - else if( - MBR_STATUS(resp)!=MBR_STATUS_SUCCESS || - MBR_BNO_STATE(resp)!=MBR_BNO_STATE_NO){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "VXI resman: Device rejected BEGIN_NORMAL_OPERATION LA=0x%X (status=%x) (state=%x)", - la, - MBR_STATUS(resp), - MBR_BNO_STATE(resp)); - } - else{ - pvxidi->msg_dev_online = TRUE; - } - - /* - * Dont send begin normal operation cmd - * to servants who have a commander - */ -/* - * apparently this is not a good enough test - * for CMDR since some devices are rejecting this cmd - */ -#if 0 - if(cmdr){ - unsigned long sa=0; - - printf("Found a msg based cmdr\n"); - - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_SERVANT_AREA, - &sa); - if(status){ - errMessage( - status, - "vxi resman: rsa failed"); - } - else{ - sa = sa & MBR_READ_SERVANT_AREA_MASK; - printf( - "The servant area was %d\n", - sa); - la += sa; - } - } -#endif - } -} - - -/* - * - * VXI_SELF_TEST - * check self test bits and place in safe state if failed - * print message about failed devices - * - */ -LOCAL EPVXISTAT vxi_self_test(void) -{ - unsigned la; - uint16_t wd; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - - - for( la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - if(!*ppvxidi){ - continue; - } - - pcsr = VXIBASE(la); - - wd = pcsr->dir.r.status; - - if(VXIPASSEDSTATUS(wd)){ - (*ppvxidi)->st_passed = TRUE; - } - else{ - errMessage( - S_epvxi_selfTestFailed, - "VXI resman: device self test failed"); - epvxiSetDeviceOffline(la); - } - } - - return VXI_SUCCESS; -} - - -/* - * - * - * epvxiSetDeviceOffline() - * - */ -LOCAL EPVXISTAT epvxiSetDeviceOffline( -unsigned la -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "WARNING: VXI device placed off line %c(LA=0x%X)", - BELL, - la); - - pcsr->dir.w.control = VXISAFECONTROL; - - return VXI_SUCCESS; -} - - -/* - * - * VXI_ADDRESS_CONFIG - * - */ -LOCAL void vxi_address_config(void) -{ - char *pBase; - EPVXISTAT status; - - /* - * fetch the EPICS address ranges from the global - * symbol table if they are available - */ - status = symbol_value_fetch( - "_EPICS_VXI_A24_BASE", - &root_extender.A24_base, - sizeof(root_extender.A24_base)); - if(status){ - root_extender.A24_base = DEFAULT_VXI_A24_BASE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A24_SIZE", - &root_extender.A24_size, - sizeof(root_extender.A24_size)); - if(status){ - root_extender.A24_size = DEFAULT_VXI_A24_SIZE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A32_BASE", - &root_extender.A32_base, - sizeof(root_extender.A32_base)); - if(status){ - root_extender.A32_base = DEFAULT_VXI_A32_BASE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A32_SIZE", - &root_extender.A32_size, - sizeof(root_extender.A32_size)); - if(status){ - root_extender.A32_size = DEFAULT_VXI_A32_SIZE; - } - - /* - * find A24 and A32 on this processor - */ - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - (char *)root_extender.A24_base, - &pBase); - if(status == OK){ - root_extender.A24_base = (long) pBase; - root_extender.A24_ok = TRUE; - } - else{ - root_extender.A24_ok = FALSE; - errMessage( - S_epvxi_badConfig, - "A24 VXI Base Addr problems"); - } - status = sysBusToLocalAdrs( - VME_AM_EXT_SUP_DATA, - (char *)root_extender.A32_base, - &pBase); - if(status == OK){ - root_extender.A32_base = (long) pBase; - root_extender.A32_ok = TRUE; - } - else{ - root_extender.A32_ok = FALSE; - errMessage( - S_epvxi_badConfig, - "A32 VXI Base Addr problems"); - } - - vxi_allocate_address_block(&root_extender); -} - - -/* - * - * VXI_ALLOCATE_ADDRESS_BLOCK - * - */ -LOCAL void vxi_allocate_address_block( -VXIE *pvxie -) -{ - unsigned la; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - VXIE *psubvxie; - unsigned long A24_base; - unsigned long A24_size; - unsigned long A32_base; - unsigned long A32_size; - - if(!pvxie->la_mapped){ - return; - } - - switch(pvxie->type){ - case ext_export_vxi_onto_mxi: - case ext_import_mxi_into_vxi: - pvxie->A24_base = MXIA24ALIGN(pvxie->A24_base); - pvxie->A32_base = MXIA32ALIGN(pvxie->A32_base); - pvxie->A24_size &= ~MXIA24MASK; - pvxie->A32_size &= ~MXIA32MASK; - break; - case ext_local_cpu: - default: - break; - } - - A24_base = pvxie->A24_base; - A24_size = pvxie->A24_size; - A32_base = pvxie->A32_base; - A32_size = pvxie->A32_size; - - psubvxie = (VXIE *) &pvxie->extenders.node; - while(psubvxie = (VXIE *) ellNext((ELLNODE *)psubvxie)){ - - psubvxie->A24_base = A24_base; - psubvxie->A24_size = A24_size; - psubvxie->A32_base = A32_base; - psubvxie->A32_size = A32_size; - psubvxie->A24_ok = pvxie->A24_ok; - psubvxie->A32_ok = pvxie->A32_ok; - - vxi_allocate_address_block(psubvxie); - - if(psubvxie->A24_mapped){ - A24_base = psubvxie->A24_base + psubvxie->A24_size; - A24_size -= psubvxie->A24_size; - pvxie->A24_mapped = TRUE; - } - - if(psubvxie->A32_mapped){ - A32_base = psubvxie->A32_base + psubvxie->A32_size; - A32_size -= psubvxie->A32_size; - pvxie->A32_mapped = TRUE; - } - } - - for( la=pvxie->la_low, ppvxidi = &epvxiLibDeviceList[la]; - ppvxidi <= &epvxiLibDeviceList[pvxie->la_high]; - ppvxidi++, la++){ - - unsigned long m; - unsigned long size; - unsigned long mask; - - if(!*ppvxidi){ - continue; - } - - /* - * dont configure devices lower in the hierarchy - */ - if((*ppvxidi)->A24_mapped || (*ppvxidi)->A32_mapped){ - continue; - } - - pcsr = VXIBASE(la); - - m = VXIREQMEM(pcsr); - - switch(VXIADDRSPACE(pcsr)){ - case VXI_ADDR_EXT_A24: - if(!pvxie->A24_ok){ - break; - } - - /* - * perform any needed alignment - */ - size = VXIA24MEMSIZE(m); - if(size>A24_size){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI A24 device does not fit Request=%d Avail=%d LA=0X%X", - size, - A24_size, - la); - epvxiSetDeviceOffline(la); - break; - } - mask = size-1; - A24_base = ((A24_base)+mask)&(~mask); - pcsr->dir.w.offset = A24_base>>8; - pcsr->dir.w.control = VXIMEMENBLCONTROL; - (*ppvxidi)->pFatAddrBase = (void *) A24_base; - (*ppvxidi)->A24_mapped = TRUE; - pvxie->A24_mapped = TRUE; - A24_base += size; - A24_size -= size; - break; - - case VXI_ADDR_EXT_A32: - if(!pvxie->A32_ok){ - break; - } - - /* - * perform any needed alignment - */ - size = VXIA32MEMSIZE(m); - if(size>A32_size){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI A32 device does not fit Request=%d Avail=%d LA=0X%X", - size, - A32_size, - la); - epvxiSetDeviceOffline(la); - break; - } - mask = size-1; - A32_base = (A32_base+mask)&(~mask); - pcsr->dir.w.offset = A32_base>>16; - pcsr->dir.w.control = VXIMEMENBLCONTROL; - (*ppvxidi)->pFatAddrBase = (void *) A32_base; - (*ppvxidi)->A32_mapped = TRUE; - pvxie->A32_mapped = TRUE; - A32_base += size; - A32_size -= size; - break; - - default: - /* - * do nothing - */ - break; - } - } - - pcsr = VXIBASE(pvxie->la); - - if(pvxie->A24_mapped){ - pvxie->A24_size = pvxie->A24_size - A24_size; - pvxie->A24_size = MXIA24ALIGN(pvxie->A24_size); - } - - if(pvxie->A32_mapped){ - pvxie->A32_size = pvxie->A32_size - A32_size; - pvxie->A32_size = MXIA32ALIGN(pvxie->A32_size); - } - - switch(pvxie->type){ - case ext_export_vxi_onto_mxi: - if(pvxie->A24_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a24_window_high = - (pvxie->A24_base+pvxie->A24_size) - >> MXIA24MASKSIZE; - pcsr->dir.w.dd.mxi.a24_window_low = - pvxie->A24_base - >> MXIA24MASKSIZE; - } - if(pvxie->A32_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a32_window_high = - (pvxie->A32_base+pvxie->A32_size) - >> MXIA32MASKSIZE; - pcsr->dir.w.dd.mxi.a32_window_low = - pvxie->A32_base - >> MXIA32MASKSIZE; - } - break; - - case ext_import_mxi_into_vxi: - if(pvxie->A24_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a24_window_high = - pvxie->A24_base - >> MXIA24MASKSIZE; - pcsr->dir.w.dd.mxi.a24_window_low = - (pvxie->A24_base+pvxie->A24_size) - >> MXIA24MASKSIZE; - } - if(pvxie->A32_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a32_window_high = - pvxie->A32_base - >> MXIA32MASKSIZE; - pcsr->dir.w.dd.mxi.a32_window_low = - (pvxie->A32_base+pvxie->A32_size) - >> MXIA32MASKSIZE; - } - break; - - case ext_local_cpu: - default: - break; - } -} - - -/* - * - * symbol_value_fetch - * - */ -LOCAL EPVXISTAT symbol_value_fetch( -char *pname, -void *pdest, -unsigned dest_size -) -{ - EPVXISTAT status; - UINT8 type; - char *pvalue; - - status = symFindByName( - sysSymTbl, - pname, - &pvalue, - &type); - if(status == OK){ - bcopy(pvalue, pdest, dest_size); - return VXI_SUCCESS; - } - else{ - return S_epvxi_internal; - } -} - - -/* - * - * VXI_INIT_IGNORE_LIST - * init list of interrupt handlers to ignore - * - */ -LOCAL EPVXISTAT vxi_init_ignore_list(void) -{ - int i; - UINT8 type; - EPVXISTAT status; - - for(i=0; ireg)){ - errMessage( - S_epvxi_internal, - "bad crate for set_reg_modid"); - return; - } - VXI_SET_REG_MODID(pvxisz->pcsr, slot); -} - -/* - * - * CLR_ALL_REG_MODID - * - */ -LOCAL void clr_all_reg_modid( -VXISZ *pvxisz -) -{ - if(!(pvxisz->reg)){ - errMessage( - S_epvxi_internal, - "bad crate for clr_all_reg_modid"); - return; - } - VXI_CLR_ALL_REG_MODID(pvxisz->pcsr); -} - - - -/* - * - * NIVXI_CPU030_SET_MODID - * - */ -#ifdef NICPU030 -LOCAL void nivxi_cpu030_set_modid( -VXISZ *pvxisz, -unsigned slot -) -{ - EPVXISTAT status; - - if(niCpu030Initialized){ - status = (*pnivxi_func[(unsigned)e_SetMODID])(TRUE,1<slot, - pmxidi->pvxisz->la, - pmxidi->class); - printf("\t"); - if(pmxidi->pvxieSelf){ - printf("extender, "); - } - if(pmxidi->msg_dev_online){ - printf("msg online, "); - } - printf("driver ID %d, ", pmxidi->driverID); - if(taskIdVerify(pmxidi->taskID)>=0){ - printf( "opened by task %s, ", - taskName(pmxidi->taskID)); - } - printf("cmdr la=0x%X, ", pmxidi->commander_la); - printf("extdr la=0x%X, ", pmxidi->extender_la); - printf("slot-zero la=0x%X, ", pmxidi->slot_zero_la); - printf("make 0X%X, ", (unsigned) pmxidi->make); - printf("model 0x%X, ", pmxidi->model); - printf( "pio_report_func %x, ", - (unsigned) pmxidi->pio_report_func); - printf("\n"); - } - i++; - ppmxidi++; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiCrateList() - * - */ -EPVXISTAT epvxiCrateList(void) -{ - VXISZ *pvxisz; - - printf("VXI crate list\n"); - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - - printf("LA=0X%X", pvxisz->la); - printf( ", extender LA=0X%X", - pvxisz->pvxie->la); - if(pvxisz->reg){ - printf(", register device"); - } - if(pvxisz->msg){ - printf(", message device"); - } - if(pvxisz->nicpu030){ - printf(", NI030"); - } - printf("\n"); - pvxisz = (VXISZ *) pvxisz->node.next; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiUniqueDriverID() - * - * return a non zero unique id for a VXI driver - */ -long epvxiUniqueDriverID(void) -{ - if(epvxiNextDriverIDdriverID == vxiDriverID){ - return S_epvxi_deviceOpen; - } - else if(pvxidi->driverID != NO_DRIVER_ATTACHED_ID){ - return S_epvxi_notOwner; - } - - if(driverConfigSize){ - pconfig = (void *)calloc(1,driverConfigSize); - if(!pconfig){ - return S_epvxi_noMemory; - } - pvxidi->pDriverConfig = pconfig; - } - else{ - pvxidi->pDriverConfig = NULL; - } - - pvxidi->pio_report_func = pio_report_func; - - pvxidi->taskID = taskIdSelf(); - pvxidi->driverID = vxiDriverID; - - return VXI_SUCCESS; -} - - -/* - * - * epvxiDeviceVerify() - * - * - */ -EPVXISTAT epvxiDeviceVerify(unsigned la) -{ - EPVXISTAT status; - VXICSR *pcsr; - VXIDI *pvxidi; - uint16_t device_status; - - if(la > NELEMENTS(epvxiLibDeviceList)){ - return S_epvxi_badLA; - } - - pvxidi = epvxiLibDeviceList[la]; - if(!pvxidi){ - return S_epvxi_uknDevice; - } - - /* - * verify that the device exists - * and check the self test in memory - * since this may run before - * the self tests are verified. - */ - pcsr = VXIBASE(la); - status = vxMemProbe( (char *)&pcsr->dir.r.status, - READ, - sizeof(pcsr->dir.r.status), - (char *)&device_status); - if(status != OK){ - return S_epvxi_uknDevice; - } - if(!VXIPASSEDSTATUS(device_status)){ - return S_epvxi_selfTestFailed; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiClose() - * - * 1) Unregister a driver's ownership of a device - * 2) Free driver's configuration block if one is allocated - */ -EPVXISTAT epvxiClose( -unsigned la, -int vxiDriverID -) -{ - VXIDI *pvxidi; - - if(la > NELEMENTS(epvxiLibDeviceList)){ - return S_epvxi_badLA; - } - - pvxidi = epvxiLibDeviceList[la]; - - if(pvxidi){ - if(pvxidi->driverID == vxiDriverID){ - pvxidi->driverID = NO_DRIVER_ATTACHED_ID; - if(pvxidi->pDriverConfig){ - free(pvxidi->pDriverConfig); - pvxidi->pDriverConfig = NULL; - } - return VXI_SUCCESS; - } - return S_epvxi_notOwner; - } - - return S_epvxi_notOwner; -} - - -/* - * - * epvxiLookupLA() - * - */ -EPVXISTAT epvxiLookupLA( -epvxiDeviceSearchPattern *pdsp, -void (*pfunc)(), -void *parg -) -{ - VXIDI *plac; - unsigned i; - - for(i=first_la; i<=last_la; i++){ - long flags; - - flags = pdsp->flags; - plac = epvxiLibDeviceList[i]; - - /* - * skip devices not present - */ - if(!plac){ - continue; - } - - if(flags & VXI_DSP_make){ - if(plac->make != pdsp->make){ - continue; - } - } - - if(flags & VXI_DSP_model){ - if(plac->model != pdsp->model){ - continue; - } - } - - if(flags & VXI_DSP_class){ - if(plac->class != pdsp->class){ - continue; - } - } - - if(flags & VXI_DSP_slot){ - if(plac->slot != pdsp->slot){ - continue; - } - } - - if(flags & VXI_DSP_slot_zero_la){ - if(plac->slot_zero_la != pdsp->slot_zero_la){ - continue; - } - } - - if(flags & VXI_DSP_commander_la){ - if(plac->commander_la != pdsp->commander_la){ - continue; - } - } - - if(flags & VXI_DSP_extender_la){ - if(plac->extender_la != pdsp->extender_la){ - continue; - } - } - - (*pfunc)(i, parg); - - } - - return VXI_SUCCESS; -} - - -/* - * epvxiRouteTriggerECL() - */ -EPVXISTAT epvxiRouteTriggerECL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - VXIDI *plac; - struct vxi_csr *pcsr; - char mask; - EPVXISTAT status; - int i; - - mask = (1<> 1, - io_map = io_map >> 1, - i++){ - - int (*pfunc)(); - int src; - int dest; - - if(!(enable_map&1)){ - continue; - } - - if(io_map&1){ - src = TRIG_LINE_FPOUT; - dest = TRIG_LINE_ECL_BASE + i; - } - else{ - src = TRIG_LINE_FPIN; - dest = TRIG_LINE_ECL_BASE + i; - } - - pfunc = pnivxi_func[(unsigned)e_MapTrigToTrig]; - status = (*pfunc)( - la, - src, - dest, - 0); - if(status < 0){ - status = S_epvxi_badTrigIO; - errPrintf( - status, - __FILE__, - __LINE__, - "NI CPU030 ECL trig map fail LA=0X%X", - la); - return status; - } - - } - return VXI_SUCCESS; - } - } - - plac = epvxiLibDeviceList[la]; - if(plac){ - if(!plac->st_passed){ - return S_epvxi_selfTestFailed; - } - } - else{ - return S_epvxi_noDevice; - } - - pcsr = VXIBASE(la); - - if(VXIMXI(pcsr)){ - int ctrl = MXI_CONTROL_CONSTANT; - - if(enable_map & (1<<0)){ - ctrl |= MXI_ECL0_ENABLE; - } - if(io_map & (1<<0)){ - ctrl |= MXI_ECL0_BP_TO_FP; - } - else{ - ctrl |= MXI_ECL0_FP_TO_BP; - } - - - if(enable_map & (1<<1)){ - ctrl |= MXI_ECL1_ENABLE; - } - if(io_map & (1<<1)){ - ctrl |= MXI_ECL1_BP_TO_FP; - } - else{ - ctrl |= MXI_ECL1_FP_TO_BP; - } - - pcsr->dir.w.dd.mxi.control = ctrl; - - return VXI_SUCCESS; - } - - /* - * HP MODEL E1404 trigger routing - */ - if(VXIMAKE(pcsr)==VXI_MAKE_HP){ - if( VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG || - VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG_SLOT0){ - return hpE1404RouteTriggerECL( - la, - enable_map, - io_map); - } - } - - status = S_epvxi_uknDevice; - errPrintf( - status, - __FILE__, - __LINE__, - "failed to map ECL trigger for (la=0x%X)", - la); - return status; -} - - -/* - * epvxiRouteTriggerTTL() - * - */ -EPVXISTAT epvxiRouteTriggerTTL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - VXIDI *plac; - struct vxi_csr *pcsr; - unsigned mask; - EPVXISTAT status; - int i; - - mask = (1<> 1, - io_map = io_map >> 1, - i++){ - - int (*pfunc)(); - int src; - int dest; - - if(!(enable_map&1)){ - continue; - } - - if(io_map&1){ - src = TRIG_LINE_FPOUT; - dest = TRIG_LINE_TTL_BASE + i; - } - else{ - src = TRIG_LINE_FPIN; - dest = TRIG_LINE_TTL_BASE + i; - } - - pfunc = pnivxi_func[(unsigned)e_MapTrigToTrig]; - status = (*pfunc)( - la, - src, - dest, - 0); - if(status < 0){ - status = S_epvxi_badTrigIO; - errPrintf( - status, - __FILE__, - __LINE__, - "NI030 TTL trig map fail LA=0X%X", - la); - return status; - } - - } - return VXI_SUCCESS; - } - } - - plac = epvxiLibDeviceList[la]; - if(plac){ - if(!plac->st_passed){ - return S_epvxi_selfTestFailed; - } - } - else{ - return S_epvxi_noDevice; - } - - - pcsr = VXIBASE(la); - - if(VXIMXI(pcsr)){ - int16_t tmp; - - tmp = ~io_map & enable_map; - tmp = (enable_map<<8) | tmp; - pcsr->dir.w.dd.mxi.trigger_config = tmp; - - return VXI_SUCCESS; - } - - /* - * HP MODEL E1404 trigger routing - */ - if(VXIMAKE(pcsr)==VXI_MAKE_HP){ - if( VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG || - VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG_SLOT0){ - return hpE1404RouteTriggerTTL( - la, - enable_map, - io_map); - } - } - - status = S_epvxi_uknDevice; - errPrintf( - status, - __FILE__, - __LINE__, - "Failed to map TTL trigger for (LA=%x%X)", - la); - return status; -} - - -/* - * vxi_io_report() - */ -EPVXISTAT vxi_io_report( -unsigned level -) -{ - return epvxiIOReport(level); -} - - -/* - * - * epvxiIOReport - * - * call io report routines for all registered devices - * - */ -EPVXISTAT epvxiIOReport( -unsigned level -) -{ - unsigned la; - unsigned resmanLA; - EPVXISTAT status; - - /* Get local address from VME address. */ - /* in case the resource manager has not been called */ - if(!epvxi_local_base){ - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - (char *)VXIBASEADDR, - (char **)&epvxi_local_base); - if(status != OK){ - status = S_epvxi_badConfig; - errMessage( - status, - "A16 base map failed"); - return status; - } - } - - /* - * special support for the niCPU030 - * since it does not see itself - */ - nicpu030_init(&root_extender); - - if(niCpu030Initialized){ - if(pnivxi_func[(unsigned)e_GetMyLA]){ - resmanLA = (*pnivxi_func[(unsigned)e_GetMyLA])(); - printf("VXI LA 0x%02X ", resmanLA); - } - } - else{ - printf("VXI LA "); - } - - printf("%s resident resource manager\n", - sysModel()); - - for(la=first_la; la<=last_la; la++){ - report_one_device(la, level); - } - - return VXI_SUCCESS; -} - - -/* - * - * report_one_device() - * - */ -LOCAL EPVXISTAT report_one_device( -unsigned la, -int level -) -{ - VXIDI *plac; - VXISZ *pvxisz; - unsigned slot; - EPVXISTAT status; - int make; - int model; - struct vxi_csr *pcsr; - int16_t id; - - pcsr = VXIBASE(la); - status = vxMemProbe( (char *)pcsr, - READ, - sizeof(id), - (char *)&id); - if(status != OK){ - return S_epvxi_internal; - } - - status = vxi_find_slot(pcsr, &slot, &pvxisz); - if(status){ - pvxisz = NULL; - slot = UKN_SLOT; - } - - - /* - * the logical address - */ - printf("VXI LA 0x%02X ", la); - - /* - * crate and slot - */ - if(pvxisz){ - printf( "slot zero LA=0X%02X slot %2d ", - pvxisz->la, - slot); - } - else{ - printf( "slot zero LA=?? slot=?? ", - UKN_LA, - UKN_LA); - } - - - /* - * make - */ - make = VXIMAKE(pcsr); - { - char buf[32]; - unsigned nactual; - - status = epuxiLookupMakeName( - make, - buf, - sizeof(buf)-1, - &nactual); - if(status==VXI_SUCCESS){ - buf[sizeof(buf)-1] = NULL; - printf("%s ", buf); - } - else{ - printf("make 0x%03X ", make); - } - } - - /* - * model - */ - model = VXIMODEL(pcsr); - { - char model_name[32]; - unsigned int nread; - - status = epuxiLookupModelName( - make, - model, - model_name, - sizeof(model_name)-1, - &nread); - if(status){ - printf( "model 0x%03X ", model); - } - else{ - model_name[sizeof(model_name)]=NULL; - printf( "%s ", model_name); - } - } - - printf("\n"); - - if(!VXIPASSEDSTATUS(pcsr->dir.r.status)){ - printf("\t---- Self Test Failed ----\n"); - return VXI_SUCCESS; - } - - /* - * call their io report routine if they supply one - */ - plac = epvxiLibDeviceList[la]; - if(plac){ - if(plac->pio_report_func){ - (*plac->pio_report_func)(la, level); - } - } - - if(level == 0){ - return VXI_SUCCESS; - } - - /* - * print out physical addresses of the cards - */ - printf("\tA16=0x%X ", (int) VXIBASE(la)); - if(VXIMEMENBL(pcsr)){ - long VMEmod = NULL; - char *VMEaddr = NULL; - char *pname = NULL; - char *pbase; - - switch(VXIADDRSPACE(pcsr)){ - case VXI_ADDR_EXT_A24: - VMEmod = VME_AM_STD_SUP_DATA; - VMEaddr = (char *) (pcsr->dir.w.offset<<8); - pname = "A24"; - break; - case VXI_ADDR_EXT_A32: - VMEmod = VME_AM_EXT_SUP_DATA; - VMEaddr = (char *) (pcsr->dir.w.offset<<16); - pname = "A32"; - break; - } - if(pname){ - status = sysBusToLocalAdrs( - VMEmod, - VMEaddr, - &pbase); - if(status>=0){ - printf( "%s=0x%X", - pname, - (unsigned)pbase); - } - else{ - printf( "failure mapping %s=%x", - pname, - (unsigned)VMEaddr); - } - } - } - printf("\n"); - - if(VXISLOT0MODEL(pcsr)){ - printf("\tSlot Zero Device\n"); - } - - printf( "\t%s device", - vxi_device_class_names[VXICLASS(pcsr)]); - switch(VXICLASS(pcsr)){ - case VXI_MEMORY_DEVICE: - break; - - case VXI_EXTENDED_DEVICE: - if(VXIMXI(pcsr)){ - mxi_io_report(pcsr, level); - } - break; - - case VXI_MESSAGE_DEVICE: - { - unsigned long resp; - - if(VXICMDR(pcsr)){ - printf(", cmdr"); - } - if(VXIFHS(pcsr)){ - printf(", fh"); - } - if(VXISHM(pcsr)){ - printf(", shm"); - } - if(VXIMBINT(pcsr)){ - printf(", interrupter"); - } - if(VXIVMEBM(pcsr)){ - printf(", VME bus master"); - } - if(VXISIGREG(pcsr)){ - printf(", has signal reg"); - } - printf("\n"); - /* - * all message based devices are required to - * implement this command query - */ - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL, - &resp); - if(status==VXI_SUCCESS){ - printf("\tprotocols("); - if(MBR_REV_12(resp)){ - printf("Rev 1.2 device, "); - } - if(MBR_RP_LW(resp)){ - printf("long word serial, "); - } - if(MBR_RP_ELW(resp)){ - printf("extended long word serial, "); - } - if(MBR_RP_I(resp)){ - printf("VXI instr, "); - } - if(MBR_RP_I4(resp)){ - printf("488 instr, "); - } - if(MBR_RP_TRG(resp)){ - printf("sft trig, "); - } - if(MBR_RP_PH(resp)){ - printf("prog int hdlr, "); - } - if(MBR_RP_PI(resp)){ - printf("prog interrupter, "); - } - if(MBR_RP_EG(resp)){ - printf("event gen, "); - } - if(MBR_RP_RG(resp)){ - printf("resp gen, "); - } - printf(")"); - } - break; - } - case VXI_REGISTER_DEVICE: - break; - - } - printf("\n"); - - return VXI_SUCCESS; -} - - -/* - * - * mxi_io_report() - * - * - */ -LOCAL void mxi_io_report( -struct vxi_csr *pmxi, -int level -) -{ - unsigned la; - unsigned ha; - unsigned a; - unsigned b; - char *msg; - - printf(", MXI sub class\n\t"); - - if(pmxi->dir.w.dd.mxi.control & MXI_UPPER_LOWER_BOUNDS){ - la = VXIADDRMASK & - pmxi->dir.w.dd.mxi.la_window; - ha = VXIADDRMASK & - (pmxi->dir.w.dd.mxi.la_window>>NVXIADDRBITS); - if(la 0 since la < ha - */ - ha--; - } - else if(la>ha){ - msg = "MXI LA's seen by this crate"; - /* - * la > 0 since la > ha - */ - la--; - } - else if(la == 0){ - msg = "LA window disabled"; - la = 0; - ha = 0; - } - else if(la >= 0x80){ - msg = "MXI LA's seen by this crate"; - la = 0; - ha = 0xff; - } - else{ - msg = "local VXI LA's seen by MXI"; - la = 0; - ha = 0xff; - } - - printf(", %s 0x%X-0x%X\n\t", - msg, - la, - ha); - - a = pmxi->dir.w.dd.mxi.a24_window_low; - b = pmxi->dir.w.dd.mxi.a24_window_high; - printf(", A24 window 0x%X-0x%X", - a, - b); - - a = pmxi->dir.w.dd.mxi.a32_window_low; - b = pmxi->dir.w.dd.mxi.a32_window_high; - printf(", A32 window 0x%X-0x%X", - a, - b); - } -# ifdef BASE_PLUS_SIZE_MXI_SUPPORT - else{ - la = VXIADDRMASK & - pmxi->dir.w.dd.mxi.la_window; - ha = la + (MXI_LA_WINDOW_SIZE_MASK & - (pmxi->dir.w.dd.mxi.la_window>>NVXIADDRBITS)); - - printf(", LA window 0x%X-0x%X", - la, - ha); - } -# endif -} - - -/* - * - * vxi_allocate_int_lines() - * - * - */ -LOCAL void vxi_allocate_int_lines(void) -{ - EPVXISTAT status; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - VXIDI *pvxidi; - unsigned la; - unsigned long resp; - unsigned long cmd; - unsigned line_count; - - for( la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - pvxidi = *ppvxidi; - - if(!pvxidi){ - continue; - } - - pcsr = VXIBASE(la); - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - /* - * find out if this is a programmable interrupter - */ - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected READ_PROTOCOL (LA=0x%X)", - la); - continue; - } - if(!MBR_RP_PI(resp)){ - continue; - } - - printf("Programming interrupter (LA=0x%X)\n", la); - - cmd = MBC_READ_INTERRUPTERS; - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected READ_INTERRUPTERS (LA=0x%X)", - la); - continue; - } - line_count = resp&MBR_READ_INTERRUPTERS_MASK; - while(line_count--){ - cmd = MBC_ASSIGN_INTERRUPTER_LINE | - ((line_count+1)<<4) | - VXIMSGINTLEVEL; - sysIntEnable(VXIMSGINTLEVEL); - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected ASSIGN_INT(LA=0x%X)", - la); - continue; - } - if(MBR_STATUS(resp) != MBR_STATUS_SUCCESS){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "ASSIGN_INT failed (LA=0x%X)", - la); - continue; - } - } - } -} - - - - -/* - * - * epvxiSymbolTableInit() - * (written by Richard Baker LANL summer intern) - * - */ -LOCAL EPVXISTAT epvxiSymbolTableInit(void) -{ - - epvxiSymbolTable = symTblCreate( - EPVXI_MAX_SYMBOLS_LOG2, - FALSE, - memSysPartId); - if(!epvxiSymbolTable){ - return S_epvxi_noMemory; - } - - return VXI_SUCCESS; -} - - -/* - * - * epuxiRegisterModelName() - * (written by Richard Baker LANL summer intern) - * - * - */ -EPVXISTAT epvxiRegisterModelName( -unsigned int make, -unsigned int model, -char *pmodel_name -) -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pcopy; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableDeviceIdString, make,model); - pcopy = (char *) malloc(strlen(pmodel_name)+1); - if(pcopy == NULL){ - return S_epvxi_noMemory; - } - - strcpy(pcopy, pmodel_name); - - status = symAdd( - epvxiSymbolTable, - name, - pcopy, - EPVXI_MODEL_NAME_SYMBOL, - NULL); - if(status < 0){ - char *pold_model_name; - UINT8 type; - - free(pcopy); - - status = symFindByNameAndType( - epvxiSymbolTable, - name, - &pold_model_name, - &type, - EPVXI_MODEL_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMemory; - } - else if(strcmp(pmodel_name, pold_model_name)){ - return S_epvxi_nameMismatch; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiRegisterMakeName() - * - * - */ -EPVXISTAT epvxiRegisterMakeName( -unsigned int make, -char *pmake_name -) -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pcopy; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableMakeIdString, make); - pcopy = (char *) malloc(strlen(pmake_name)+1); - if(pcopy == NULL){ - return S_epvxi_noMemory; - } - - strcpy(pcopy, pmake_name); - - status = symAdd( - epvxiSymbolTable, - name, - pcopy, - EPVXI_MAKE_NAME_SYMBOL, - NULL); - if(status<0){ - char *pold_make_name; - UINT8 type; - - free(pcopy); - - status = symFindByNameAndType( - epvxiSymbolTable, - name, - &pold_make_name, - &type, - EPVXI_MAKE_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMemory; - } - else if(strcmp(pmake_name, pold_make_name)){ - return S_epvxi_nameMismatch; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * epuxiLookupMakeName() - * (written by Richard Baker LANL summer intern) - * - */ -EPVXISTAT epuxiLookupMakeName( -unsigned int make, /* VXI manuf. */ -char *pbuffer, /* model name return */ -unsigned int bufsize, /* size of supplied buf */ -unsigned int *preadcount) /* n bytes written */ -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pmake_name; - UINT8 type; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableMakeIdString, make); - status = symFindByNameAndType( - epvxiSymbolTable, - name, - &pmake_name, - &type, - EPVXI_MAKE_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMatch; - } - if(type != EPVXI_MAKE_NAME_SYMBOL){ - abort(0); - } - *preadcount = min(strlen(pmake_name)+1, bufsize); - strncpy(pbuffer, pmake_name, bufsize); - - return VXI_SUCCESS; -} - - -/* - * - * epuxiLookupModelName() - * (written by Richard Baker LANL summer intern) - * - */ -EPVXISTAT epuxiLookupModelName( -unsigned int make, /* VXI manuf. */ -unsigned int model, /* VXI model code */ -char *pbuffer, /* model name return */ -unsigned int bufsize, /* size of supplied buf */ -unsigned int *preadcount) /* n bytes written */ -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pmodel_name; - UINT8 type; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableDeviceIdString, make, model); - status = symFindByNameAndType( - epvxiSymbolTable, - name, - &pmodel_name, - &type, - EPVXI_MODEL_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMatch; - } - if(type != EPVXI_MODEL_NAME_SYMBOL){ - abort(0); - } - *preadcount = min(strlen(pmodel_name)+1, bufsize); - strncpy(pbuffer, pmodel_name, bufsize); - - return VXI_SUCCESS; -} - - -/* - * - * epvxiExtenderList() - * - * list any bus extenders - */ -EPVXISTAT epvxiExtenderList(void) -{ - epvxiExtenderPrint(&root_extender); - - return VXI_SUCCESS; -} - - - -/* - * - * epvxiExtenderPrint - * - * - */ -LOCAL void epvxiExtenderPrint(VXIE *pvxie) -{ - VXIE *psubvxie; - - - printf( "%s Extender LA=0x%02X\n", - ext_type_name[pvxie->type], - pvxie->la); - - if(pvxie->la_mapped){ - printf("\tLA window 0x%02X - 0x%02X\n", - pvxie->la_low, - pvxie->la_high); - } - - if(pvxie->A24_mapped){ - printf("\tA24 window base=0x%08X size=0x%08X\n", - pvxie->A24_base, - pvxie->A24_size); - } - - if(pvxie->A32_mapped){ - printf("\tA32 window base=0x%08X size=0x%08X\n", - pvxie->A32_base, - pvxie->A32_size); - } - - psubvxie = (VXIE *) &pvxie->extenders.node; - while(psubvxie = (VXIE *) ellNext((ELLNODE *)psubvxie)){ - epvxiExtenderPrint(psubvxie); - } -} - - -/* - * - * register some common manufacturer names - * for consistency - * - */ -LOCAL void epvxiRegisterCommonMakeNames(void) -{ - int i; - EPVXISTAT status; - - for(i=0; i -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -enum msgDeviceSyncType { - syncInt, - syncSignal, - syncPoll -}; - -typedef -struct epvxiMessageDeviceInfo{ - unsigned err:1; /* error pending */ - unsigned trace:1; /* debug trace on */ - unsigned long timeout; /* in ticks */ - enum msgDeviceSyncType syncType; - SEM_ID syncSem; - FAST_LOCK lck; -}VXIMDI; - -#define VXIMSGSYNCDELAY 1 - -#define DEFAULTMSGTMO (sysClkRateGet()*10) /* 10 sec */ -#define MAXIMUMTMO (0xffffff) - -/* - * set to a valid LA when the LA of the - * commander is located - */ -LOCAL -int msgCommanderLA = (-1); - - -#define abort(A) taskSuspend(0) - -#define epvxiPMsgConfig(LA)\ -((VXIMDI *)(epvxiLibDeviceList[LA]?epvxiLibDeviceList[LA]->pMsgConfig:0)) - -/* - * local functions - */ -LOCAL void set_la( - unsigned la, - unsigned *pla -); - -LOCAL void vxiMsgInt( - unsigned la -); - -LOCAL void signalHandler( - int16_t signal -); - -LOCAL EPVXISTAT epvxiReadSlowHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -); - -#ifdef FASTHANDSHAKE -LOCAL EPVXISTAT epvxiReadFastHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -); -#endif - -LOCAL EPVXISTAT vxiMsgClose( - unsigned la -); - -LOCAL EPVXISTAT vxiMsgOpen( - unsigned la -); - -LOCAL void vxiMsgSignalSetup( - void -); - -LOCAL void vxiCPU030MsgSignalSetup( - void -); - -LOCAL void vxiHP1404MsgSignalSetup( - void -); - -LOCAL EPVXISTAT vxiAttemptAsyncModeControl( - unsigned la, - unsigned long cmd -); - -LOCAL EPVXISTAT vxiMsgSync( - unsigned la, - unsigned resp_mask, - unsigned resp_state, - int override_err -); - -LOCAL EPVXISTAT fetch_protocol_error( - unsigned la -); - - -/* - * should be in a header - */ -EPVXISTAT vxi_msg_test( - unsigned la -); - -EPVXISTAT vxi_msg_print_id( - unsigned la -); - -EPVXISTAT vxi_msg_test_protocol_error( - unsigned la -); - - -/* - * - * vxi_msg_test() - * - */ -EPVXISTAT vxi_msg_test( - unsigned la -) -{ - char buf[512]; - unsigned long count; - EPVXISTAT status; - - status = epvxiWrite(la, "*IDN?", 5, &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = NULL; - printf("%s %d\n", buf,count); - - status = epvxiWrite(la, "*TST?", 5, &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = NULL; - printf("%s %d\n", buf, count); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_msg_print_id - * - */ -EPVXISTAT vxi_msg_print_id( - unsigned la -) -{ - char buf[32]; - unsigned long count; - char *pcmd = "*IDN?"; - EPVXISTAT status; - - status = epvxiWrite(la, pcmd, strlen(pcmd), &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = NULL; - printf(" %s ", buf); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_msg_test_protocol_error - * - */ -EPVXISTAT vxi_msg_test_protocol_error( - unsigned la -) -{ - int i; - EPVXISTAT status; - - for(i=0;i<1000;i++){ - status = epvxiCmd(la, MBC_READ_PROTOCOL); - if(status){ - return status; - } - } - return VXI_SUCCESS; -} - - -/* - * epvxiCmd() - * - * deliver a command to a msg based device - * - */ -EPVXISTAT epvxiCmd( -unsigned la, -unsigned long cmd -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - EPVXISTAT status; - -# ifdef DEBUG - printf("cmd to be sent %4x (la=%d)\n", cmd, la); -# endif - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - - /* - * RULE C.3.3 - * A commander shall not send any command requiring a servant to - * place data in in its data registers until the commander has read - * (from the data registers) all data generated by previous commands - * (and the read ready bit is set to zero). - */ - status = vxiMsgSync( - la, - VXIWRITEREADYMASK|VXIREADREADYMASK, - VXIWRITEREADYMASK, - cmd == MBC_CLEAR); - if(status>=0){ - pcsr->dir.w.dd.msg.dlow = cmd; - } - else{ - /* - * RULE C.3.2 - */ - if(pcsr->dir.r.dd.msg.response&VXIREADREADYMASK){ - status = S_epvxi_unreadData; - } - } - - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Cmd -> %x\n", - la, - cmd); - } - - return status; -} - - - -/* - * epvxiQuery() - * - * query the response to a command - * - */ -EPVXISTAT epvxiQuery( -unsigned la, -unsigned long *presp -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - - status = vxiMsgSync( - la, - VXIREADREADYMASK, - VXIREADREADYMASK, - FALSE); - if(status==VXI_SUCCESS){ - *presp = pcsr->dir.r.dd.msg.dlow; - } - - FASTUNLOCK(&pvximdi->lck); - -# ifdef DEBUG - printf("resp returned %4x (la=%d)\n", *presp, la); -# endif - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Query -> %x\n", - la, - *presp); - } - - return status; -} - - -/* - * epvxiCmdQuery() - */ -EPVXISTAT epvxiCmdQuery( -unsigned la, -unsigned long cmd, -unsigned long *presp -) -{ - EPVXISTAT status; - - status = epvxiCmd(la, cmd); - if(status){ - return status; - } - status = epvxiQuery(la, presp); - return status; -} - - -/* - * epvxiRead() - * - * Read a string using fast handshake mode - * or call a routine to do a slow handshake - * if that is all that is supported. - */ -EPVXISTAT epvxiRead( -unsigned la, -char *pbuf, -unsigned long count, -unsigned long *pread_count, -unsigned long option -) -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - /* - * does the device support fast handshake - */ -# ifdef FASTHANDSHAKE - if(VXIFHS(pcsr)){ - status = epvxiReadFastHandshake( - la, - pbuf, - count, - pread_count, - option); - } - else{ -# endif - status = epvxiReadSlowHandshake( - la, - pbuf, - count, - pread_count, - option); -# ifdef FASTHANDSHAKE - } -# endif - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Read -> %*s\n", - la, - (int)count, - pbuf); - } - - return status; -} - - -#ifdef FASTHANDSHAKE -@@@@ needs to tell them if their buffer is full - and the EOM bit wasnt se @@@@ -/* - * epvxiReadFastHandshake() - * - * Read a string using fast handshake mode - * or call a routine to do a slow handshake - * if that is all that is supported. - * - * This function will be tested and installed - * if a card with fast handshake s found to exist - * - */ -LOCAL EPVXISTAT epvxiReadFastHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - short resp; - int fhm; - short cmd; - EPVXISTAT status; - int i; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - fhm = FALSE; - /* - * always leave room to write a NULL termination - */ - for(i=0; i<(count-1); i++){ - - while(TRUE){ - /* - * wait for fast handshake mode - */ - if(!fhm){ - status = vxiMsgSync( - la, - VXIFHSMMASK, - 0, - FALSE); - if(status){ - *pread_count = i; - goto exit; - } - fhm = TRUE; - } - - cmd = MBC_BR; - status = vxMemProbe( - &pcsr->dir.r.dd.msg.dlow, - WRITE, - sizeof(pcsr->dir.r.dd.msg.dlow), - &cmd); - if(status == OK){ - break; - } - fhm = FALSE; - } - - while(TRUE){ - /* - * wait for fast handshake mode - */ - if(!fhm){ - status = vxiMsgSync( - la, - VXIFHSMMASK, - 0, - FALSE); - if(status){ - *pread_count = i; - goto exit; - } - fhm = TRUE; - } - - status = vxMemProbe( - &pcsr->dir.r.dd.msg.dlow, - READ, - sizeof(pcsr->dir.r.dd.msg.dlow), - &resp); - if(status == OK){ - break; - } - fhm = FALSE; - } - - *pbuf = resp; - pbuf++; - if(resp & MBC_END){ - *pread_count = i+1; - break; - } - } - status = VXI_SUCCESS; -exit: - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - *pbuf = NULL; - - return status; -} -#endif - - -/* - * epvxiReadSlowHandshake() - */ -LOCAL -EPVXISTAT epvxiReadSlowHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - short resp; - EPVXISTAT status; - int function_status; - int i; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - /* - * always leave room to write a NULL termination - */ - if(count<1){ - return S_epvxi_bufferFull; - } - - FASTLOCK(&pvximdi->lck); - - /* - * always leave room to write a NULL termination - */ - function_status = S_epvxi_bufferFull; - for(i=0; i<(count-1); i++){ - - /* - * wait for handshake - * - * RULE C.3.3 specifies that there shouldnt be - * any unread data present at this point . - */ - status = vxiMsgSync( - la, - VXIWRITEREADYMASK|VXIDORMASK|VXIREADREADYMASK, - VXIWRITEREADYMASK|VXIDORMASK, - FALSE); - if(status){ - if(pcsr->dir.r.dd.msg.response&VXIREADREADYMASK){ - function_status = S_epvxi_unreadData; - } - else{ - function_status = status; - } - break; - } - - pcsr->dir.w.dd.msg.dlow = MBC_BR; - - /* - * wait for handshake - */ - status = vxiMsgSync( - la, - VXIREADREADYMASK, - VXIREADREADYMASK, - FALSE); - if(status){ - function_status = status; - break; - } - - resp = pcsr->dir.r.dd.msg.dlow; - - *pbuf = resp; - pbuf++; - if(resp & MBC_END){ - - /* - * so the read count will be correct below - */ - i++; - function_status = VXI_SUCCESS; - break; - } - } - FASTUNLOCK(&pvximdi->lck); - - *pread_count = i; - - /* - * append the NULL - */ - *pbuf = NULL; - - if(function_status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - return function_status; -} - - -/* - * epvxiWrite() - * (set the end bit on the last byte sent) - */ -EPVXISTAT epvxiWrite( -unsigned la, -char *pbuf, -unsigned long count, -unsigned long *pwrite_count, -unsigned long option -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - int i; - short cmd; - short extra; - EPVXISTAT status; - char *pstr; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - pstr = pbuf; - if(option&epvxiWriteOptPartialMsg){ - extra = 0; - } - else{ - extra = MBC_END; - } - for(i=0; idir.r.dd.msg.dlow = cmd; - pstr++; - } - *pwrite_count = i; - status = VXI_SUCCESS; -exit: - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Write -> %*s\n", - la, - (int)count, - pbuf); - } - - return status; -} - - -/* - * - * epvxiSetTimeout() - * - * change the message based transfer timeout - * (timeout is in milli sec) - * - */ -EPVXISTAT epvxiSetTimeout( -unsigned la, -unsigned long timeout -) -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - /* - * order of operations significant here - */ - if(timeout > MAXIMUMTMO){ - return S_epvxi_timeoutToLarge; - } - - pvximdi->timeout = (timeout * sysClkRateGet())/1000; - - return VXI_SUCCESS; -} - - -/* - * - * epvxiSetTraceEnable() - * - * turn trace mode on or off - * - */ -EPVXISTAT epvxiSetTraceEnable(la, enable) -unsigned la; -int enable; -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pvximdi->trace = enable?TRUE:FALSE; - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgClose() - * - * - */ -LOCAL -EPVXISTAT vxiMsgClose( -unsigned la -) -{ - EPVXISTAT status; - VXIMDI *pvximdi; - - pvximdi = epvxiPMsgConfig(la); - if(!pvximdi){ - return S_epvxi_notOpen; - } - - status = semDelete(pvximdi->syncSem); - if(status){ - errMessage( - S_epvxi_internal, - "vxiMsgClose(): bad sem id"); - } - FASTLOCKFREE(&pvximdi->lck); - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgOpen() - * - * - */ -LOCAL -EPVXISTAT vxiMsgOpen( - unsigned la -) -{ - EPVXISTAT status; - VXIDI *pvxidi; - VXIMDI *pvximdi; - unsigned long resp; - unsigned long read_proto_resp; - unsigned long cmd; - struct vxi_csr *pcsr; - int signalSync = FALSE; - int intSync = FALSE; - - - /* - * return quickly if we have been here before - */ - pvxidi = epvxiLibDeviceList[la]; - if(pvxidi){ - if(pvxidi->pMsgConfig){ - return VXI_SUCCESS; - } - } - - /* - * standard verification of unknown LA - */ - status = epvxiDeviceVerify(la); - if(status){ - return status; - } - - pcsr = VXIBASE(la); - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - return S_epvxi_notMsgDevice; - } - - pvximdi = (VXIMDI *) calloc(1, sizeof(*pvximdi)); - if(!pvximdi){ - return S_epvxi_noMemory; - } - - pvxidi->pMsgConfig = (void *) pvximdi; - - vxiMsgSignalSetup(); - - pvximdi->syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - if(!pvximdi->syncSem){ - return S_epvxi_noMemory; - } - - /* - * - * assume the worst for the transfers below - * - */ - pvximdi->timeout = DEFAULTMSGTMO; - pvximdi->syncType = syncPoll; - FASTLOCKINIT(&pvximdi->lck); - - /* - * if it is not an interrupter or a signal - * generator then we poll - */ - if(!VXIMBINT(pcsr) && !VXIVMEBM(pcsr)){ - return VXI_SUCCESS; - } - - /* - * if it is not a response generator then we poll - */ - status = epvxiCmdQuery( - la, - (unsigned long) MBC_READ_PROTOCOL, - &read_proto_resp); - if(status){ - /* - * All devices are required by the VXI standard - * to accept this command while in the - * configure state or in the normal operation - * state. Some dont. - * - */ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected MBC_READ_PROTOCOL (la=0X%X)", - la); - return VXI_SUCCESS; - } - -return VXI_SUCCESS; - - if(!MBR_RP_RG(read_proto_resp)){ - return VXI_SUCCESS; - } - -printf("mb device has response gen\n"); - - /* - * try to setup interrupt synchronization first - * (this works even if we dont have a signal register) - */ - if(VXIMBINT(pcsr)){ - cmd = MBC_ASYNC_MODE_CONTROL | - MBC_AMC_RESP_ENABLE | - MBC_AMC_RESP_INT_ENABLE; - status = vxiAttemptAsyncModeControl(la, cmd); - if(status>=0){ - printf( "%s: mb device has int sync!\n", - __FILE__); - intSync = TRUE; - } - } - - /* - * hopefully a signal register is available if we get to here - */ - if(VXIVMEBM(pcsr) && !intSync && msgCommanderLA>=0){ - cmd = MBC_ASYNC_MODE_CONTROL | - MBC_AMC_RESP_ENABLE | - MBC_AMC_EVENT_ENABLE | - MBC_AMC_RESP_SIGNAL_ENABLE | - MBC_AMC_EVENT_SIGNAL_ENABLE; - status = vxiAttemptAsyncModeControl(la, cmd); - if(status>=0){ - printf( "%s: mb device has signal sync!\n", - __FILE__); - signalSync = TRUE; - } - } - - if(!intSync && !signalSync){ - errMessage( - S_epvxi_msgDeviceFailure, - "mb responder failed to configure"); - return VXI_SUCCESS; - } - - cmd = MBC_CONTROL_RESPONSE; - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errMessage( - status, - "Control response rejected by responder"); - vxiMsgClose(la); - return status; - } - if( MBR_STATUS(resp) != MBR_STATUS_SUCCESS || - (resp^cmd)&MBR_CR_CONFIRM_MASK){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "Control Response Failed %x", - resp); - return VXI_SUCCESS; - } -printf("sent ctrl resp (la=%d) (cmd=%x)\n", la, cmd); - -printf("synchronized msg based device is ready!\n"); - - if(intSync){ - pvximdi->syncType = syncInt; - } - if(signalSync){ - pvximdi->syncType = syncSignal; - } - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgSignalSetup - * - * - */ -LOCAL -void vxiMsgSignalSetup( - void -) -{ - static char vxiMsgSignalInit; - - if(vxiMsgSignalInit){ - return; - } - - vxiMsgSignalInit = TRUE; - - vxiHP1404MsgSignalSetup(); - - if(msgCommanderLA<0){ - vxiCPU030MsgSignalSetup(); - } - - if(msgCommanderLA<0){ - errMessage( - S_epvxi_noCmdr, - NULL); - } -} - - -/* - * - * vxiCPU030MsgSignalSetup - * - * - */ -LOCAL void vxiCPU030MsgSignalSetup( - void -) -{ - int niMsgLA; - EPVXISTAT status; - - if( !pnivxi_func[(unsigned)e_EnableSignalInt] || - !pnivxi_func[(unsigned)e_SetSignalHandler] || - !pnivxi_func[(unsigned)e_RouteSignal] || - !pnivxi_func[(unsigned)e_GetMyLA]){ - return; - } - - niMsgLA = (*pnivxi_func[(unsigned)e_GetMyLA])(); - -# define ANY_DEVICE (-1) -# define MSG_RESP_ENABLE (0x3f) - status = (*pnivxi_func[(unsigned)e_RouteSignal])( - ANY_DEVICE, - ~0); /* enable every thing */ - if(status){ - return; - } - -# define UKN_DEVICE (-2) - status = (*pnivxi_func[(unsigned)e_SetSignalHandler])( - UKN_DEVICE, - signalHandler); - if(status){ - return; - } - - status = (*pnivxi_func[(unsigned)e_EnableSignalInt])(); - if(status){ - return; - } - - msgCommanderLA = niMsgLA; - - return; -} - - -/* - * - * vxiHP1404MsgSignalSetup - * - * - */ -LOCAL -void vxiHP1404MsgSignalSetup( - void -) -{ - epvxiDeviceSearchPattern dsp; - int hpMsgLA = -1; - int hpRegLA = -1; - EPVXISTAT status; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_MSG; - status = epvxiLookupLA(&dsp, set_la, (void *)&hpMsgLA); - if(status){ - return; - } - if(hpMsgLA<0){ - return; - } - dsp.flags = VXI_DSP_make | VXI_DSP_slot; - dsp.make = VXI_MAKE_HP; - dsp.slot = epvxiLibDeviceList[hpMsgLA]->slot; - status = epvxiLookupLA(&dsp, set_la, (void *)&hpRegLA); - if(status){ - return; - } - - if(hpRegLA<0){ - return; - } - - msgCommanderLA = hpMsgLA; - status = hpE1404SignalConnect(hpRegLA, signalHandler); - if(status){ - errMessage(status, NULL); - } - - return; -} - - -/* - * - * set_la - * - * - */ -LOCAL void set_la( -unsigned la, -unsigned *pla -) -{ - *pla = la; -} - - -/* - * - * vxiAttemptAsyncModeControl - * - * - */ -LOCAL EPVXISTAT vxiAttemptAsyncModeControl( - unsigned la, - unsigned long cmd -) -{ - EPVXISTAT status; - unsigned long resp; - unsigned long tmpcmd; - - if(msgCommanderLA<0 && cmd&MBC_AMC_RESP_SIGNAL_ENABLE){ - return S_epvxi_badConfig; - } - - /* - * this step tells the device what la to signal at - */ - if(cmd & MBC_AMC_RESP_SIGNAL_ENABLE){ - tmpcmd = MBC_IDENTIFY_COMMANDER | msgCommanderLA; - status = epvxiCmd( - la, - tmpcmd); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "IDENTIFY_COMMANDER rejected (la=0X%X)", - la); - return status; - } -printf("sent id cmdr (la=0X%X) (cmd=%x)\n", la, tmpcmd); - } - - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Async mode control rejected (la=0X%X)", - la); - return status; - } - if( MBR_STATUS(resp) != MBR_STATUS_SUCCESS || - (resp^cmd)&MBR_AMC_CONFIRM_MASK){ - status = S_epvxi_msgDeviceFailure; - errPrintf( - status, - __FILE__, - __LINE__, - "async mode ctrl failure (la=0X%X,cmd=%x,resp=%x)", - la, - cmd, - resp); - return status; - } -printf("sent asynch mode control (la=%d) (cmd=%x)\n",la,cmd); - - - if(cmd & MBC_AMC_RESP_INT_ENABLE){ - intConnect( - INUM_TO_IVEC(la), - vxiMsgInt, - la); -printf("connected to interrupt (la=%d)\n", la); - } - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgSync() - * - * - */ -LOCAL EPVXISTAT vxiMsgSync( - unsigned la, - unsigned resp_mask, - unsigned resp_state, - int override_err -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - EPVXISTAT status; - long timeout; - unsigned short resp; - int pollcnt = 100; - - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - -# ifdef DEBUG - printf( "Syncing to resp mask %4x, request %4x (la=%d)\n", - resp_mask, - resp_state, - la); -# endif - - timeout = pvximdi->timeout; - do{ - int sync; - - resp = pcsr->dir.r.dd.msg.response; - - sync = !((resp^resp_state)&resp_mask); - - if(!(resp & VXIERRNOTMASK)){ - if(!override_err && !pvximdi->err){ - pvximdi->err = TRUE; - return S_epvxi_protocolError; - } - } - - if(sync){ - return VXI_SUCCESS; - } - - /* - * this improves VXI throughput at the - * expense of sucking CPU - */ - if(pollcnt>0){ - pollcnt--; - } - else{ - status = semTake( - pvximdi->syncSem, - VXIMSGSYNCDELAY); - if(status){ - timeout -= VXIMSGSYNCDELAY; - } - } - } - while(timeout>0); - - /* - * sync timed out if we got here - */ - status = S_epvxi_deviceTMO; - errPrintf( - status, - __FILE__, - __LINE__, - "msg dev timed out after %d sec", - (pvximdi->timeout-timeout) / sysClkRateGet()); - errPrintf( - status, - __FILE__, - __LINE__, - "resp mask %4x, request %4x, actual %4x", - resp_mask, - resp_state, - resp); - return status; -} - - -/* - * - * fetch_protocol_error - * - */ -LOCAL EPVXISTAT fetch_protocol_error( - unsigned la -) -{ - VXIMDI *pvximdi; - unsigned long error; - struct vxi_csr *pcsr; - unsigned short resp; - EPVXISTAT status; - - pvximdi = epvxiPMsgConfig(la); - if(!pvximdi){ - return S_epvxi_errFetchFailed; - } - - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL_ERROR, - &error); - if(status){ - errMessage(status, "serial protocol error fetch"); - return S_epvxi_errFetchFailed; - } - - pcsr = VXIBASE(la); - resp = pcsr->dir.r.dd.msg.response; - - if(resp & VXIERRNOTMASK){ - pvximdi->err = FALSE; - } - else{ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "Device failed to clear its ERR bit (la=0X%X)", - la); - } - - switch(error){ - case MBE_MULTIPLE_QUERIES: - status = S_epvxi_multipleQueries; - break; - case MBE_UNSUPPORTED_CMD: - status = S_epvxi_unsupportedCmd; - break; - case MBE_DIR_VIOLATION: - status = S_epvxi_dirViolation; - break; - case MBE_DOR_VIOLATION: - status = S_epvxi_dorViolation; - break; - case MBE_RR_VIOLATION: - status = S_epvxi_rrViolation; - break; - case MBE_WR_VIOLATION: - status = S_epvxi_wrViolation; - break; - case MBE_NO_ERROR: - default: - status = S_epvxi_errFetchFailed; - break; - } - - errMessage(status, "serial protocol error"); - return status; -} - - -/* - * - * vxiMsgInt - * - * - */ -LOCAL -void vxiMsgInt( - unsigned la -) -{ - VXIMDI *pvximdi; - - /* - * verify that this device is open for business - */ - pvximdi = epvxiPMsgConfig(la); - if(pvximdi){ - - /* - * - * wakeup pending tasks - * - */ - semGive(pvximdi->syncSem); - } - else{ - logMsg( - "%s: vxiMsgInt(): msg int to ukn or closed dev\n", - (int)__FILE__, - NULL, - NULL, - NULL, - NULL, - NULL); - } -} - - - -/* - * signalHandler - */ -LOCAL -void signalHandler( -int16_t signal -) -{ - unsigned signal_la; - - signal_la = signal & VXIADDRMASK; - - if(MBE_EVENT_TEST(signal)){ - logMsg( "%s: VXI event was ignored %x\n", - (int)__FILE__, - signal, - NULL, - NULL, - NULL, - NULL); - } - else{ - vxiMsgInt(signal_la); - } -} diff --git a/src/drv/old/drvHp1404a.c b/src/drv/old/drvHp1404a.c deleted file mode 100644 index 06c51d071..000000000 --- a/src/drv/old/drvHp1404a.c +++ /dev/null @@ -1,408 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * - * HP E1404A VXI bus slot zero translator - * device dependent routines - * - * share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93 - * - * Author Jeffrey O. Hill - * Date 030692 - * - * 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 joh 073092 Added msg device support & interrupt shutdown for - * soft reboots - * .02 joh 082792 converted to ANSI C - * .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals - * - * - * - */ - -static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93"; - -#include -#include -#include -#include - -#include -#include -#include - -LOCAL unsigned long hpE1404DriverID; - -struct hpE1404_config{ - void (*pSignalCallback)(int16_t signal); -}; - -#define TLTRIG(N) (1<<(N)) -#define ECLTRIG(N) (1<<((N)+8)) - -/* - * enable int when signal register is written - */ -#define HP1404A_INT_ENABLE 0x0008 -#define HP1404A_INT_DISABLE 0x0000 - -/* - * - * tag the device dependent registers - */ -#define IRQ_enable dir.w.dd.reg.ddx1a -#define MSG_status dir.w.dd.reg.ddx1e -#define fp_trig_drive dir.w.dd.reg.ddx2a -#define bp_trig_drive dir.w.dd.reg.ddx22 -#define signal_read dir.r.dd.reg.ddx10 - -#define hpE1404PConfig(LA, PC) \ - epvxiFetchPConfig((LA), hpE1404DriverID, (PC)) - -LOCAL void hpE1404InitLA( - unsigned la -); - -LOCAL int hpE1404ShutDown( - void -); - -LOCAL void hpE1404ShutDownLA( - unsigned la -); - -LOCAL void hpE1404IOReport( -unsigned la, -unsigned level -); - -LOCAL void hpE1404Int( -unsigned la -); - - - -/* - * - * hpE1404Init - * - */ -hpE1404Stat hpE1404Init(void) -{ - hpE1404Stat status; - - status = rebootHookAdd(hpE1404ShutDown); - if(status<0){ - status = S_dev_internal; - errMessage(status, "rebootHookAdd() failed"); - return status; - } - - hpE1404DriverID = epvxiUniqueDriverID(); - - status = epvxiRegisterMakeName( - VXI_MAKE_HP, - "Hewlett-Packard"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_REG_SLOT0, - "Slot Zero Translator (reg)"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_REG, - "Translator (reg)"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_MSG, - "Translator (msg)"); - if(status){ - errMessage(status, NULL); - } - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0; - status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return status; - } - - dsp.model = VXI_HP_MODEL_E1404_REG; - status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return status; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404ShutDown() - * - * - */ -LOCAL int hpE1404ShutDown(void) -{ - hpE1404Stat status; - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0; - status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return ERROR; - } - - dsp.model = VXI_HP_MODEL_E1404_REG; - status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return ERROR; - } - return OK; -} - - -/* - * - * hpE1404ShutDownLA() - * - * - */ -LOCAL -void hpE1404ShutDownLA( - unsigned la -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->IRQ_enable = HP1404A_INT_DISABLE; -} - - -/* - * - * hpE1404InitLA() - * - */ -LOCAL -void hpE1404InitLA( - unsigned la -) -{ - struct hpE1404_config *pc; - struct vxi_csr *pcsr; - hpE1404Stat status; - - status = epvxiOpen( - la, - hpE1404DriverID, - sizeof(*pc), - hpE1404IOReport); - if(status){ - errMessage(status, NULL); - return; - } - - pcsr = VXIBASE(la); - - status = hpE1404PConfig(la, pc); - if(status){ - errMessage(status, NULL); - epvxiClose(la, hpE1404DriverID); - return; - } - - /* - * set the self test status to passed for - * the message based device - */ - pcsr->MSG_status = VXIPASS<<2; - - intConnect( - INUM_TO_IVEC(la), - hpE1404Int, - la); - - /* - * enable int when signal register is written - */ - pcsr->IRQ_enable = HP1404A_INT_ENABLE; - - return; -} - - -/* - * - * hpE1404SignalConnect() - * - */ -hpE1404Stat hpE1404SignalConnect( -unsigned la, -void (*pSignalCallback)(int16_t signal) -) -{ - hpE1404Stat s; - struct hpE1404_config *pc; - - s = hpE1404PConfig(la, pc); - if(s){ - return s; - } - - pc->pSignalCallback = pSignalCallback; - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404Int() - * - */ -LOCAL -void hpE1404Int( - unsigned la -) -{ - hpE1404Stat s; - struct vxi_csr *pcsr; - unsigned short signal; - struct hpE1404_config *pc; - - s = hpE1404PConfig(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - - /* - * vector is only D8 so we cant check the cause of the int - * (signal cause is assumed since that was all that was enabled) - */ - - pcsr = VXIBASE(la); - - signal = pcsr->signal_read; - - if(pc->pSignalCallback){ - (*pc->pSignalCallback)(signal); - } -} - - -/* - * - * hpE1404RouteTriggerECL - * - */ -hpE1404Stat hpE1404RouteTriggerECL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->fp_trig_drive = (io_map&enable_map)<<8; - pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8; - - return VXI_SUCCESS; -} - - -/* - * - * - * hpE1404RouteTriggerTTL - * - * - */ -hpE1404Stat hpE1404RouteTriggerTTL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->fp_trig_drive = io_map&enable_map; - pcsr->bp_trig_drive = (~io_map)&enable_map; - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404IOReport() - * - * - */ -LOCAL -void hpE1404IOReport( - unsigned la, - unsigned level -) -{ - - - - -} diff --git a/src/drv/old/drvHp1404a.h b/src/drv/old/drvHp1404a.h deleted file mode 100644 index f6f6d2bfb..000000000 --- a/src/drv/old/drvHp1404a.h +++ /dev/null @@ -1,74 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * drvHp1404a.h - * - * HP E1404A VXI bus slot zero translator - * device dependent routines header file - * - * share/src/drv/@(#)drvHp1404a.h 1.1 8/27/93 - * - * Author Jeffrey O. Hill - * Date 030692 - * - * 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: - * ----------------- - * - * - * - */ - -typedef long hpE1404Stat; - -hpE1404Stat hpE1404Init(void); - -hpE1404Stat hpE1404SignalConnect( - unsigned la, - void (*pSignalCallback)(int16_t signal) -); - -hpE1404Stat hpE1404RouteTriggerECL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -); - -hpE1404Stat hpE1404RouteTriggerTTL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -); - -#define VXI_HP_MODEL_E1404_REG_SLOT0 0x10 -#define VXI_HP_MODEL_E1404_REG 0x110 -#define VXI_HP_MODEL_E1404_MSG 0x111 - - diff --git a/src/drv/old/drvHpe1368a.c b/src/drv/old/drvHpe1368a.c deleted file mode 100644 index a760b09d1..000000000 --- a/src/drv/old/drvHpe1368a.c +++ /dev/null @@ -1,359 +0,0 @@ -/* drvHpe1368a.c*/ -/* base/src/drv $Id$ */ - -/* - * hpe1368a_driver.c - * - * driver for hpe1368a and hpe1369a microwave switch VXI modules - * - * Author: Jeff Hill - * Date: 052192 - * - * 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 071792 joh Added model name registration - * .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID - * .03 082692 mrk Added support for new I/O event scanning and DRVET - * .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - * - */ - -static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93"; - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define HPE1368A_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), hpe1368aDriverId, (PC)) - -#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08) -#define ModuleStatus(PCSR) ((PCSR)->dir.r.status) - -#define ALL_SWITCHES_OPEN 0 - -struct hpe1368a_config{ - FAST_LOCK lock; /* mutual exclusion */ - unsigned short pending; /* switch position pending int */ - unsigned short shadow; /* shadow of actual switch pos */ - int busy; /* relays active */ - IOSCANPVT ioscanpvt; -}; - -#define HPE1368A_INT_LEVEL 1 - -LOCAL int hpe1368aDriverId; - -LOCAL void hpe1368a_int_service(unsigned la); -LOCAL void hpe1368a_init_card(unsigned la); -LOCAL void hpe1368a_stat(unsigned la, int level); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvHpe1368a={ - 2, - NULL, /*VXI io report takes care of this */ - hpe1368a_init}; - - -/* - * hpe1368a_init - * - * initialize all hpe1368a cards - * - */ -hpe1368aStat hpe1368a_init(void) -{ - hpe1368aStat r0; - - /* - * do nothing on crates without VXI - */ - if(!epvxiResourceMangerOK){ - return VXI_SUCCESS; - } - - hpe1368aDriverId = epvxiUniqueDriverID(); - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_MODEL_HPE1368A; - r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL); - if(r0){ - errMessage(r0, NULL); - return r0; - } - } - - return VXI_SUCCESS; -} - - - -/* - * HPE1368A_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL void hpe1368a_init_card(unsigned la) -{ - hpe1368aStat r0; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - int model; - - r0 = epvxiOpen( - la, - hpe1368aDriverId, - (unsigned long) sizeof(*pc), - hpe1368a_stat); - if(r0){ - errMessage(r0,NULL); - return; - } - - r0 = HPE1368A_PCONFIG(la, pc); - if(r0){ - errMessage(r0, NULL); - return; - } - - pcsr = VXIBASE(la); - - /* - * we must reset the device to a known state since - * we cant read back the current state - */ - pc->pending = ALL_SWITCHES_OPEN; - pc->shadow = ALL_SWITCHES_OPEN; - ChannelEnable(pcsr) = ALL_SWITCHES_OPEN; - - FASTLOCKINIT(&pc->lock); - scanIoInit(&pc->ioscanpvt); - - r0 = intConnect( - INUM_TO_IVEC(la), - hpe1368a_int_service, - la); - if(r0 == ERROR){ - errMessage(S_dev_vxWorksVecInstlFail, NULL); - return; - } - - sysIntEnable(HPE1368A_INT_LEVEL); - - model = VXIMODEL(pcsr); - r0 = epvxiRegisterModelName( - VXIMAKE(pcsr), - model, - "E 1368A Microwave Switch\n"); - if(r0){ - errMessage(r0, NULL); - } - r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard"); - if(r0){ - errMessage(r0,NULL); - } -} - - -/* - * - * hpe1368a_int_service() - * - * - * This device interrupts once the - * switches have settled - * - */ -LOCAL void -hpe1368a_int_service(unsigned la) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la,pc); - if(s){ - return; - } - - /* - * operation completed so we can update - * the shadow value - */ - pc->shadow = pc->pending; - pc->busy = FALSE; - - /* - * tell them that the switches have settled - */ - scanIoRequest(pc->ioscanpvt); -} - - -/* - * HPE1368A_STAT - * - * initialize single at5vxi card - * - */ -LOCAL void hpe1368a_stat( -unsigned la, -int level -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return; - } - pcsr = VXIBASE(la); - - if(level>0){ - printf("\tSwitch states %x\n", pc->shadow); - printf("\tModule status %x\n", pcsr->dir.r.status); - if(pc->busy){ - printf("\tModule is busy.\n"); - } - } -} - - -/* - * hpe1368a_getioscanpvt() - */ -hpe1368aStat hpe1368a_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - *scanpvt = pc->ioscanpvt; - return VXI_SUCCESS; -} - - -/* - * HPE1368A_BO_DRIVER - */ -hpe1368aStat hpe1368a_bo_driver( -unsigned la, -unsigned val, -unsigned mask -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - unsigned int work; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pc->lock); - - work = pc->pending; - - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - pc->pending = work; - - ChannelEnable(pcsr) = work; - - FASTUNLOCK(&pc->lock); - - return VXI_SUCCESS; -} - - - -/* - * - * HPE1368A_BI_DRIVER - * - * - * - */ -hpe1368aStat hpe1368a_bi_driver( -unsigned la, -unsigned mask, -unsigned *pval -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - FASTLOCK(&pc->lock); - - *pval = pc->shadow & mask; - - FASTUNLOCK(&pc->lock); - - return VXI_SUCCESS; -} diff --git a/src/drv/old/drvHpe1368a.h b/src/drv/old/drvHpe1368a.h deleted file mode 100644 index 6e7688555..000000000 --- a/src/drv/old/drvHpe1368a.h +++ /dev/null @@ -1,60 +0,0 @@ -/* drvHpe1368a.h*/ -/* base/src/drv $Id$ */ - -/* - * hpe1368a_driver.h - * - * driver for hpe1368a and hpe1369a microwave switch VXI modules - * - * Author: Jeff Hill - * Date: 052192 - * - * 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: - * ----------------- - * - */ - -#define VXI_MODEL_HPE1368A (0xf28) - -typedef long hpe1368aStat; - -hpe1368aStat hpe1368a_init(void); - -hpe1368aStat hpe1368a_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -); - -hpe1368aStat hpe1368a_bo_driver( -unsigned la, -unsigned val, -unsigned mask -); - -hpe1368aStat hpe1368a_bi_driver( -unsigned la, -unsigned mask, -unsigned *pval -); - diff --git a/src/drv/old/drvHpe1445a.c b/src/drv/old/drvHpe1445a.c deleted file mode 100644 index e26af0598..000000000 --- a/src/drv/old/drvHpe1445a.c +++ /dev/null @@ -1,1185 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * driver for hpe1445a arbitrary function generator VXI modules - * - * Author: Jeff Hill - * Date: 082492 - * - * 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 021192 joh Fixed hpe1445aUnloadWaveformLocked() ANSI C - * function prototype missmatch. Changed - * unsigned short to unsigned. - * - * - */ - -static char *sccsId = "@(#)drvHpe1445a.c 1.5\t8/27/93"; - -#include -#include -#include - -#include -#include -#include -#include - -/* - * comment out this line if you prefer - * to use backplane ttl trigger 0 - */ -#define FRONT_PANEL_TRIGGER - -#define VXI_MODEL_HPE1445A (418) - -LOCAL int hpe1445aDriverId; - -#define HPE1445A_MAX_POINTS 0x40000 -#define HPE1445A_MIN_POINTS 4 - -#define HPE1445_DATA_PORT_OFFSET (0x26) - -struct hpe1445aConfig { - FAST_LOCK lck; - char device_active; - double dacPeakAmplitude; - double dacOffset; - char buf[256]; -}; - -#define HPE1445A_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), hpe1445aDriverId, (PC)) - -typedef long hpe1445aStat; - -/* - * - * For External Use - * - */ -hpe1445aStat hpe1445aInit(void); -hpe1445aStat hpe1445aSetupDAC(unsigned la, double dacPeakAmplitude, double dacOffset); -hpe1445aStat hpe1445aSetupFreq(unsigned la, char *pFreqString); -void hpe1445aIoReport(unsigned la, int level); -hpe1445aStat hpe1445aLoadWaveform(unsigned la, char *pWaveformName, - double *pdata, unsigned long npoints); -hpe1445aStat hpe1445aUnloadWaveform(unsigned la, char *pWaveformName); -hpe1445aStat hpe1445aActivateWaveform(unsigned la, char *pWaveformName); -hpe1445aStat hpe1445aTest(unsigned la); -hpe1445aStat hpe1445aWriteWithLineno(unsigned la, char *pmsg, unsigned lineno); -void hpe1445aLogErrorsWithLineno(unsigned la, int lineno); - - -/* - * - * For Driver Internal Use - * - */ -LOCAL void hpe1445aInitCard(unsigned la); -LOCAL hpe1445aStat hpe1445aReset(unsigned la); -LOCAL hpe1445aStat logEntireError(unsigned la, int lineno); -LOCAL hpe1445aStat hpe1445aActivateWaveformLocked(unsigned la, char *pWaveformName, - struct hpe1445aConfig *pc); -LOCAL hpe1445aStat hpe1445aSetupFunction(unsigned la); -LOCAL hpe1445aStat hpe1445aSetupOutput(unsigned la); -LOCAL hpe1445aStat hpe1445aArm(unsigned la); -LOCAL hpe1445aStat hpe1445aUnloadWaveformLocked(unsigned la, char *pWaveformName); -LOCAL hpe1445aStat hpe1445aLoadWaveformLocked(unsigned la, - struct hpe1445aConfig *pc, - char *pWaveformName, double *pdata, - unsigned long npoints); - - -#define logErrors(LA) hpe1445aLogErrorsWithLineno(LA, __LINE__) -#define hpe1445aWrite(LA, PMSG) hpe1445aWriteWithLineno(LA, PMSG, __LINE__) - -#define HPE1445A_MAX_NAME_LENGTH 12 -#define SEGMENT_NAME_PREFIX "e_" -#define SEQUENCE_NAME_PREFIX "e__" -#define PREFIX_MAX_NAME_LENGTH 3 -#define MAX_NAME_LENGTH (HPE1445A_MAX_NAME_LENGTH-PREFIX_MAX_NAME_LENGTH) - -#define TEST_FILE_NAME "hpe1445a.dat" - - -/* - * - * hpe1445aTest() - * - * - */ -hpe1445aStat hpe1445aTest(unsigned la) -{ - hpe1445aStat s; - FILE *pf; - char *pfn = TEST_FILE_NAME; - double *pwaveform; - int nsamples; - int i; - - pf = fopen(pfn, "r"); - if(!pf){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "file access problems %s", - pfn); - fclose(pf); - return s; - } - s = fscanf(pf, "%d", &nsamples); - if(s!=1){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "no element count in the file %s", - pfn); - fclose(pf); - return s; - } - - pwaveform = (double *) calloc(nsamples, sizeof(double)); - if(!pwaveform){ - s = S_dev_noMemory; - errPrintf( - s, - __FILE__, - __LINE__, - "specified sample count to large %s", - pfn); - fclose(pf); - return s; - } - - for(i=0; ibuf, - sizeof(pc->buf), - &read_count, - 0); - if(s!=S_epvxi_bufferFull && s!=VXI_SUCCESS){ - errPrintf( - s, - __FILE__, - lineno, - "error fetch problem at LA=0X%X", - la); - return s; - } - nreads++; - /* - * return of zero indicates no errors - * this will always be a very short message - */ - if(nreads==1){ - int val; - int n; - - n = sscanf(pc->buf,"%d",&val); - if(n==1){ - if(val==0){ - return S_epvxi_internal; - } - } - } - errPrintf( - S_epvxi_msgDeviceStatus, - __FILE__, - lineno, - "LA=0X%X: Error => %s", - la, - pc->buf); - - if(s==VXI_SUCCESS){ - break; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aReset() - * - * - */ -LOCAL -hpe1445aStat hpe1445aReset(unsigned la) -{ - hpe1445aStat s; - - s = hpe1445aWrite(la, "*RST"); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list1:ssequence:delete:all"); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list1:segment:delete:all"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupFreq() - * - * - */ -hpe1445aStat hpe1445aSetupFreq(unsigned la, char *pFreqString) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return s; - } - - /* - * - * Set the sample rate - * - */ - sprintf(pc->buf, "source:frequency:fixed %s", pFreqString); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupFunction() - * - * - */ -LOCAL -hpe1445aStat hpe1445aSetupFunction(unsigned la) -{ - hpe1445aStat s; - - /* - * - * set the function to arbitrary waveform - * - */ - s = hpe1445aWrite(la, "source:function:shape user"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupOutput() - * - * - */ -LOCAL -hpe1445aStat hpe1445aSetupOutput(unsigned la) -{ - hpe1445aStat s; - - - /* - * set the output impedance - * (50 Ohm coax assumed) - * - */ - s = hpe1445aWrite(la, "output:impedance 50 Ohm"); - if(s){ - return s; - } - - /* - * - * disable output low pass filter - * (freq would need to be set if it were turned on) - * - */ - s = hpe1445aWrite(la, "output:filter:lpass:state off"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * hpe1445aArm() - * - */ -hpe1445aStat hpe1445aArm(unsigned la) -{ - hpe1445aStat s; - - /* - * - * initiate waveform output off the external trigger input - * - */ -#ifdef FRONT_PANEL_TRIGGER - s = hpe1445aWrite(la, "arm:start:layer2:source external"); -#else - s = hpe1445aWrite(la, "arm:start:layer2:source ttltrg0"); -#endif - if(s){ - return s; - } - - /* - * - * initiate waveform output on the rising edge - * - */ - s = hpe1445aWrite(la, "arm:start:layer2:slope positive"); - if(s){ - return s; - } - - /* - * - * output the waveform once only after receiving - * a trigger - * - */ - s = hpe1445aWrite(la, "arm:start:layer1:count 1"); - if(s){ - return s; - } - - /* - * - * output the waveform after each trigger edge - * forever - * - */ - s = hpe1445aWrite(la, "arm:start:layer2:count infinity"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * - * hpe1445aSetupDAC - * - * - * - */ -hpe1445aStat hpe1445aSetupDAC( -unsigned la, -double dacPeakAmplitude, -double dacOffset) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la,pc); - if(s){ - errMessage(s,NULL); - return s; - } - - sprintf(pc->buf, - "source:voltage:level:immediate:amplitude %f V", - dacPeakAmplitude); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - pc->dacPeakAmplitude = dacPeakAmplitude; - - sprintf(pc->buf, - "source:voltage:level:immediate:offset %f V", - dacOffset); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - pc->dacOffset = dacOffset; - - logErrors(la); - - return VXI_SUCCESS; -} - - - -/* - * - * hpe1445aActivateWaveform() - * - * - * - */ -hpe1445aStat hpe1445aActivateWaveform( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return s; - } - - FASTLOCK(&pc->lck); - - s = hpe1445aActivateWaveformLocked(la, pWaveformName, pc); - - FASTUNLOCK(&pc->lck); - - return s; -} - - -/* - * - * hpe1445aActivateWaveformLocked() - * - * - * - */ -LOCAL hpe1445aStat -hpe1445aActivateWaveformLocked( -unsigned la, -char *pWaveformName, -struct hpe1445aConfig *pc -) -{ - int s; - - if(pc->device_active){ - s = hpe1445aWrite(la, "abort"); - if(s){ - return s; - } - pc->device_active = FALSE; - } - - /* - * - * select active sequence - * - */ - sprintf( pc->buf, - "source:function:user %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * - * initiate the trigger system - * - */ - s = hpe1445aWrite(la, "initiate:immediate"); - if(s){ - return s; - } - pc->device_active = TRUE; - - logErrors(la); - - return VXI_SUCCESS; -} - - - -/* - * - * hpe1445aUnloadWaveform() - * - * - * - */ -hpe1445aStat hpe1445aUnloadWaveform( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - FASTLOCK(&pc->lck); - - s = hpe1445aUnloadWaveformLocked(la, pWaveformName); - - FASTUNLOCK(&pc->lck); - - logErrors(la); - - return s; -} - - -/* - * - * hpe1445aUnloadWaveformLocked() - * - * - * - */ -LOCAL hpe1445aStat hpe1445aUnloadWaveformLocked( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - sprintf( - pc->buf, - "source:list:ssequence:select %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list:ssequence:delete:selected"); - if(s){ - return s; - } - - sprintf( - pc->buf, - "source:list:segment:select %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list:segment:delete:selected"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - - -/* - * hpe1445aLoadWaveform() - */ -hpe1445aStat -hpe1445aLoadWaveform( -unsigned la, -char *pWaveformName, -double *pdata, -unsigned long npoints -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - if(strlen(pWaveformName)>MAX_NAME_LENGTH){ - s = S_dev_highValue; - errMessage(s, "waveform element name to long"); - return s; - } - - if(npointslck); - - s = hpe1445aLoadWaveformLocked(la, pc, pWaveformName, pdata, npoints); - - FASTUNLOCK(&pc->lck); - - return s; -} - - -/* - * - * hpe1445aLoadWaveformLocked() - * - * - */ -LOCAL hpe1445aStat hpe1445aLoadWaveformLocked( -unsigned la, -struct hpe1445aConfig *pc, -char *pWaveformName, -double *pdata, -unsigned long npoints -) -{ - unsigned long read_count; - hpe1445aStat s; - - s = hpe1445aWrite(la, "source:list:segment:free?"); - if(s){ - return s; - } - s = epvxiRead( - la, - pc->buf, - sizeof(pc->buf), - &read_count, - 0); - if(s){ - errMessage(s, "\"source:list:segment:free?\" query failed"); - return s; - } - - { - int nfree; - int nused; - - s = sscanf(pc->buf, "%d,%d", &nfree, &nused); - if(s!=2){ - s = S_dev_internal; - errMessage(s, "bad \"source:list:segment:free?\" resp"); - return s; - } - if(nfree < npoints){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "%d waveform elements available", - nfree); - errPrintf( - s, - __FILE__, - __LINE__, - "%d element waveform rejected", - npoints); - return s; - } - } - - - /* - * - * select the segment for subsequent - * commands - * - */ - sprintf( - pc->buf, - "source:list:segment:select %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - - sprintf(pc->buf, "source:list:segment:define %u", npoints); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - sprintf( pc->buf, - "source:arbitrary:download VXI,%s%s,%d", - SEGMENT_NAME_PREFIX, - pWaveformName, - npoints); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * wait for the device to finish with the download - * command prior to the backplane download - */ - s = hpe1445aWrite(la, "*OPC?"); - if(s){ - return s; - } - s = epvxiRead( - la, - pc->buf, - sizeof(pc->buf), - &read_count, - 0); - if(s){ - errMessage(s,"\"*OPC?\" query failed"); - return s; - } - - { - double truncationOffset; - double dacPeakAmplitude; - double dacOffset; - double *pwf; - unsigned short *pdata_port; - - pdata_port = (unsigned short *) epvxiA24Base(la); - pdata_port += (HPE1445_DATA_PORT_OFFSET/sizeof(*pdata_port)); - dacPeakAmplitude = pc->dacPeakAmplitude; - dacOffset = pc->dacOffset; - truncationOffset = dacPeakAmplitude/(4095*2); - for(pwf=pdata; pwf < &pdata[npoints]; pwf++){ - short idata; - double fdata; - - /* - * extra step here preserves precision - */ - fdata = (*pwf-dacOffset)*4095; - fdata = fdata/dacPeakAmplitude; - /* - * This offset causes round up to occur and - * not truncation - */ - fdata += truncationOffset; - idata = (short) fdata; - idata = idata << 3; - - if(pwf == &pdata[npoints-4]){ -# define LAST_POINT 1 - idata |= LAST_POINT; - } - - /* - * load the waveform element into the 1445 - */ - *pdata_port = idata; - } - } - - s = hpe1445aWrite(la, "source:arbitrary:download:complete"); - if(s){ - return s; - } - - /* - * - * install this segment into the sequence - * - */ - sprintf( pc->buf, - "source:list:ssequence:select %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * set the number of segments in this sequence - */ - s = hpe1445aWrite(la, "source:list:ssequence:define 1"); - if(s){ - return s; - } - sprintf(pc->buf, - "source:list:ssequence:sequence %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - s = hpe1445aWrite(la, "source:list:ssequence:dwell:count 1"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aWriteWithLineno() - * - */ -hpe1445aStat hpe1445aWriteWithLineno( - unsigned la, - char *pmsg, - unsigned lineno -) -{ - unsigned long nactual; - hpe1445aStat s; - - s = epvxiWrite( - la, - pmsg, - strlen(pmsg), - &nactual, - 0); - if(s){ - errPrintf( - s, - __FILE__, - lineno, - "LA=0X%02X MSG=%s", - la, - pmsg); - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aIoReport() - * - * - */ -void hpe1445aIoReport(unsigned la, int level) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - char *pStateName[] = {"in",""}; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - - if(level>0){ - printf("\tdevice %sactive, DAC peak = %f V, DAC offset = %f V\n", - pStateName[(unsigned)pc->device_active], - pc->dacPeakAmplitude, - pc->dacOffset); - } -} diff --git a/src/drv/old/drvKscV215.c b/src/drv/old/drvKscV215.c deleted file mode 100644 index 35a245a8a..000000000 --- a/src/drv/old/drvKscV215.c +++ /dev/null @@ -1,484 +0,0 @@ -/* drvKscV215.c*/ -/* base/src/drv $Id$ */ -/* - * KscV215_driver.c - * - * driver for KscV215 VXI module - * - * Author: Jeff Hill - * Date: 052192 - * - * 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 071792 joh Added model name registration - * .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID - * .03 082692 mrk Added support for new I/O event scanning and DRVET - * .04 012893 joh include file name change - * .05 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - * - */ - - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define MAXTRIES 100 - -#define KSCV215_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), KscV215DriverId, PC) - -#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08) -#define ModuleStatus(PCSR) ((PCSR)->dir.r.status) - -#define ALL_SWITCHES_OPEN 0 - -struct KscV215_config{ - FAST_LOCK lock; /* mutual exclusion */ - IOSCANPVT ioscanpvt; -}; - -#define KSCV215_INT_LEVEL 1 -#define KscV215Handshake (0x0040) -#define KscV215csrInit (0x9000) - -LOCAL int KscV215DriverId; - - -struct KscV215_A24{ - unsigned short diag; - unsigned short isr; - unsigned short pad1[7]; - unsigned short channels[64]; /* odd access causes a bus error ? */ - unsigned short controlMemoryAddr; - unsigned short pad2; - unsigned short controlMemoryDataWrite; - unsigned short pad3; - unsigned short controlMemoryDataRead; - unsigned short pad4; - unsigned short lastChannel; - unsigned short pad5; - unsigned short singleScan; - unsigned short pad6; - unsigned short stopScan; - unsigned short pad7; - unsigned short clearControlMemoryAddr; - unsigned short pad8; - unsigned short enableContinuousScanning; - unsigned short pad9; - unsigned short disableContinuousScanning; - unsigned short pad10; - unsigned short enableDoneInt; - unsigned short pad11; - unsigned short disbaleDoneInt; - unsigned short pad12; - unsigned short clearDoneInt; - unsigned short pad13; - unsigned short testDoneInt; - unsigned short pad14; -}; - -#ifdef INTERRUPTS -LOCAL void KscV215_int_service(unsigned la); -#endif -LOCAL void KscV215_init_card(unsigned la); - -LOCAL void KscV215_stat( -unsigned la, -int level -); - -LOCAL kscV215Stat KscV215WriteSync( -struct KscV215_A24 *pA24, -unsigned short *preg, -unsigned val -); - - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvKscV215={ - 2, - NULL, /* VXI report takes care of this */ - KscV215Init}; - -/* - * KscV215_init - * - * initialize all KscV215 cards - * - */ -kscV215Stat KscV215Init(void) -{ - kscV215Stat r0; - - /* - * do nothing on crates without VXI - */ - if(!epvxiResourceMangerOK){ - return VXI_SUCCESS; - } - - KscV215DriverId = epvxiUniqueDriverID(); - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_KSC; - dsp.model = VXI_MODEL_KSCV215; - r0 = epvxiLookupLA(&dsp, KscV215_init_card, (void *)NULL); - if(r0){ - return r0; - } - } - - return VXI_SUCCESS; -} - - - -/* - * KSCV215_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL void KscV215_init_card(unsigned la) -{ - kscV215Stat status; - int i; - struct KscV215_config *pc; - struct KscV215_A24 *pA24; - struct vxi_csr *pcsr; - int model; - - status = epvxiOpen( - la, - KscV215DriverId, - (unsigned long) sizeof(*pc), - KscV215_stat); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "AT5VXI: device open failed %d\n", - la); - - return; - } - - status = KSCV215_PCONFIG(la, pc); - if(status){ - errMessage(status,NULL); - epvxiClose(la, KscV215DriverId); - return; - } - - pA24 = epvxiA24Base(la); - pcsr = VXIBASE(la); - - pcsr->dir.w.control = KscV215csrInit; - - status = KscV215WriteSync(pA24, &pA24->controlMemoryAddr, 0); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed\n"); - return; - } - for(i=0; i<(NELEMENTS(pA24->channels)/2); i++){ - status = KscV215WriteSync( - pA24, - &pA24->controlMemoryDataWrite, - 0); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed\n"); - return; - } - } - - /* - * turn on continuous scan mode - */ - status = KscV215WriteSync( - pA24, - &pA24->enableContinuousScanning, - 0); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed- device left open\n"); - return; - } - - FASTLOCKINIT(&pc->lock); - scanIoInit(&pc->ioscanpvt); - -#ifdef INTERRUPTS - status = intConnect( - (unsigned char) INUM_TO_IVEC(la), - KscV215_int_service, - (void *) la); - if(status == ERROR){ - epvxiClose(la, KscV215DriverId); - errMessage(S_dev_vxWorksVecInstlFail, - "KscV215 init failed- device left open"); - return; - } - sysIntEnable(KSCV215_INT_LEVEL); -#endif - - status = epvxiRegisterMakeName(VXI_MAKE_KSC, "Kinetic Systems"); - if(status){ - errMessage(status, NULL); - } - - model = VXIMODEL(pcsr); - status = epvxiRegisterModelName( - VXIMAKE(pcsr), - model, - "V215 16 bit 32 channel ADC\n"); - if(status){ - errMessage(status, NULL); - } - -} - - -/* - * - * KscV215WriteSync - * - * - */ -LOCAL kscV215Stat KscV215WriteSync( -struct KscV215_A24 *pA24, -unsigned short *preg, -unsigned val -) -{ - kscV215Stat status; - int i; - - for(i=0; idiag & KscV215Handshake){ - return VXI_SUCCESS; - } - taskDelay(1); - } - - status = S_dev_deviceTMO; - errMessage(status, NULL); - return status; -} - - -/* - * - * KscV215_int_service() - * - * - * This device interrupts once the - * switches have settled - * - */ -#ifdef INTERRUPTS -LOCAL void KscV215_int_service(unsigned la) -{ - kscV215Stat s; - struct KscV215_config *pc; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - logMsg( "Int to ukn device %s line=%d\n", - __FILE__, - __LINE__, - NULL, - NULL, - NULL, - NULL); - return; - } - - /* - * tell them that the switches have settled - */ - scanIoRequest(pc->ioscanpvt); -} -#endif - - -/* - * KSCV215_STAT - * - * initialize single at5vxi card - * - */ -LOCAL void KscV215_stat( -unsigned la, -int level -) -{ - kscV215Stat s; - struct KscV215_config *pc; - struct vxi_csr *pcsr; - struct KscV215_A24 *pA24; - int i; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - pcsr = VXIBASE(la); - - pA24 = (struct KscV215_A24 *) epvxiA24Base(la); - - if(level>0){ - printf ("KSC V215 32 CHANNEL 16 BIT ADC.\n"); - } - if (level > 1) { - for (i = 0; i < 32; i++) - printf ("Channel %d Value %d\n", - i, - pA24->channels[i*2]); - } - if (level > 2) { - printf ("\nGain Setting (Control Memory Data Register\n"); - pA24->controlMemoryAddr = 0; - for (i = 0; i < 32; i++) { - switch (pA24->controlMemoryAddr) { - case 0: - printf ("+- 10V"); - break; - case 1: - printf ("+- 5V"); - break; - case 3: - printf ("+- 2.5V"); - break; - case 5: - printf ("+- 1.25V"); - break; - case 6: - printf ("+- 625mV"); - break; - default: - printf ("Unknown Gain Setting."); - } - } - printf ("\n"); - } - - - -} - - - -/* - * - * - * AT5VXI_AI_DRIVER - * - * analog input driver - */ -kscV215Stat KscV215_ai_driver( -unsigned la, -unsigned chan, -unsigned short *prval -) -{ - struct KscV215_config *pc; - struct vxi_csr *pcsr; - struct KscV215_A24 *pA24; - long tmp; - int i; - kscV215Stat s; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - return s; - } - pcsr = VXIBASE(la); - - pA24 = epvxiA24Base(la); - - if(chan >= NELEMENTS(pA24->channels)/2){ - return S_dev_badSignalNumber; - } - - for(i=0; ichannels[chan<<1]; - if(pA24->diag & KscV215Handshake){ - tmp = tmp + 0xffff; - tmp = tmp >> 4; - tmp &= 0xfff; - *prval = tmp; - return VXI_SUCCESS; - } - taskDelay(1); - } - - s = S_dev_deviceTMO; - return s; -} - - -/* - * KscV215_getioscanpvt() - */ -kscV215Stat KscV215_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -) -{ - kscV215Stat s; - struct KscV215_config *pc; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - *scanpvt = pc->ioscanpvt; - return VXI_SUCCESS; -} diff --git a/src/drv/old/drvKscV215.h b/src/drv/old/drvKscV215.h deleted file mode 100644 index 34eaf2c27..000000000 --- a/src/drv/old/drvKscV215.h +++ /dev/null @@ -1,56 +0,0 @@ -/* drvKscV215.c*/ -/* base/src/drv $Id$ */ -/* - * KscV215_driver.c - * - * driver for KscV215 VXI module - * - * Author: Jeff Hill - * Date: 052192 - * - * 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: - * ----------------- - * - */ - -#define VXI_MODEL_KSCV215 (0x215) - -typedef long kscV215Stat; - -kscV215Stat KscV215Init(void); - -kscV215Stat KscV215_ai_driver( -unsigned la, -unsigned chan, -unsigned short *prval -); - -kscV215Stat KscV215_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -); - - - - diff --git a/src/drv/old/drvMz8310.c b/src/drv/old/drvMz8310.c deleted file mode 100644 index d526c0837..000000000 --- a/src/drv/old/drvMz8310.c +++ /dev/null @@ -1,628 +0,0 @@ - -/* drvMz8310.c */ -/* base/src/drv $Id$ */ -/* - * Routines specific to the MZ8310. Low level routines for the AMD STC in - * stc_driver.c - * Author: Jeff Hill - * Date: Feb 1989 - * - * 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 History - * joh 02-20-89 Init Release - * joh 04-28-89 Added read back - * joh 11-17-89 added readback to io report - * joh 12-10-89 DB defaults the internal/external clock - * parameter to 0 or external clock. This was the opposite - * of what this driver expected. Fix was made here. - * joh 07-06-90 print channel number with channel value in IO report - * joh 02-25-91 made ext/int clk IO report more readable - * joh 09-05-91 converted to v5 vxWorks - * bg 09-15-91 added sysBustoLocalAdrs() for addressing - * bg 03-10-92 added the argument, level, to mz310_io_report(). - * bg 04-27-92 added rebootHookAdd and mz8310_reset so ioc will - * not hang on ctl X reboot. - * joh 04-28-92 added arguments to MACROS which had hidden - * parameters - * bg 06-25-92 combined drvMz8310.c and mz8310_driver.c - * bg 06-26-92 Added level to mz8310_io_report. - * joh 08-05-92 callable interface now conforms with epics standard - * mgb 08-04-93 Removed V5/V4 and EPICS_V2 conditionals - * joh 08-24-93 Include drvStc.h and ANSI C upgrade - * joh 09-29-93 removed superfluous error message - */ - -/* drvMz8310.c - Driver Support Routines for Mz8310 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#define MZ8310CHIPSIZE 0x20 -#define MZ8310SIZE 0x00000100 -#define MZ8310BASE(CARD) (shortaddr+tm_addrs[MZ8310]+(CARD)*MZ8310SIZE) - -#define MZ8310DATA 0 -#define MZ8310CMD 3 -#define MZ8310CHANONCHIP 5 -#define MZ8310CHIPCOUNT 2 -#define MZ8310CHANCNT (MZ8310CHANONCHIP*MZ8310CHIPCOUNT) - -/* - NOTE: The mizar draftsman has labeled the chip at the - highest address as one and the chip at the lowest address - 2 so I am reversing the chip number below. -*/ -#define CHIP_REVERSE(CHIP) (MZ8310CHIPCOUNT-1-(CHIP)) -#define CHIP_ADDR(CARD,CHIP) (MZ8310BASE(CARD)+\ - (CHIP_REVERSE(CHIP)*MZ8310CHIPSIZE)) - -#define MZ8310_CMD_ADDR(CARD,CHIP)\ -((volatile unsigned char *) CHIP_ADDR(CARD,CHIP) + MZ8310CMD) -#define MZ8310_DATA_ADDR(CARD,CHIP)\ -((volatile unsigned short *) CHIP_ADDR(CARD,CHIP) + MZ8310DATA) -#if 0 -#define MZ8310VECBASE(CARD,CHIP)\ -((volatile unsigned char *) CHIP_ADDR(CARD,CHIP) + 0x41) -#endif - -#define MZ8310VECSIZE (0x20) -#define MZ8310INTCNT 4 -#define MZ8310FIRSTINTCHAN 0 -#define MZ8310INTVEC(CARD,CHAN)\ -(MZ8310_INT_VEC_BASE + (CARD*MZ8310INTCNT) + mz8310_strap[CHAN].vec_num) - -#define MZ8310_INTERUPTABLE(CHAN) (mz8310_strap[CHAN].vec_addr) - -# define INT_TICKS 4.0e06 /* speed of F1 in Hz */ -# define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */ - - -struct mz8310_int_conf{ - void (*user_service)(); - int user_param; - unsigned int cnt; -}; - -struct mz8310_conf{ - char init; - FAST_LOCK lock; - struct mz8310_int_conf icf[MZ8310CHANCNT]; -}; - -struct mz8310_strap_info{ - unsigned char irq; /* the level at which the chan gen ints */ - unsigned char vec_num; /* really a vec offset-see MZ8310INTVEC */ - unsigned char vec_addr;/* offset from card base address */ -}; - -static volatile char *shortaddr; - -LOCAL struct mz8310_conf *mzconf; -LOCAL unsigned int mz8310_card_count; - -/* - only 4 unique interrupts per card but any channel can potentially - generate an interrupt depending on board strapping. - - NOTE: existence of vec addr tells the driver that that channel is - strapped for interrupts since the card can't be polled for this info. - - In the MIZAR 8310 Documentation: - - Designation vector reg offset - IRQA 0x41 - IRQB 0x61 - IRQC 0x81 - IRQD 0xa1 -*/ - -LOCAL struct mz8310_strap_info mz8310_strap[MZ8310CHANCNT] = -{ - { NULL, NULL, NULL }, /* channel 0 */ - { NULL, NULL, NULL }, /* channel 1 */ - { NULL, NULL, NULL }, /* channel 2 */ - { NULL, NULL, NULL }, /* channel 3 */ - { NULL, NULL, NULL }, /* channel 4 */ - { NULL, NULL, NULL }, /* channel 5 */ - { 1, 0, 0x41 }, /* channel 6 */ - { 3, 1, 0x61 }, /* channel 7 */ - { 5, 2, 0x81 }, /* channel 8 */ - { 6, 3, 0xa1 } /* channel 9 */ -}; - -/* forward reference. */ -LOCAL int mz8310_reset(void); -LOCAL mz8310Stat mz8310_io_report_card(unsigned card, int level); -LOCAL mz8310Stat mz8310_init_card(unsigned card); -LOCAL mz8310Stat mz8310_setup_int(unsigned card, unsigned channel); -LOCAL mz8310Stat mz8310_io_report(int level); -LOCAL mz8310Stat mz8310_init(void); -LOCAL mz8310Stat mz8310_read_test(int card, int channel); -LOCAL void mz8310_int_service(struct mz8310_int_conf *icf); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvMz8310={ - 2, - mz8310_io_report, - mz8310_init}; - - -/* - * mz8310_io_report() - */ -LOCAL mz8310Stat mz8310_io_report(int level) -{ - unsigned card; - - for(card=0; card= MZ8310CHANONCHIP * MZ8310CHIPCOUNT) - return S_dev_badSignalNumber; - - if(card>=mz8310_card_count) - return S_dev_badA16; - - if(!mzconf) - return S_dev_noDevice; - - FASTLOCK(&mzconf[card].lock); - - status = - stc_one_shot_read( - preset, - &iedge0, - &iedge1, - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - int_source); - if(status==STC_SUCCESS){ - ticks = *int_source ? INT_TICKS : EXT_TICKS; - *edge0_delay = iedge0 / ticks; - *edge1_delay = iedge1 / ticks; - } - - FASTUNLOCK(&mzconf[card].lock); - - return status; -} - - -/* - * mz8310_read_test() - */ -LOCAL mz8310Stat mz8310_read_test(int card, int channel) -{ - int preset; - double edge0_delay; - double edge1_delay; - int int_source; - mz8310Stat status; - static char *pclktype[] = {"external-clk", "internal-clk"}; - static char *ppresettype[] = {"preset-FALSE", "preset-TRUE "}; - - status = - mz8310_one_shot_read( - &preset, - &edge0_delay, - &edge1_delay, - card, - channel, - &int_source); - if(status==MZ8310_SUCCESS){ - printf( "\tChannel %d %s delay=%f width=%f %s\n", - channel, - ppresettype[preset&1], - edge0_delay, - edge1_delay, - pclktype[int_source&1]); - if(mzconf[card].icf[channel].cnt) - printf("\tChannel %d Interrupt count=%u\n", - channel, - mzconf[card].icf[channel].cnt); - } - - return status; -} - - -/* - * mz8310_one_shot() - */ -mz8310Stat mz8310_one_shot( -int preset, /* TRUE or COMPLEMENT logic */ -double edge0_delay, /* sec */ -double edge1_delay, /* set */ -int card, /* 0 through ... */ -int channel, /* 0 through channels on a card */ -int int_source, /* (FALSE)External/ (TRUE)Internal source */ -void *event_rtn, /* subroutine to run on events */ -int event_rtn_param /* parameter to pass to above routine */ -) -{ - int chip = channel/MZ8310CHANONCHIP; - double ticks = int_source?INT_TICKS:EXT_TICKS; - mz8310Stat status; - - if(channel >= MZ8310CHANONCHIP * MZ8310CHIPCOUNT) - return S_dev_badSignalNumber; - - if(card>=mz8310_card_count) - return S_dev_badA16; - - if(!mzconf) - return S_dev_noDevice; - - /* dont overflow unsigned short in STC */ - if(edge0_delay >= 0xffff/ticks) - return S_dev_highValue; - if(edge1_delay >= 0xffff/ticks) - return S_dev_highValue; - if(edge0_delay < 0.0) - return S_dev_lowValue; - if(edge1_delay < 0.0) - return S_dev_lowValue; - - FASTLOCK(&mzconf[card].lock); - - /* Enable calling of user routine */ - if(MZ8310_INTERUPTABLE(channel)){ - mzconf[card].icf[channel].user_service = event_rtn; - mzconf[card].icf[channel].user_param = event_rtn_param; - } - - status = - stc_one_shot( - preset, - (unsigned short) (edge0_delay * ticks), - (unsigned short) (edge1_delay * ticks), - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - int_source); - - FASTUNLOCK(&mzconf[card].lock); - - return status; - -} - - - -/* - * mz8310_int_service() - */ -LOCAL void mz8310_int_service(struct mz8310_int_conf *icf) -{ - icf->cnt++; - - if(icf->user_service) - (*icf->user_service)(icf->user_param); - - return; -} - -/* - * The following are provided for mz8310 access from the shell - */ - - -/* - * mz8310_cmd() - */ -int mz8310_cmd( -unsigned value, -unsigned card, -unsigned chip -) -{ - volatile unsigned char *cmd = MZ8310_CMD_ADDR(card,chip); - - *cmd = value; - - return *cmd; -} - - -/* - * mz8310_rdata() - */ -int mz8310_rdata(int card, int chip) -{ - volatile unsigned short *data = MZ8310_DATA_ADDR(card,chip); - - return *data; -} - - -/* - * mz8310_wdata() - */ -int mz8310_wdata( -unsigned value, -int card, -int chip -) -{ - volatile unsigned short *data = MZ8310_DATA_ADDR(card,chip); - - *data = value; - - return value; - -} - - - -/* - * mz8310_reset - */ -LOCAL int mz8310_reset(void) -{ - short card,channel,chip; - - for (card = 0; card < mz8310_card_count; card++){ - FASTLOCK(&mzconf[card].lock); - for ( channel = 0; channel < tm_num_channels[MZ8310]; channel++){ - if (mzconf[card].icf[channel].cnt){ - chip = channel/MZ8310CHANONCHIP; - - stc_one_shot( - 0, - 10, - 0, - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - 0); - } - } - FASTUNLOCK(&mzconf[card].lock); - } - - return OK; -} - - - diff --git a/src/drv/old/drvMz8310.h b/src/drv/old/drvMz8310.h deleted file mode 100644 index 865d1bb8c..000000000 --- a/src/drv/old/drvMz8310.h +++ /dev/null @@ -1,74 +0,0 @@ -/* drvMz8310.c */ -/* base/src/drv $Id$ */ -/* - * Routines specific to the MZ8310. Low level routines for the AMD STC in - * stc_driver.c - * Author: Jeff Hill - * Date: Feb 1989 - * - * 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 History - */ - - - - -#define MZ8310_SUCCESS 0 - -typedef long mz8310Stat; - -mz8310Stat mz8310_one_shot_read( -int *preset, /* TRUE or COMPLEMENT logic */ -double *edge0_delay, /* sec */ -double *edge1_delay, /* sec */ -int card, /* 0 through ... */ -int channel, /* 0 through channels on a card */ -int *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -mz8310Stat mz8310_one_shot( -int preset, /* TRUE or COMPLEMENT logic */ -double edge0_delay, /* sec */ -double edge1_delay, /* set */ -int card, /* 0 through ... */ -int channel, /* 0 through channels on a card */ -int int_source, /* (FALSE)External/ (TRUE)Internal source */ -void *event_rtn, /* subroutine to run on events */ -int event_rtn_param /* parameter to pass to above routine */ -); - -int mz8310_cmd( -unsigned value, -unsigned card, -unsigned chip -); - -int mz8310_rdata(int card, int chip); - -int mz8310_wdata( -unsigned value, -int card, -int chip -); - - diff --git a/src/drv/old/drvStc.c b/src/drv/old/drvStc.c deleted file mode 100644 index 0a48ab78d..000000000 --- a/src/drv/old/drvStc.c +++ /dev/null @@ -1,290 +0,0 @@ -/* drvStc.c */ -/* base/src/drv $Id$ */ -/* - * The following are specific driver routines for the AMD STC - * - * NOTE: if multiple threads use these routines at once you must provide locking - * so command/data sequences are gauranteed. See mz8310_driver.c for examples. - * - * - * Author: Jeff Hill - * Date: Feb 89 - * - * 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: - * ----------------- - * - * joh 022089 Init Release - * joh 042889 Added read back - * joh 111789 Fixed reset goes to byte mode bug - * joh 121090 Fixed confusion about the polarity of internal/external - * clock between DB and the drivers. - * joh 110791 Prevent the stc from generating tc prior to the trigger - * in delayed pulse mode by forcing edge 0 delays of zero to be - * a delay of one instead. - * joh 010491 force all edge 0 delays less than two to two - * joh 082493 ANSI C and EPICS return codes - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - - - -/* - * stc_io_report() - */ -stcStat stc_io_report( -volatile uint8_t *pcmd, -volatile uint16_t *pdata -) -{ - uint8_t cmd; - uint16_t data; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - - /* - * addd AMD STC status here - */ - - return STC_SUCCESS; -} - - - -/* - * stc_init() - */ -stcStat stc_init( -volatile uint8_t *pcmd, -volatile uint16_t *pdata, -unsigned master_mode -) -{ - uint8_t cmd; - uint16_t data; - unsigned channel; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - - /* - * go to 16 bit mode in order to test the master mode register - */ - STC_BUS16; - if(master_mode != STC_MASTER_MODE){ - - /* - * start in a known state - */ - STC_RESET; - - /* - * required since the reset puts it in byte mode - */ - STC_BUS16; - STC_SET_MASTER_MODE(master_mode); - for(channel=0; channel=CHANONCHIP) - return S_dev_badSignalNumber; - - STC_CTR_READ(mode, edge0, edge1); - - /* - * Only return values if the counter is in the proper mode - * see stc_one_shot() for info on conversions and functions selected - * by these bit fields - */ - if(mode == 0xc16a){ - *int_source = FALSE; - *preset = TRUE; - *edge0_count = ~edge0; - *edge1_count = ~edge1+1; - } - else if(mode == 0xc162){ - *int_source = FALSE; - *preset = FALSE; - *edge0_count = edge0-1; - *edge1_count = edge1; - } - else if(mode == 0xcb6a){ - *int_source = TRUE; - *preset = TRUE; - *edge0_count = ~edge0; - *edge1_count = ~edge1+1; - } - else if(mode == 0xcb62){ - *int_source = TRUE; - *preset = FALSE; - *edge0_count = edge0-1; - *edge1_count = edge1; - } - else - return S_dev_internal; - - return STC_SUCCESS; -} - - - -/* - * stc_one_shot() - */ -stcStat stc_one_shot( -unsigned preset, -unsigned edge0_count, -unsigned edge1_count, -volatile uint8_t *pcmd, -volatile uint16_t *pdata, -unsigned channel, -unsigned int_source -) -{ - uint8_t cmd; - uint16_t data; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - if(channel>=CHANONCHIP) - return S_dev_badSignalNumber; - - /* - * joh 110791 - * Prevent the stc from generating tc prior to the trigger - * in delayed pulse mode by forcing edge 0 delays of zero to be - * a delay of one instead. - * - * 010492 - * Strange extra edges occur when the delay is 0 or 1 - * and the counter is reinitialized to a width of - * zero so I have disabled a delay of one also - * - * These extra edges occur when TC is set - */ - - if(edge0_count < 2) - edge0_count = 2; - - STC_DISARM; - - /* - * active positive going edge (gate input) - * count on the rising edge of source - * ctr source: (F1- internal) (SRC1- external) - * mode L - Hardware triggered delayed pulse one-shot - * binary count - * count down (count up if preset is TRUE) - * TC toggled output - * - * see chapter 7 of the Am9513 STC tech man concerning count + 1 - * - */ - - /* - * NOTE: I must be able to read back the state of the preset later - * so I encode this information in the count down/up bit. - * count up on TRUE preset - * count down on FALSE preset - * - * see stc_one_shot_read() above - */ - if(int_source){ - if(preset) - STC_CTR_INIT(0xcb6a, ~edge0_count, ~edge1_count+1) - else - STC_CTR_INIT(0xcb62, edge0_count+1, edge1_count); - }else{ - if(preset) - STC_CTR_INIT(0xc16a, ~edge0_count, ~edge1_count+1) - else - STC_CTR_INIT(0xc162, edge0_count+1, edge1_count); - } - - STC_LOAD; - /* - *see chapter 7 of the Am9513 STC tech man concerning this step - */ - - STC_STEP; - - STC_SET_TC(preset); - - /* - * Only arm counter if the pulse has a finite duration - */ - if(edge1_count != 0){ - STC_ARM; - } - - return STC_SUCCESS; -} - - - diff --git a/src/drv/old/drvStc.h b/src/drv/old/drvStc.h deleted file mode 100644 index 5d4a6203b..000000000 --- a/src/drv/old/drvStc.h +++ /dev/null @@ -1,107 +0,0 @@ -/* drvStc.h */ -/* base/src/drv $Id$ */ -/* - * The following are specific driver routines for the AMD STC - * - * NOTE: if multiple threads use these routines at once you must provide locking - * so command/data sequences are gauranteed. See mz8310_driver.c for examples. - * - * - * Author: Jeff Hill - * Date: Feb 89 - * - * 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: - * ----------------- - * - * joh 022089 Init Release - * joh 082493 ANSI C and EPICS return codes - */ - -/* - * AMD STC constants - */ -#define CHANONCHIP 5U -#define CHIPCHAN (channel%CHANONCHIP) -#define CHIPNUM (channel/CHANONCHIP) - -#define STC_RESET *pcmd = 0xffU -#define STC_BUS16 *pcmd = 0xefU -#define STC_SET_MASTER_MODE(D) {*pcmd = 0x17U; *pdata=(D);} -#define STC_MASTER_MODE (*pcmd = 0x17U, *pdata) - -#define STC_CTR_INIT(MODE,LOAD,HOLD)\ -{*pcmd = CHIPCHAN+1; *pdata = (MODE); *pdata = (LOAD); *pdata= (HOLD);} - -#define STC_CTR_READ(MODE,LOAD,HOLD)\ -{*pcmd = CHIPCHAN+1; (MODE) = *pdata; (LOAD) = *pdata; (HOLD) = *pdata;} - -#define STC_SET_TC(D) *pcmd = 0xe0U | ((D)?8:0)|(CHIPCHAN+1U) - -#define STC_LOAD *pcmd = 0x40U | 1<<(CHIPCHAN) -#define STC_STEP *pcmd = 0xf0U | (CHIPCHAN+1U) -#define STC_ARM *pcmd = 0x20U | 1< -#include - -#include - -struct pulse{ -double offset; -double width; -}; - - - -/* - * - * time_driver_read() - * - * - */ -time_driver_read - ( - card, /* 0 through ... */ - channel, /* 0 through chans on card */ - card_type, /* module type as stored in GTA DB */ - int_source, /* (TRUE)External/ (FALSE)Internal source */ - preset, /* TRUE or COMPLEMENT logic */ - pulses, /* ptr to array of structure describing pulses */ - npulses, /* N elements found */ - npulmax /* N elements in the caller's array */ - ) -unsigned int card; -unsigned int channel; -unsigned int card_type; -unsigned int *int_source; -int *preset; -struct pulse *pulses; -unsigned int *npulses; -unsigned int npulmax; -{ - int status; - - *npulses=0; - - switch(card_type){ - case MZ8310: - if(npulmax<1) - return ERROR; - status = mz8310_one_shot_read ( - preset, - &pulses->offset, - &pulses->width, - card, - channel, - int_source - ); - if(status==0) - *npulses=1; - - return status; - case VXI_AT5_TIME: - if(npulmax<1) - return ERROR; - status = at5vxi_one_shot_read ( - preset, - &pulses->offset, - &pulses->width, - card, - channel, - int_source - ); - if(status==0) - *npulses=1; - - return status; - case DG535: - break; - default: - break; - } - logMsg("time_driver: No support for that type of timing card\n"); - return ERROR; -} - - -time_driver ( - card, /* 0 through ... */ - channel, /* 0 through chans on card */ - card_type, /* module type as stored in GTA DB */ - int_source, /* (TRUE)External/ (FALSE)Internal source */ - preset, /* TRUE or COMPLEMENT logic */ - pulses, /* ptr to array of structure describing pulses */ - npulses, /* N elements in this array */ - eventrtn, /* routine to run on events */ - eventrtnarg /* argument to above rtn */ - ) -unsigned int card; -unsigned int channel; -unsigned int card_type; -unsigned int int_source; -int preset; -struct pulse *pulses; -unsigned int npulses; -void (*eventrtn)(); -unsigned int eventrtnarg; -{ - - switch(card_type){ - case MZ8310: - if(npulses != 1) - return ERROR; - return mz8310_one_shot ( - preset, - pulses->offset, - pulses->width, - card, - channel, - int_source, - eventrtn, - eventrtnarg - ); - case VXI_AT5_TIME: - if(npulses != 1) - return ERROR; - return at5vxi_one_shot ( - preset, - pulses->offset, - pulses->width, - card, - channel, - int_source, - eventrtn, - eventrtnarg - ); - case DG535: - break; - default: - break; - } - logMsg("time_driver: No support for that type of timing card\n"); - return ERROR; -} - - - -time_test() -{ - unsigned int card=0; - unsigned int channel=0; - unsigned int card_type=MZ8310; - unsigned int int_source=1; - int preset=1; - static struct - pulse pulses={.00001,.00001}; - unsigned int npulses = 1; - - unsigned int t_int_source; - int t_preset; - struct pulse t_pulses; - unsigned int t_npulses; - - int status; - - status = - time_driver ( - card, /* 0 through ... */ - channel, /* 0 through chans on card */ - card_type, /* module type as stored in GTA DB */ - int_source, /* (TRUE)External/ (FALSE)Internal source */ - preset, /* TRUE or COMPLEMENT logic */ - &pulses, /* ptr to array of structure describing pulses */ - npulses, /* N elements in this array */ - NULL, /* routine to run on events */ - NULL /* argument to above rtn */ - ); - if(status==ERROR) - return ERROR; - - - status = - time_driver_read( - card, /* 0 through ... */ - channel, /* 0 through chans on card */ - card_type, /* module type as stored in GTA DB */ - &t_int_source, /* (TRUE)External/ (FALSE)Internal source */ - &t_preset, /* TRUE or COMPLEMENT logic */ - &t_pulses, /* ptr to array of structure describing pulses */ - &t_npulses, /* N elements found */ - 1 /* max N elements in this array */ - ); - if(status==ERROR) - return ERROR; - - - logMsg( "wrote: preset %x internal-clk %x delay %f width %f \n", - preset, - int_source, - pulses.offset, - pulses.width); - logMsg( "read: preset %x internal-clk %x delay %f width %f count %x\n", - t_preset, - t_int_source, - t_pulses.offset, - t_pulses.width, - t_npulses); - return OK; -} diff --git a/src/drv/steppermotor.h b/src/drv/steppermotor.h deleted file mode 100644 index f9d827ab3..000000000 --- a/src/drv/steppermotor.h +++ /dev/null @@ -1,64 +0,0 @@ -/* steppermotor.h */ -/* base/src/drv $Id$ */ -/* - * header file to support database library interface to motor drivers - * - * Author: Bob Dalesio - * Date: 12-11-89 - * - * 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 mm-dd-yy iii Comment - */ - -/* readback data passed to the database library routine from the motor driver */ -struct motor_data{ -short cw_limit; -short ccw_limit; -short moving; -short direction; -short constant_velocity; -long velocity; -long encoder_position; -long motor_position; -long accel; -}; - -/* - * Sets values for the database library based on the value flag: - * 0 - set the mode of the motor (position/velocity) - * 1 - set the velocity of the motor - * 2 - set the poistion of the motor - * 3 - start motor rotating - * 4 - set the callback routine for a motor - */ -#define SM_MODE 0 -#define SM_VELOCITY 1 -#define SM_MOVE 2 -#define SM_MOTION 3 -#define SM_CALLBACK 4 -#define SM_SET_HOME 5 -#define SM_ENCODER_RATIO 6 -#define SM_MOTOR_RESOLUTION 7 -#define SM_READ 8 diff --git a/src/include/asDbLib.h b/src/include/asDbLib.h deleted file mode 100644 index 5f943b80d..000000000 --- a/src/include/asDbLib.h +++ /dev/null @@ -1,45 +0,0 @@ -/* share/epicsH/dbAsLib.h */ -/* $Id$ */ -/* Author: Marty Kraimer Date: 02-23-94*/ -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ - -/* - * Modification Log: - * ----------------- - * .01 02-23-94 mrk Initial Implementation - */ - -#ifndef INCdbAsLibh -#define INCdbAsLibh -#include -#include - -typedef struct { - CALLBACK callback; - long status; -} ASDBCALLBACK; - -int asSetFilename(char *acf); -int asSetSubstitutions(char *substitutions); -int asInit(void); -int asInitAsyn(ASDBCALLBACK *pcallback); -int asDbGetAsl( void *paddr); -ASMEMBERPVT asDbGetMemberPvt( void *paddr); -int asdbdump( void); -int aspuag(char *uagname); -int asphag(char *hagname); -int asprules(char *asgname); -int aspmem(char *asgname,int clients); -void asCaStart(void); -void asCaStop(void); - -#endif /*INCdbAsLibh*/ diff --git a/src/include/asLib.h b/src/include/asLib.h deleted file mode 100644 index 5f7bfa04d..000000000 --- a/src/include/asLib.h +++ /dev/null @@ -1,192 +0,0 @@ -/* $Id$ */ -/* Author: Marty Kraimer Date: 09-27-93*/ -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ - -/* - * Modification Log: - * ----------------- - * .01 09-27-93 mrk Initial Implementation - */ -#ifndef INCasLibh -#define INCasLibh - -#include -#include -#include -#include -#include - -typedef struct asgMember *ASMEMBERPVT; -typedef struct asgClient *ASCLIENTPVT; -typedef int (*ASINPUTFUNCPTR)(char *buf,int max_size); -typedef enum{ - asClientCOAR /*Change of access rights*/ - /*For now this is all*/ -} asClientStatus; - -typedef void (*ASCLIENTCALLBACK) (ASCLIENTPVT,asClientStatus); -/* The following routines are macros with the following syntax -long asCheckGet(ASCLIENTPVT asClientPvt); -long asCheckPut(ASCLIENTPVT asClientPvt); -*/ -#define asCheckGet(asClientPvt)\ - (asActive ?\ - ((asClientPvt)->access>=asREAD ? TRUE : FALSE)\ - : TRUE) -#define asCheckPut(asClientPvt)\ - (asActive ?\ - ((asClientPvt)->access>=asWRITE ? TRUE : FALSE)\ - : TRUE) - -epicsShareFunc int epicsShareAPI asInit(void); -epicsShareFunc long epicsShareAPI asInitialize(ASINPUTFUNCPTR inputfunction); -epicsShareFunc long epicsShareAPI asInitFile(const char *filename,const char *substitutions); -epicsShareFunc long epicsShareAPI asInitFP(FILE *fp,const char *substitutions); -/*caller must provide permanent storage for asgName*/ -epicsShareFunc long epicsShareAPI asAddMember(ASMEMBERPVT *asMemberPvt,char *asgName); -epicsShareFunc long epicsShareAPI asRemoveMember(ASMEMBERPVT *asMemberPvt); -/*caller must provide permanent storage for newAsgName*/ -epicsShareFunc long epicsShareAPI asChangeGroup(ASMEMBERPVT *asMemberPvt,char *newAsgName); -epicsShareFunc void * epicsShareAPI asGetMemberPvt(ASMEMBERPVT asMemberPvt); -epicsShareFunc void epicsShareAPI asPutMemberPvt(ASMEMBERPVT asMemberPvt,void *userPvt); -/*client must provide permanent storage for user and host*/ -epicsShareFunc long epicsShareAPI asAddClient(ASCLIENTPVT *asClientPvt,ASMEMBERPVT asMemberPvt, - int asl,char *user,char *host); -/*client must provide permanent storage for user and host*/ -epicsShareFunc long epicsShareAPI asChangeClient(ASCLIENTPVT asClientPvt,int asl,char *user,char *host); -epicsShareFunc long epicsShareAPI asRemoveClient(ASCLIENTPVT *asClientPvt); -epicsShareFunc void * epicsShareAPI asGetClientPvt(ASCLIENTPVT asClientPvt); -epicsShareFunc void epicsShareAPI asPutClientPvt(ASCLIENTPVT asClientPvt,void *userPvt); -epicsShareFunc long epicsShareAPI asRegisterClientCallback(ASCLIENTPVT asClientPvt, - ASCLIENTCALLBACK pcallback); -epicsShareFunc long epicsShareAPI asComputeAllAsg(void); -/* following declared below after ASG is declared -epicsShareFunc long epicsShareAPI asComputeAsg(ASG *pasg); -*/ -epicsShareFunc long epicsShareAPI asCompute(ASCLIENTPVT asClientPvt); -epicsShareFunc int epicsShareAPI asDump(void (*memcallback)(ASMEMBERPVT), - void (*clientcallback)(ASCLIENTPVT),int verbose); -epicsShareFunc int epicsShareAPI asDumpUag(char *uagname); -epicsShareFunc int epicsShareAPI asDumpHag(char *hagname); -epicsShareFunc int epicsShareAPI asDumpRules(char *asgname); -epicsShareFunc int epicsShareAPI asDumpMem(char *asgname,void (*memcallback)(ASMEMBERPVT),int clients); -epicsShareFunc int epicsShareAPI asDumpHash(void); - -#define S_asLib_clientsExist (M_asLib| 1) /*Client Exists*/ -#define S_asLib_noUag (M_asLib| 2) /*User Access Group does not exist*/ -#define S_asLib_noHag (M_asLib| 3) /*Host Access Group does not exist*/ -#define S_asLib_noAccess (M_asLib| 4) /*access security: no access allowed*/ -#define S_asLib_noModify (M_asLib| 5) /*access security: no modification allowed*/ -#define S_asLib_badConfig (M_asLib| 6) /*access security: bad configuration file*/ -#define S_asLib_badCalc (M_asLib| 7) /*access security: bad calculation espression*/ -#define S_asLib_dupAsg (M_asLib| 8) /*Duplicate Access Security Group */ -#define S_asLib_InitFailed (M_asLib| 9) /*access security: Init failed*/ -#define S_asLib_asNotActive (M_asLib|10) /*access security is not active*/ -#define S_asLib_badMember (M_asLib|11) /*access security: bad ASMEMBERPVT*/ -#define S_asLib_badClient (M_asLib|12) /*access security: bad ASCLIENTPVT*/ -#define S_asLib_badAsg (M_asLib|13) /*access security: bad ASG*/ -#define S_asLib_noMemory (M_asLib|14) /*access security: no Memory */ - -/*Private declarations */ -#define ASMAXINP 12 -extern int asActive; -/* definition of access rights*/ -typedef enum{asNOACCESS,asREAD,asWRITE} asAccessRights; - -/*Base pointers for access security*/ -typedef struct asBase{ - ELLLIST uagList; - ELLLIST hagList; - ELLLIST asgList; - void *phash; -} ASBASE; -/*Defs for User Access Groups*/ -typedef struct{ - ELLNODE node; - char *user; -} UAGNAME; -typedef struct uag{ - ELLNODE node; - char *name; - ELLLIST list; /*list of UAGNAME*/ -} UAG; -/*Defs for Host Access Groups*/ -typedef struct{ - ELLNODE node; - char *host; -} HAGNAME; -typedef struct hag{ - ELLNODE node; - char *name; - ELLLIST list; /*list of HAGNAME*/ -} HAG; -/*Defs for Access SecurityGroups*/ -typedef struct { - ELLNODE node; - UAG *puag; -}ASGUAG; -typedef struct { - ELLNODE node; - HAG *phag; -}ASGHAG; -typedef struct{ - ELLNODE node; - asAccessRights access; - int level; - int inpUsed; /*mask for which inputs are used*/ - int result; /*Result of calc converted to TRUE/FALSE*/ - char *calc; - void *rpcl; - ELLLIST uagList; /*List of ASGUAG*/ - ELLLIST hagList; /*List of ASGHAG*/ -} ASGRULE; -typedef struct{ - ELLNODE node; - char *inp; - void *capvt; - struct asg *pasg; - int inpIndex; -}ASGINP; - -typedef struct asg{ - ELLNODE node; - char *name; - ELLLIST inpList; - ELLLIST ruleList; - ELLLIST memberList; - double *pavalue; /*pointer to array of input values*/ - int inpBad; /*mask for which inputs are bad*/ - int inpChanged; /*mask showing inputs that have changed*/ -} ASG; -typedef struct asgMember { - ELLNODE node; - ASG *pasg; - ELLLIST clientList; - char *asgName; - void *userPvt; -} ASGMEMBER; -typedef struct asgClient { - ELLNODE node; - ASGMEMBER *pasgMember; - char *user; - char *host; - void *userPvt; - ASCLIENTCALLBACK pcallback; - int level; - asAccessRights access; -} ASGCLIENT; - -epicsShareFunc long epicsShareAPI asComputeAsg(ASG *pasg); -/*following is "friend" function*/ -void * asCalloc(size_t nobj,size_t size); - -#endif /*INCasLibh*/ diff --git a/src/include/cadef.h b/src/include/cadef.h deleted file mode 100644 index db7d97629..000000000 --- a/src/include/cadef.h +++ /dev/null @@ -1,1184 +0,0 @@ -/************************************************************************/ -/* */ -/* L O S A L A M O S */ -/* Los Alamos National Laboratory */ -/* Los Alamos, New Mexico 87545 */ -/* */ -/* Copyright, 1986, The Regents of the University of California. */ -/* Author Jeffrey O. Hill */ -/* hill@atdiv.lanl.gov */ -/* 505 665 1831 */ -/* */ -/* */ -/* History */ -/* ------- */ -/* */ -/* Date Person Comments */ -/* ---- ------ -------- */ -/* 08xx87 joh Init Release */ -/* 031290 joh Added db_access auto include */ -/* 031991 joh fixed SEVCHK dbl function call when status */ -/* returned indicates unsuccessful completion */ -/* 060591 joh delinting */ -/* 091691 joh exported channel state */ -/* 060392 joh added ca host name MACRO */ -/* 072792 joh added ca_test_io() decl */ -/* 072792 joh changed compile time flag from VAXC to STDC */ -/* so the function prototypes can be used by */ -/* other compilers */ -/* 072892 joh added function prototype for host name function */ -/* 101692 joh use unique name for var in SEVCHK to avoid */ -/* clashing with application */ -/* 120492 joh turn off VAXC ca_real reduction from double to */ -/* float. This was originally provided to ease */ -/* integration of the VAX FORTRAN based pt_shell */ -/* code which will in all likelyhood no longer */ -/* be used. */ -/* 120992 joh converted to dll list routines */ -/* 061193 joh added missing prototype for ca_clear_channel() */ -/* and others */ -/* 080593 rcz converted to ell list routines */ -/* 090893 joh added client id to channel in use block */ -/* 010694 joh added put callback rtn and synch group rtns */ -/* 090194 joh support C++ */ -/* 101194 joh merged NT changes */ -/* */ -/*_begin */ -/************************************************************************/ -/* */ -/* Title: GTA high level channel access routines C */ -/* function prototypes */ -/* File: cadef.h */ -/* Environment: Architecture independent */ -/* ( Current ports ) */ -/* VAXC, VMS V4.6 */ -/* SUNC, BSD UNIX V4.3 */ -/* SUNC, vxWorks */ -/* */ -/* */ -/* Purpose */ -/* ------- */ -/* */ -/* GTACS universal remote access library function prototypes. */ -/* ( C default argument passing mechanisms ) */ -/* */ -/* Special comments */ -/* ------- -------- */ -/* "ca_" is the standard prefix for the "channel access" library */ -/* function names. */ -/* */ -/* */ -/************************************************************************/ -/*_end */ - -#ifndef INCLcadefh -#define INCLcadefh - -/* - * done in two ifdef steps so that we will remain compatible with - * traditional C - */ -#ifdef __cplusplus -extern "C" { -#define CAC_ANSI_FUNC_PROTO -#endif -#ifdef __STDC__ -#define CAC_ANSI_FUNC_PROTO -#endif - -#include "shareLib.h" - - -#ifndef HDRVERSIONID -# define HDRVERSIONID(NAME,VERS) -#endif /*HDRVERSIONID*/ - -HDRVERSIONID(cadefh, "@(#) $Id$") - -/* - * auto include of all stuff that cadef.h uses - */ - -/* - * use two ifdef's for trad C compatibility - */ -#ifndef CA_DONT_INCLUDE_STDARGH -#ifdef CAC_ANSI_FUNC_PROTO -#include -#endif -#endif - -#ifndef INCLdb_accessh -#include "db_access.h" -#endif /* INCLdb_accessh */ - -#ifndef INCLcaerrh -#include "caerr.h" -#endif /* INCLcaerrh */ - -#ifndef INCLcaeventmaskh -#include "caeventmask.h" -#endif /* INCLcaeventmaskh */ - -#ifndef INCLellLibh -#include "ellLib.h" -#endif /* INCLellLibh */ - -/* - * - * NOTE: the channel in use fields type, count, name, and - * host name are available to applications. However it is - * recommended that the following MACROS be used to access them. - * - */ -#define ca_field_type(CHID) (ca_get_field_type(CHID)) -#define ca_element_count(CHID) (ca_get_element_count(CHID)) -#define ca_name(CHID) ((READONLY char *)((CHID)+1)) -/* - * the odd cast here removes const (and allows past practice - * of using ca_puser(CHID) as an lvalue. - */ -#define ca_puser(CHID) (*(void **)&((CHID)->puser)) -/* - * here is the preferred way to load the puser ptr associated with - * channel (the cast removes const) - */ -#define ca_set_puser(CHID,PUSER) ((CHID)->puser=(READONLY void *)(PUSER)) -#define ca_host_name(CHID) ca_host_name_function(CHID) -#define ca_read_access(CHID) ((CHID)->ar.read_access) -#define ca_write_access(CHID) ((CHID)->ar.write_access) - -/* - * cs_ - `channel state' - * - * cs_never_conn valid chid, IOC not found - * cs_prev_conn valid chid, IOC was found, but unavailable - * cs_conn valid chid, IOC was found, still available - * cs_closed invalid chid - */ -enum channel_state{cs_never_conn, cs_prev_conn, cs_conn, cs_closed}; -#define ca_state(CHID) ((CHID)->state) - -typedef struct ca_access_rights{ - unsigned read_access:1; - unsigned write_access:1; -}caar; - - -/* Format for the arguments to user connection handlers */ -struct channel_in_use; -struct connection_handler_args{ - struct channel_in_use *chid; /* Channel id */ - long op; /* External codes for CA op */ -}; - -#ifdef CAC_ANSI_FUNC_PROTO -typedef void caCh(struct connection_handler_args args); -#else /*CAC_ANSI_FUNC_PROTO*/ -typedef void caCh(); -#endif /*CAC_ANSI_FUNC_PROTO*/ - -/* Format for the arguments to user access rights handlers */ -struct access_rights_handler_args{ - struct channel_in_use *chid; /* Channel id */ - caar ar; /* New access rights state */ -}; - -#ifdef CAC_ANSI_FUNC_PROTO -typedef void caArh(struct access_rights_handler_args args); -#else /*CAC_ANSI_FUNC_PROTO*/ -typedef void caArh(); -#endif /*CAC_ANSI_FUNC_PROTO*/ - -/* - * The fields in this structure may change or even vanish in the future. - * Please use the macros above to access the information in this structure. - */ -struct channel_in_use{ - ELLNODE node; /* list ptrs */ - short privType; /* database field type */ -#define TYPENOTCONN (-1) /* the type when disconnected */ - unsigned short privCount; /* array element count */ - union{ - unsigned sid; /* server id */ - struct dbAddr *paddr; /* database address */ - } id; - READONLY void *puser; /* user available area */ - short state; /* connected/ disconnected etc */ - unsigned short retrySeqNo; /* search retry seq number */ - caar ar; /* access rights */ - - - caCh *pConnFunc; - caArh *pAccessRightsFunc; - ELLLIST eventq; - unsigned cid; /* client id */ - unsigned retry; /* search retry number */ - void *piiu; /* private ioc in use block */ -#ifdef vxWorks - void *ppn; /* ptr to optional put notify blk */ -#endif /* vxWorks */ - unsigned claimPending:1; /* claim msg was sent if T */ - /* - * channel name stored directly after this structure in a - * null terminated string. - */ -}; - -typedef struct channel_in_use *chid; -typedef long chtype; -typedef struct pending_event *evid; -typedef double ca_real; - -/* The conversion routine to call for each type */ -#define VALID_TYPE(TYPE) (((unsigned short)TYPE)<=LAST_BUFFER_TYPE) - - -/* - * Arguments passed to event handlers and get/put call back handlers. - * - * The status field below is the CA ECA_XXX status of the requested - * operation which is saved from when the operation was attempted in the - * server and copied back to the clients call back routine. - * If the status is not ECA_NORMAL then the dbr pointer will be NULL - * and the requested operation can not be assumed to be successful. - */ -typedef struct event_handler_args{ - void *usr; /* User argument supplied when event added */ - struct channel_in_use - *chid; /* Channel id */ - long type; /* the type of the value returned */ - long count; /* the element count of the item returned */ - READONLY void *dbr; /* Pointer to the value returned */ - int status; /* ECA_XXX Status of the requested op from server */ -}evargs; - -struct pending_event{ - ELLNODE node; /* list ptrs */ -#ifdef CAC_ANSI_FUNC_PROTO - void (*usr_func)(struct event_handler_args args); -#else /*CAC_ANSI_FUNC_PROTO*/ - void (*usr_func)(); -#endif /*CAC_ANSI_FUNC_PROTO*/ - READONLY void *usr_arg; - chid chan; - chtype type; /* requested type for local CA */ - unsigned long count; /* requested count for local CA */ - /* - * the following provide for reissuing a - * disconnected monitor - */ - ca_real p_delta; - ca_real n_delta; - ca_real timeout; - unsigned id; - unsigned short mask; -}; - -epicsShareFunc void epicsShareAPI ca_test_event - ( -#ifdef CAC_ANSI_FUNC_PROTO - struct event_handler_args -#endif /*CAC_ANSI_FUNC_PROTO*/ - ); - -/* Format for the arguments to user exception handlers */ -struct exception_handler_args{ - void *usr; /* User argument supplied when event added */ - struct channel_in_use - *chid; /* Channel id (may be NULL) */ - long type; /* Requested type for the operation */ - long count; /* Requested count for the operation */ - void *addr; /* User's address to write results of CA_OP_GET */ - long stat; /* Channel access std status code */ - long op; /* External codes for channel access operations */ - READONLY char *ctx; /* A character string containing context info */ - READONLY char *pFile; /* source file name (may be NULL) */ - unsigned lineNo; /* source file line number */ -}; - -typedef unsigned CA_SYNC_GID; - -/* - * - * External OP codes for CA operations - * - */ -#define CA_OP_GET 0 -#define CA_OP_PUT 1 -#define CA_OP_SEARCH 2 -#define CA_OP_ADD_EVENT 3 -#define CA_OP_CLEAR_EVENT 4 -#define CA_OP_OTHER 5 -#define CA_OP_CONN_UP 6 -#define CA_OP_CONN_DOWN 7 - -/* - * provides efficient test and display of channel access errors - */ -#define SEVCHK(CA_ERROR_CODE, MESSAGE_STRING) \ -{ \ - int ca_unique_status_name = (CA_ERROR_CODE); \ - if(!(ca_unique_status_name & CA_M_SUCCESS)) \ - ca_signal_with_file_and_lineno( \ - ca_unique_status_name, \ - (MESSAGE_STRING), \ - __FILE__, \ - __LINE__); \ -} - -#ifdef CAC_ANSI_FUNC_PROTO - -epicsShareFunc short epicsShareAPI ca_get_field_type (chid chan); -epicsShareFunc unsigned short epicsShareAPI ca_get_element_count (chid chan); - -/************************************************************************/ -/* Perform Library Initialization */ -/* */ -/* Must be called once before calling any of the other routines */ -/************************************************************************/ -epicsShareFunc int epicsShareAPI ca_task_initialize (void); - - -/************************************************************************/ -/* Remove CA facility from your task */ -/* */ -/* Normally called automatically at task exit */ -/************************************************************************/ -epicsShareFunc int epicsShareAPI ca_task_exit (void); - -/************************************************************************ - * anachronistic entry points * - * **** Fetching a value while searching no longer supported**** * - ************************************************************************/ -#define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\ -ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) - -#define ca_array_build(NAME,XXXXX, ZZZZZZ, CHIDPTR,YYYYY)\ -ca_build_and_connect(NAME, XXXXX, ZZZZZZ, CHIDPTR, YYYYY, 0, 0) - - -/************************************************************************/ -/* Return a channel identification for the supplied channel name */ -/* (and attempt to create a virtual circuit) */ -/************************************************************************/ - -/* - * ca_search() - * - * a preferred search request API - * - * pChanName R channel name string - * pChanID RW channel id written here - */ -#define ca_search(pChanName, pChanID)\ -ca_search_and_connect(pChanName, pChanID, 0, 0) - - -/* - * ca_search_and_connect() - * - * a preferred search request API - * - * pChanName R channel name string - * pChanID RW channel id written here - * pFunc R address of connection call-back function - * pArg R placed in the channel's puser field - * (fetched later by ca_puser(CHID)) - * (passed as void * arg to (*pFunc)() above) - */ -epicsShareFunc int epicsShareAPI ca_search_and_connect -( - READONLY char *pChanName, - chid *pChanID, - void (*pFunc)(struct connection_handler_args), - READONLY void *pArg -); - -/* - * anachronistic entry point - * **** Fetching a value while searching no longer supported **** - * - * pChanName R channel name string - * pChanID RW channel id written here - * pFunc R address of connection call-back function - * pArg R placed in the channel's puser field - * (fetched later by ca_puser(CHID)) - * (passed as void * arg to (*pFunc)() above) - */ -epicsShareFunc int epicsShareAPI ca_build_and_connect -( - READONLY char *pChanName, - chtype, /* pass TYPENOTCONN */ - unsigned long, /* pass 0 */ - chid *pChanID, - void *, /* pass NULL */ - void (*pFunc)(struct connection_handler_args), - void *pArg -); - -/* - * ca_change_connection_event() - * - * chan R channel identifier - * pfunc R address of connection call-back function - */ -epicsShareFunc int epicsShareAPI ca_change_connection_event -( - chid chan, - void (*pfunc)(struct connection_handler_args) -); - -/* - * ca_replace_access_rights_event () - * - * chan R channel identifier - * pfunc R address of access rights call-back function - */ -epicsShareFunc int epicsShareAPI ca_replace_access_rights_event( - chid chan, - void (*pfunc)(struct access_rights_handler_args) -); - -/* - * ca_add_exception_event () - * - * replace the default exception handler - * - * pfunc R address of exception call-back function - * pArg R copy of this pointer passed to exception - * call-back function - */ -epicsShareFunc int epicsShareAPI ca_add_exception_event -( - void (*pfunc) (struct exception_handler_args), - READONLY void *pArg -); - -/* - * ca_clear_channel() - * - deallocate resources reserved for a channel - * - * chanId R channel ID - */ -epicsShareFunc int epicsShareAPI ca_clear_channel -( - chid chanId -); - -/************************************************************************/ -/* Write a value to a channel */ -/************************************************************************/ -/* - * ca_bput() - * - * WARNING: this copies the new value from a string (dbr_string_t) - * (and not as an integer) - * - * chan R channel identifier - * pValue R new channel value string copied from this location - */ -#define ca_bput(chan, pValue) \ -ca_array_put(DBR_STRING, 1u, chan, (READONLY dbr_string_t *) (pValue)) - -/* - * ca_rput() - * - * WARNING: this copies the new value from a dbr_float_t - * - * chan R channel identifier - * pValue R new channel value copied from this location - */ -#define ca_rput(chan,pValue) \ -ca_array_put(DBR_FLOAT, 1u, chan, (READONLY dbr_float_t *) pValue) - -/* - * ca_put() - * - * type R data type from db_access.h - * chan R channel identifier - * pValue R new channel value copied from this location - */ -#define ca_put(type, chan, pValue) ca_array_put(type, 1u, chan, pValue) - -/* - * ca_array_put() - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue R new channel value copied from this location - */ -epicsShareFunc int epicsShareAPI ca_array_put -( - chtype type, - unsigned long count, - chid chanId, - READONLY void *pValue -); - -/* - * ca_array_put_callback() - * - * This routine functions identically to the original ca put request - * with the addition of a callback to the user supplied function - * after recod processing completes in the IOC. The arguments - * to the user supplied callback function are declared in - * the structure event_handler_args and include the pointer - * sized user argument supplied when ca_array_put_callback() is called. - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue R new channel value copied from this location - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -epicsShareFunc int epicsShareAPI ca_array_put_callback -( - chtype type, - unsigned long count, - chid chanId, - READONLY void *pValue, - void (*pFunc)(struct event_handler_args), - READONLY void *pArg -); - -#define ca_put_callback(type, chan, pValue, pFunc, pArg) \ - ca_array_put_callback(type, 1u, chan, pValue, pFunc, pArg) - -/************************************************************************/ -/* Read a value from a channel */ -/************************************************************************/ - -/* - * ca_bget() - * - * WARNING: this copies the new value into a string (dbr_string_t) - * (and not into an integer) - * - * chan R channel identifier - * pValue W channel value copied to this location - */ -#define ca_bget(chan, pValue) \ -ca_array_get(DBR_STRING, 1u, chan, (dbr_string_t *)(pValue)) - -/* - * ca_rget() - * - * WARNING: this copies the new value into a 32 bit float (dbr_float_t) - * - * chan R channel identifier - * pValue W channel value copied to this location - */ -#define ca_rget(chan, pValue) \ -ca_array_get(DBR_FLOAT, 1u, chan, (dbr_float_t *)(pValue)) - -/* - * ca_rget() - * - * type R data type from db_access.h - * chan R channel identifier - * pValue W channel value copied to this location - */ -#define ca_get(type, chan, pValue) ca_array_get(type, 1u, chan, pValue) - -/* - * ca_array_get() - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue W channel value copied to this location - */ -epicsShareFunc int epicsShareAPI ca_array_get -( - chtype type, - unsigned long count, - chid chanId, - void *pValue -); - -/************************************************************************/ -/* Read a value from a channel and run a callback when the value */ -/* returns */ -/* */ -/* */ -/************************************************************************/ -/* - * ca_bget_callback() - * - * WARNING: this returns the new value as a string (dbr_string_t) - * (and not as an integer) - * - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -#define ca_bget_callback(chan, pFunc, pArg)\ -ca_array_get_callback(DBR_STRING, 1u, chan, pFunc, pArg) - -/* - * ca_rget_callback() - * - * WARNING: this returns the new value as a float (dbr_float_t) - * - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -#define ca_rget_callback(chan, pFunc, pArg)\ -ca_array_get_callback(DBR_FLOAT, 1u, chan, pFunc, pArg) - -/* - * ca_get_callback() - * - * type R data type from db_access.h - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -#define ca_get_callback(type, chan, pFunc, pArg)\ -ca_array_get_callback(type, 1u, chan, pFunc, pArg) - -/* - * ca_array_get_callback() - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -epicsShareFunc int epicsShareAPI ca_array_get_callback -( - chtype type, - unsigned long count, - chid chanId, - void (*pFunc)(struct event_handler_args), - READONLY void *pArg -); - -/************************************************************************/ -/* Specify a function to be executed whenever significant changes */ -/* occur to a channel. */ -/* NOTES: */ -/* 1) Evid may be omited by passing a NULL pointer */ -/* */ -/* 2) An array count of zero specifies the native db count */ -/* */ -/************************************************************************/ - -/* - * ca_add_event () - * - * assumes "delta" info comes from the database or defaults - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - * pEventID W event id written at specified address - */ -#define ca_add_event(type,chan,pFunc,pArg,pEventID)\ -ca_add_array_event(type,1u,chan,pFunc,pArg,0.0,0.0,0.0,pEventID) - - -/* Sets both P_DELTA and M_DELTA below to argument DELTA */ -#define ca_add_delta_event(TYPE,CHID,ENTRY,ARG,DELTA,EVID)\ - ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,DELTA,DELTA,0.0,EVID) - -#define ca_add_general_event(TYPE,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ -ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID) - -#define ca_add_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ -ca_add_masked_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID, DBE_VALUE | DBE_ALARM) - -/* - * ca_add_masked_array_event () - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - * p_delta R not currently used (set to 0.0) - * n_delta R not currently used (set to 0.0) - * timeout R not currently used (set to 0.0) - * pEventID W event id written at specified address - * mask R event mask - one of {DBE_VALUE, DBE_ALARM, DBE_LOG} - */ -epicsShareFunc int epicsShareAPI ca_add_masked_array_event -( - chtype type, - unsigned long count, - chid chanId, - void (*pFunc)(struct event_handler_args), - READONLY void *pArg, - ca_real p_delta, - ca_real n_delta, - ca_real timeout, - evid *pEventID, - long mask -); - -/************************************************************************/ -/* Remove a function from a list of those specified to run */ -/* whenever significant changes occur to a channel */ -/* */ -/************************************************************************/ -/* - * ca_clear_event() - * - * eventID R event id - */ -epicsShareFunc int epicsShareAPI ca_clear_event -( - evid eventID -); - - -/************************************************************************/ -/* */ -/* Requested data is not necessarily stable prior to */ -/* return from called subroutine. Call ca_pend_io() */ -/* to guarantee that requested data is stable. Call the routine */ -/* ca_flush_io() to force all outstanding subroutine calls to be */ -/* sent out over the network. Significant increases in */ -/* performance have been measured when batching several remote */ -/* subroutine calls together into one message. Additional */ -/* improvements can be obtained by performing local processing */ -/* in parallel with outstanding remote processing. */ -/* */ -/* FLOW OF TYPICAL APPLICATION */ -/* */ -/* search() ! Obtain Channel ids */ -/* . ! " */ -/* */ -/* get() ! several requests for remote info */ -/* get() ! " */ -/* add_event() ! " */ -/* get() ! " */ -/* . */ -/* . */ -/* . */ -/* flush_io() ! send get requests */ -/* ! optional parallel processing */ -/* . ! " */ -/* . ! " */ -/* pend_io() ! wait for replies from get requests */ -/* . ! access to requested data */ -/* . ! " */ -/* pend_event() ! wait for requested events */ -/* */ -/************************************************************************/ - -/************************************************************************/ -/* This routine pends waiting for channel events and calls the */ -/* functions specified with add_event when events occur. If the */ -/* timeout is specified as 0 an infinite timeout is assumed. */ -/* if the argument early is specified TRUE then CA_NORMAL is */ -/* returned when outstanding queries complete. Otherwise if the */ -/* argument early is FALSE the routine does not return until the */ -/* entire delay specified by the timeout argument has expired. */ -/* ca_flush_io() is called by this routine. If the argument */ -/* early is TRUE then ca_pend() will return immediately without */ -/* processing outstanding CA labor if no queries are outstanding */ -/************************************************************************/ -#define ca_poll() ca_pend((1e-12), 0/*FALSE*/) -#define ca_pend_event(TIMEOUT) ca_pend((TIMEOUT), 0/*FALSE*/) -#define ca_pend_io(TIMEOUT) ca_pend((TIMEOUT), 1/*TRUE*/) - -/* - * ca_pend() - * - * timeOut R delay in seconds - * early R T: return early if all get requests (or search - * requests with null connection handler pointer - * have completed) - * F: wait for the entire delay to expire - */ -epicsShareFunc int epicsShareAPI ca_pend -( - ca_real timeOut, - int early -); - -/* - * ca_test_io() - * - * returns TRUE when get requests (or search requests with null - * connection handler pointer) are outstanding - */ -epicsShareFunc int epicsShareAPI ca_test_io (void); - -/************************************************************************/ -/* Send out all outstanding messages in the send queue */ -/************************************************************************/ -/* - * ca_flush_io() - */ -epicsShareFunc int epicsShareAPI ca_flush_io (void); - - -/* - * ca_signal() - * - * errorCode R status returned from channel access function - * pCtxStr R context string included with error print out - */ -epicsShareFunc void epicsShareAPI ca_signal -( - long errorCode, - READONLY char *pCtxStr -); - -/* - * ca_signal_with_file_and_lineno() - * errorCode R status returned from channel access function - * pCtxStr R context string included with error print out - * pFileStr R file name string included with error print out - * lineNo R line number included with error print out - * - */ -epicsShareFunc void epicsShareAPI ca_signal_with_file_and_lineno -( - long errorCode, - READONLY char *pCtxStr, - READONLY char *pFileStr, - int lineNo -); - -/* - * ca_host_name_function() - * - * channel R channel identifier - */ -epicsShareFunc READONLY char * epicsShareAPI ca_host_name_function ( chid channel); - -/* - * CA_ADD_FD_REGISTRATION - * - * call their function with their argument whenever - * a new fd is added or removed - * (for use with a manager of the select system call under UNIX) - * - * if (opened) then fd was created - * if (!opened) then fd was deleted - * - */ -typedef void CAFDHANDLER(void *parg, int fd, int opened); - -/* - * ca_add_fd_registration() - * - * pHandler R pointer to function which is to be called - * when an fd is created or deleted - * pArg R argument passed to above function - */ -epicsShareFunc int epicsShareAPI ca_add_fd_registration -( - CAFDHANDLER *pHandler, - READONLY void *pArg -); - -/* - * ca_channel_status() - * - * tid R task id - */ -#ifdef vxWorks -epicsShareFunc int epicsShareAPI ca_channel_status( int tid); -#endif - -/* - * ca_import () - * - * tid R task id - */ -#ifdef vxWorks -int ca_import(int tid); -#endif /* vxWorks */ - -/* - * ca_import_cancel () - * - * tid R task id - */ -#ifdef vxWorks -int ca_import_cancel(int tid); -#endif /* vxWorks */ - -/* - * CA synch groups - * - * This facility will allow the programmer to create - * any number of synchronization groups. The programmer might then - * interleave IO requests within any of the groups. Once The - * IO operations are initiated then the programmer is free to - * block for IO completion within any one of the groups as needed. - */ - -/* - * ca_sg_create() - * - * create a sync group - * - * pgid W pointer to sync group id that will be written - */ -epicsShareFunc int epicsShareAPI ca_sg_create( CA_SYNC_GID * pgid); - -/* - * ca_sg_delete() - * - * delete a sync group - * - * gid R sync group id - */ -epicsShareFunc int epicsShareAPI ca_sg_delete(READONLY CA_SYNC_GID gid); - -/* - * ca_sg_block() - * - * block for IO performed within a sync group to complete - * - * gid R sync group id - * timeout R wait for this duration prior to timing out - * and returning ECA_TIMEOUT - */ -epicsShareFunc int epicsShareAPI ca_sg_block(READONLY CA_SYNC_GID gid, ca_real timeout); - -/* - * ca_sg_test() - * - * test for sync group IO operations in progress - * - * gid R sync group id - * - * returns one of ECA_BADSYNCGRP, ECA_IOINPROGRESS, ECA_IODONE - */ -epicsShareFunc int epicsShareAPI ca_sg_test(READONLY CA_SYNC_GID gid); - -/* - * ca_sg_reset - * - * gid R sync group id - */ -epicsShareFunc int epicsShareAPI ca_sg_reset(READONLY CA_SYNC_GID gid); - -/* - * ca_sg_array_get() - * - * initiate a get within a sync group - * (essentially a ca_array_get() with a sync group specified) - * - * gid R sync group id - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue W channel value copied to this location - */ -epicsShareFunc int epicsShareAPI ca_sg_array_get -( - READONLY CA_SYNC_GID gid, - chtype type, /* TYPE R channel type */ - unsigned long count, - chid chan, - void *pValue -); - -#define ca_sg_get(gid, type, chan, pValue) \ -ca_sg_array_get(gid, type, 1u, chan, pValue) - -/* - * ca_sg_array_put() - * - * initiate a put within a sync group - * (essentially a ca_array_put() with a sync group specified) - * - * gid R sync group id - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue R new channel value copied from this location - */ -epicsShareFunc int epicsShareAPI ca_sg_array_put -( - READONLY CA_SYNC_GID gid, - chtype type, - unsigned long count, - chid chan, - READONLY void *pValue -); - -#define ca_sg_put(gid, type, chan, pValue) \ -ca_sg_array_put(gid, type, 1u, chan, pValue) - -/* - * ca_sg_stat() - * - * print status of a sync group - * - * gid R sync group id - */ -epicsShareFunc int epicsShareAPI ca_sg_stat(READONLY CA_SYNC_GID gid); - -/* - * ca_modify_user_name() - * - * Modify or override the default - * client user name. - * - * pUserName R new user name string copied from this location - */ -epicsShareFunc int epicsShareAPI ca_modify_user_name(READONLY char *pUserName); - -/* - * CA_MODIFY_HOST_NAME() - * - * Modify or override the default - * client host name. - * - * pHostName R new host name string copied from this location - */ -epicsShareFunc int epicsShareAPI ca_modify_host_name(READONLY char *pHostName); - -/* - * ca_v42_ok() - * - * Put call back is available if the CA server is on version is 4.2 - * or higher. - * - * chan R channel identifier - * - * (returns true or false) - */ -epicsShareFunc int epicsShareAPI ca_v42_ok(chid chan); - -/* - * ca_version() - * - * returns the CA version string - */ -epicsShareFunc READONLY char * epicsShareAPI ca_version(void); - -/* - * ca_replace_printf_handler () - * - * for apps that want to change where ca formatted - * text output goes - * - * use two ifdef's for trad C compatibility - * - * ca_printf_func R pointer to new function called when - * CA prints an error message - */ -#ifndef CA_DONT_INCLUDE_STDARGH -epicsShareFunc int epicsShareAPI ca_replace_printf_handler ( - int (*ca_printf_func)(READONLY char *pformat, va_list args) -); -#endif /*CA_DONT_INCLUDE_STDARGH*/ - -/* - * ca_get_ioc_connection_count() - * - * returns the number of IOC's that CA is connected to - * (for testing purposes only) - */ -epicsShareFunc unsigned epicsShareAPI ca_get_ioc_connection_count (); - -#else /* CAC_ANSI_FUNC_PROTO */ -epicsShareFunc short epicsShareAPI ca_get_field_type (); -epicsShareFunc unsigned short epicsShareAPI ca_get_element_count (); -epicsShareFunc int epicsShareAPI ca_task_initialize (); -epicsShareFunc int epicsShareAPI ca_task_exit (); -epicsShareFunc int epicsShareAPI ca_search_and_connect (); -epicsShareFunc int epicsShareAPI ca_build_and_connect (); -epicsShareFunc int epicsShareAPI ca_change_connection_event (); -epicsShareFunc int epicsShareAPI ca_replace_access_rights_event (); -epicsShareFunc int epicsShareAPI ca_add_exception_event (); -epicsShareFunc int epicsShareAPI ca_clear_channel (); -epicsShareFunc int epicsShareAPI ca_array_put (); -epicsShareFunc int epicsShareAPI ca_array_put_callback (); -epicsShareFunc int epicsShareAPI ca_array_get (); -epicsShareFunc int epicsShareAPI ca_array_get_callback (); -epicsShareFunc int epicsShareAPI ca_add_masked_array_event (); -epicsShareFunc int epicsShareAPI ca_clear_event (); -epicsShareFunc int epicsShareAPI ca_pend (); -epicsShareFunc int epicsShareAPI ca_test_io (); -epicsShareFunc int epicsShareAPI ca_flush_io (); -epicsShareFunc void epicsShareAPI ca_signal (); -epicsShareFunc void epicsShareAPI ca_signal_with_file_and_lineno (); -epicsShareFunc char * epicsShareAPI ca_host_name_function (); -typedef void CAFDHANDLER(); -epicsShareFunc int epicsShareAPI ca_add_fd_registration(); -epicsShareFunc int epicsShareAPI ca_replace_printf_handler (); -epicsShareFunc int epicsShareAPI ca_sg_create(); -epicsShareFunc int epicsShareAPI ca_sg_delete(); -epicsShareFunc int epicsShareAPI ca_sg_block(); -epicsShareFunc int epicsShareAPI ca_sg_test(); -epicsShareFunc int epicsShareAPI ca_sg_reset(); -epicsShareFunc int epicsShareAPI ca_sg_array_get(); -epicsShareFunc int epicsShareAPI ca_sg_array_put(); -epicsShareFunc int epicsShareAPI ca_sg_stat(); -epicsShareFunc int epicsShareAPI ca_modify_user_name(); -epicsShareFunc int epicsShareAPI ca_modify_host_name(); -epicsShareFunc int epicsShareAPI ca_v42_ok(); -epicsShareFunc char * epicsShareAPI ca_version(); -#define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\ - ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) -#define ca_array_build(NAME,XXXXX, ZZZZZZ, CHIDPTR,YYYYY)\ - ca_build_and_connect(NAME, XXXXX, ZZZZZZ, CHIDPTR, YYYYY, 0, 0) -#define ca_search(pChanName, pChanID)\ - ca_search_and_connect(pChanName, pChanID, 0, 0) -#define ca_bput(chan, pValue) \ - ca_array_put(DBR_STRING, 1, chan, (READONLY dbr_string_t *) (pValue)) -#define ca_rput(chan,pValue) \ - ca_array_put(DBR_FLOAT, 1, chan, (READONLY dbr_float_t *) pValue) -#define ca_put(type, chan, pValue) ca_array_put(type, 1, chan, pValue) -#define ca_bget(chan, pValue) \ - ca_array_get(DBR_STRING, 1, chan, (dbr_string_t *)(pValue)) -#define ca_rget(chan, pValue) \ - ca_array_get(DBR_FLOAT, 1, chan, (dbr_float_t *)(pValue)) -#define ca_get(type, chan, pValue) ca_array_get(type, 1, chan, pValue) -#define ca_bget_callback(chan, pFunc, pArg)\ - ca_array_get_callback(DBR_STRING, 1, chan, pFunc, pArg) -#define ca_rget_callback(chan, pFunc, pArg)\ - ca_array_get_callback(DBR_FLOAT, 1, chan, pFunc, pArg) -#define ca_get_callback(type, chan, pFunc, pArg)\ - ca_array_get_callback(type, 1, chan, pFunc, pArg) -#define ca_put_callback(type, chan, pValue, pFunc, pArg) \ - ca_array_put_callback(type, 1u, chan, pValue, pFunc, pArg) -#define ca_add_event(type,chan,pFunc,pArg,pEventID)\ - ca_add_array_event(type,1,chan,pFunc,pArg,0.0,0.0,0.0,pEventID) -#define ca_add_delta_event(TYPE,CHID,ENTRY,ARG,DELTA,EVID)\ - ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,DELTA,DELTA,0.0,EVID) -#define ca_add_general_event(TYPE,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ - ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID) -#define ca_add_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ -ca_add_masked_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID, DBE_VALUE | DBE_ALARM) -#define ca_poll() ca_pend((1e-12), 0/*FALSE*/) -#define ca_pend_event(TIMEOUT) ca_pend((TIMEOUT), 0/*FALSE*/) -#define ca_pend_io(TIMEOUT) ca_pend((TIMEOUT), 1/*TRUE*/) -#define ca_sg_get(gid, type, chan, pValue) \ -ca_sg_array_get(gid, type, 1u, chan, pValue) -#define ca_sg_put(gid, type, chan, pValue) \ -ca_sg_array_put(gid, type, 1u, chan, pValue) - -#ifdef vxWorks - epicsShareFunc int epicsShareAPI ca_channel_status() - epicsShareFunc int epicsShareAPI ca_import(); - epicsShareFunc int epicsShareAPI ca_import_cancel(); -#endif - -#endif /* CAC_ANSI_FUNC_PROTO */ - -#ifdef __cplusplus -} -#endif - -/* - * no additions below this endif - */ -#endif /* INCLcadefh */ diff --git a/src/include/caerr.h b/src/include/caerr.h deleted file mode 100644 index 19b29fee1..000000000 --- a/src/include/caerr.h +++ /dev/null @@ -1,235 +0,0 @@ -/************************************************************************/ -/* */ -/* L O S A L A M O S */ -/* Los Alamos National Laboratory */ -/* Los Alamos, New Mexico 87545 */ -/* */ -/* Copyright, 1986, The Regents of the University of California. */ -/* */ -/* Author: Jeffrey O. Hill */ -/* */ -/* History */ -/* ------- */ -/* */ -/* Date Programmer Comments */ -/* ---- ---------- -------- */ -/* 08--87 joh Init Release */ -/* 031290 joh Changed __CAERR__ to INCLcaerrh */ -/* 102990 joh added readonly for VAXC share image */ -/* 032092 joh added ECA_BADMASK */ -/* 072792 joh added ECA_IODONE & ECA_IOINPROGESS */ -/* 102992 joh changed wording on the no vx fp message */ -/* 011494 joh Added ECA_BADSYNCGRP */ -/* 021194 joh Added ECA_PUTCBINPROG */ -/* */ -/*_begin */ -/************************************************************************/ -/* */ -/* Name: */ -/* Title: */ -/* File: */ -/* Environment: VMS, UNIX, VRTX */ -/* Equipment: VAX, SUN, VME */ -/* */ -/* */ -/* Purpose */ -/* ------- */ -/* */ -/* CA error message declaration include file */ -/* */ -/* */ -/* Special comments */ -/* ------- -------- */ -/* */ -/************************************************************************/ -/*_end */ - -#ifndef INCLcaerrh -#define INCLcaerrh - -#include "shareLib.h" -#include "epicsTypes.h" - -#ifndef HDRVERSIONID -# define HDRVERSIONID(NAME,VERS) -#endif /*HDRVERSIONID*/ - -HDRVERSIONID(caerrh, "@(#) $Id$") - -/* CA Status Code Definitions */ - -#define CA_K_INFO 3 /* successful */ -#define CA_K_ERROR 2 /* failed- continue */ -#define CA_K_SUCCESS 1 /* successful */ -#define CA_K_WARNING 0 /* unsuccessful */ -#define CA_K_SEVERE 4 /* failed- quit */ -#define CA_K_FATAL CA_K_ERROR | CA_K_SEVERE - -#define CA_M_MSG_NO 0x0000FFF8 -#define CA_M_SEVERITY 0x00000007 -#define CA_M_LEVEL 0x00000003 -#define CA_M_SUCCESS 0x00000001 -#define CA_M_ERROR 0x00000002 -#define CA_M_SEVERE 0x00000004 - -#define CA_S_MSG_NO 0x0D -#define CA_S_SEVERITY 0x03 - -#define CA_V_MSG_NO 0x03 -#define CA_V_SEVERITY 0x00 -#define CA_V_SUCCESS 0x00 - -/* Define MACROS to extract/insert individual fields from a status value */ - -#define CA_EXTRACT_MSG_NO(code)\ -( ( (code) & CA_M_MSG_NO ) >> CA_V_MSG_NO ) -#define CA_EXTRACT_SEVERITY(code)\ -( ( (code) & CA_M_SEVERITY ) >> CA_V_SEVERITY ) -#define CA_EXTRACT_SUCCESS(code)\ -( ( (code) & CA_M_SUCCESS ) >> CA_V_SUCCESS ) - -#define CA_INSERT_MSG_NO(code)\ -( ((code)<< CA_V_MSG_NO) & CA_M_MSG_NO ) -#define CA_INSERT_SEVERITY(code)\ -( ((code)<< CA_V_SEVERITY)& CA_M_SEVERITY ) -#define CA_INSERT_SUCCESS(code)\ -( ((code)<< CA_V_SUCCESS) & CA_M_SUCCESS ) - - -#define DEFMSG(SEVERITY,NUMBER)\ -(CA_INSERT_MSG_NO(NUMBER) | CA_INSERT_SEVERITY(SEVERITY)) - - -#define ECA_NORMAL DEFMSG(CA_K_SUCCESS, 0) -#define ECA_MAXIOC DEFMSG(CA_K_ERROR, 1) -#define ECA_UKNHOST DEFMSG(CA_K_ERROR, 2) -#define ECA_UKNSERV DEFMSG(CA_K_ERROR, 3) -#define ECA_SOCK DEFMSG(CA_K_ERROR, 4) -#define ECA_CONN DEFMSG(CA_K_WARNING, 5) -#define ECA_ALLOCMEM DEFMSG(CA_K_WARNING, 6) -#define ECA_UKNCHAN DEFMSG(CA_K_WARNING, 7) -#define ECA_UKNFIELD DEFMSG(CA_K_WARNING, 8) -#define ECA_TOLARGE DEFMSG(CA_K_ERROR, 9) -#define ECA_TIMEOUT DEFMSG(CA_K_WARNING, 10) -#define ECA_NOSUPPORT DEFMSG(CA_K_WARNING, 11) -#define ECA_STRTOBIG DEFMSG(CA_K_WARNING, 12) -#define ECA_DISCONNCHID DEFMSG(CA_K_ERROR, 13) -#define ECA_BADTYPE DEFMSG(CA_K_ERROR, 14) -#define ECA_CHIDNOTFND DEFMSG(CA_K_INFO, 15) -#define ECA_CHIDRETRY DEFMSG(CA_K_INFO, 16) -#define ECA_INTERNAL DEFMSG(CA_K_FATAL, 17) -#define ECA_DBLCLFAIL DEFMSG(CA_K_WARNING, 18) -#define ECA_GETFAIL DEFMSG(CA_K_WARNING, 19) -#define ECA_PUTFAIL DEFMSG(CA_K_WARNING, 20) -#define ECA_ADDFAIL DEFMSG(CA_K_WARNING, 21) -#define ECA_BADCOUNT DEFMSG(CA_K_WARNING, 22) -#define ECA_BADSTR DEFMSG(CA_K_ERROR, 23) -#define ECA_DISCONN DEFMSG(CA_K_WARNING, 24) -#define ECA_DBLCHNL DEFMSG(CA_K_WARNING, 25) -#define ECA_EVDISALLOW DEFMSG(CA_K_ERROR, 26) -#define ECA_BUILDGET DEFMSG(CA_K_WARNING, 27) -#define ECA_NEEDSFP DEFMSG(CA_K_WARNING, 28) -#define ECA_OVEVFAIL DEFMSG(CA_K_WARNING, 29) -#define ECA_BADMONID DEFMSG(CA_K_ERROR, 30) -#define ECA_NEWADDR DEFMSG(CA_K_WARNING, 31) -#define ECA_NEWCONN DEFMSG(CA_K_INFO, 32) -#define ECA_NOCACTX DEFMSG(CA_K_WARNING, 33) -#define ECA_DEFUNCT DEFMSG(CA_K_FATAL, 34) -#define ECA_EMPTYSTR DEFMSG(CA_K_WARNING, 35) -#define ECA_NOREPEATER DEFMSG(CA_K_WARNING, 36) -#define ECA_NOCHANMSG DEFMSG(CA_K_WARNNING, 37) -#define ECA_DLCKREST DEFMSG(CA_K_WARNING, 38) -#define ECA_SERVBEHIND DEFMSG(CA_K_WARNING, 39) -#define ECA_NOCAST DEFMSG(CA_K_WARNING, 40) -#define ECA_BADMASK DEFMSG(CA_K_ERROR, 41) -#define ECA_IODONE DEFMSG(CA_K_INFO, 42) -#define ECA_IOINPROGRESS DEFMSG(CA_K_INFO, 43) -#define ECA_BADSYNCGRP DEFMSG(CA_K_ERROR, 44) -#define ECA_PUTCBINPROG DEFMSG(CA_K_ERROR, 45) -#define ECA_NORDACCESS DEFMSG(CA_K_WARNING, 46) -#define ECA_NOWTACCESS DEFMSG(CA_K_WARNING, 47) -#define ECA_ANACHRONISM DEFMSG(CA_K_ERROR, 48) -#define ECA_NOSEARCHADDR DEFMSG(CA_K_WARNING, 49) -#define ECA_NOCONVERT DEFMSG(CA_K_WARNING, 50) -#define ECA_BADCHID DEFMSG(CA_K_ERROR, 51) -#define ECA_BADFUNCPTR DEFMSG(CA_K_ERROR, 52) - -#ifndef CA_ERROR_GLBLSOURCE -epicsShareExtern READONLY char *ca_message_text[]; -#else -READONLY char *ca_message_text[] -= -{ -"Normal successful completion", -"Maximum simultaneous IOC connections exceeded", -"Unknown internet host", -"Unknown internet service", -"Unable to allocate a new socket", -"Unable to connect to internet host or service", -"Unable to allocate additional dynamic memory", -"Unknown IO channel", -"Record field specified inappropriate for channel specified", -"The array or data structure specified will not fit in CA message buffer", -"User specified timeout on IO operation expired", -"Sorry, that feature is planned but not supported at this time", -"The supplied string is unusually large", -"The request was ignored because the specified channel is disconnected", -"The type you have requested from this channel is unknown", -"Remote Channel not found", -"Unable to locate all user specified channels", -"Channel Access Internal Failure", -"The requested local DB operation failed", -"Could not perform a database value get for that channel", -"Could not perform a database value put for that channel", -"Could not perform a database event add for that channel", -"Count requested inappropriate for that channel", -"The supplied string has improper format", -"Network connection lost", -"Ambiguous channel host (multiple IOC's have a channel by that name)", -"The CA routine called is inappropriate for use within an event handler", -"Database value get for that channel failed during channel search", -"Unable to initialize without the vxWorks VX_FP_TASK task option set", -"Event queue overflow has prevented first pass event after event add", -"A monitor by that id cant be found", -"Remote channel has new network address", -"New or resumed network connection", -"Specified task isnt a member of a CA context", -"Attempt to use defunct CA feature failed", -"The supplied string is empty", -"Unable to spawn the CA repeater thread- auto reconnect will fail", -"No channel id match for search reply- search reply ignored", -"Reseting dead connection- will try to reconnect", -"Server (IOC) has fallen behind or is not responding- still waiting", -"No internet interface with broadcast available", -"The event selection mask supplied is empty or inappropriate", -"IO operations have completed", -"IO operations are in progress", -"Invalid synchronous group identifier", -"Put call back operation collision with put call back operation in progress", -"Read access denied", -"Write access denied", -"Sorry, that anachronistic feature of CA is no longer supported", -"The search request/beacon address list was empty after initialization", -"Data conversion between client's type and the server's type failed", -"Invalid channel identifier", -"Invalid function pointer" -}; -#endif - -#ifdef __STDC__ -#define CAERR_USE_FUNC_PROTO -#endif - -#ifdef __cplusplus -#ifndef CAERR_USE_FUNC_PROTO -#define CAERR_USE_FUNC_PROTO -#endif -#endif - -#ifdef CAERR_USE_FUNC_PROTO -epicsShareFunc READONLY char * epicsShareAPI ca_message(long ca_status); -#else /* CAERR_USE_FUNC_PROTO */ -READONLY char *ca_message(); -#endif - -#endif diff --git a/src/include/caeventmask.h b/src/include/caeventmask.h deleted file mode 100644 index e146e0001..000000000 --- a/src/include/caeventmask.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - $Id$ - caeventmask.h - - Modification History - joh 04-16-90 Created - -*/ - -#ifndef INCLcaeventmaskh -#define INCLcaeventmaskh - -/* - event selections - (If any more than 8 of these are needed then update the - select field in the event_block struct in db_event.c from - unsigned char to unsigned short) - - - DBE_VALUE - Trigger an event when a significant change in the channel's value - occurs. Relies on the monitor deadband field under DCT. - - DBE_LOG - Trigger an event when an archive significant change in the channel's - valuue occurs. Relies on the archiver monitor deadband field under DCT. - - DBE_ALARM - Trigger an event when the alarm state changes - -*/ -#define DBE_VALUE (1<<0) -#define DBE_LOG (1<<1) -#define DBE_ALARM (1<<2) - -#endif diff --git a/src/include/devSup.h b/src/include/devSup.h deleted file mode 100644 index b68f96b87..000000000 --- a/src/include/devSup.h +++ /dev/null @@ -1,66 +0,0 @@ -/* devSup.h Device Support */ -/* share/epicsH $Id$ */ -/* - * 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 10-04-91 jba Added error message - * .02 05-18-92 rcz Changed macro "GET_DEVSUP(" to "GET_PDEVSUP(precDevSup," - * .03 05-18-92 rcz Structure devSup changed element name from dsetName to papDsetName - * .04 05-18-92 rcz New database access - */ - -#ifndef INCdevSuph -#define INCdevSuph 1 - -#ifdef __cplusplus -typedef long (*DEVSUPFUN)(void*); /* ptr to device support function*/ -#else -typedef long (*DEVSUPFUN)(); /* ptr to device support function*/ -#endif - -struct dset { /* device support entry table */ - long number; /*number of support routines*/ - DEVSUPFUN report; /*print report*/ - DEVSUPFUN init; /*init support*/ - DEVSUPFUN init_record; /*init support for particular record*/ - DEVSUPFUN get_ioint_info; /* get io interrupt information*/ - /*other functions are record dependent*/ - }; - -#define S_dev_noDevSup (M_devSup| 1) /*SDR_DEVSUP: Device support missing*/ -#define S_dev_noDSET (M_devSup| 3) /*Missing device support entry table*/ -#define S_dev_missingSup (M_devSup| 5) /*Missing device support routine*/ -#define S_dev_badInpType (M_devSup| 7) /*Bad INP link type*/ -#define S_dev_badOutType (M_devSup| 9) /*Bad OUT link type*/ -#define S_dev_badInitRet (M_devSup|11) /*Bad init_rec return value */ -#define S_dev_badBus (M_devSup|13) /*Illegal bus type*/ -#define S_dev_badCard (M_devSup|15) /*Illegal or nonexistant module*/ -#define S_dev_badSignal (M_devSup|17) /*Illegal signal*/ -#define S_dev_NoInit (M_devSup|19) /*No init*/ -#define S_dev_Conflict (M_devSup|21) /*Multiple records accessing same signal*/ - -#endif diff --git a/src/include/drvSup.h b/src/include/drvSup.h deleted file mode 100644 index 82e00869a..000000000 --- a/src/include/drvSup.h +++ /dev/null @@ -1,52 +0,0 @@ -/* drvSup.h Driver Support */ -/* share/epicsH $Id$ */ - -/* - * 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 05-21-92 rcz changed drvetName to papDrvName - * .02 05-18-92 rcz New database access (removed extern) - */ - -#ifndef INCdrvSuph -#define INCdrvSuph 1 - -typedef long (*DRVSUPFUN) (); /* ptr to driver support function*/ - -struct drvet { /* driver entry table */ - long number; /*number of support routines*/ - DRVSUPFUN report; /*print report*/ - DRVSUPFUN init; /*init support*/ - DRVSUPFUN reboot; /*reboot support*/ - /*other functions are device dependent*/ - }; -#define DRVETNUMBER ( (sizeof(struct drvet) -sizeof(long))/sizeof(DRVSUPFUN) ) - -#define S_drv_noDrvSup (M_drvSup| 1) /*SDR_DRVSUP: Driver support missing*/ -#define S_drv_noDrvet (M_drvSup| 3) /*Missing driver support entry table*/ - -#endif diff --git a/src/include/drvTS.h b/src/include/drvTS.h deleted file mode 100644 index 9a5d854af..000000000 --- a/src/include/drvTS.h +++ /dev/null @@ -1,252 +0,0 @@ -#ifndef __DRVTS_h__ -#define __DRVTS_h__ - -/* - * $Log$ - * Revision 1.2 1998/03/19 20:41:16 mrk - * Checked for Y2K complience. It turns out it was even ok when NTP time overflows - * in 2036. However it was modified so that no overflows should occur while convert - * ing between NTP, UNIX, and EPICS epochs. - * In addition the conversion of fractions of a second to nanaoseconds was changed - * Formatting was changed so that interesting code does not run off right side of page. - * Hopefully EPICS base is now fine for Y2K. - * In fact it should be fine (as far as time is converned) until the Unix epoch - * overflows a 32 unsigned integer in the year 2106. - * - * Revision 1.1 1996/01/25 21:11:56 mrk - * moved includes; .ascii=> .db; path changes - * - * Revision 1.12 1995/08/30 15:39:07 jbk - * Added global variables for force accurate time stamps and direct time. - * - * Revision 1.11 1995/08/18 13:18:13 mrk - * Added function prototypes for ansi c - * - * Revision 1.10 1995/08/17 20:35:52 jbk - * fixed the debug macro to work with -pendantic option (yuck) - * - * Revision 1.9 1995/08/17 19:44:08 jbk - * Added a new utility function to get the first of the year time stamp. - * - * Revision 1.8 1995/08/16 19:04:20 jbk - * corrected vxworks time troubles - * - * Revision 1.7 1995/05/22 15:22:24 jbk - * changes TS_EXTERN thing - * - * Revision 1.6 1995/02/01 15:30:17 winans - * Added a type field to the configure command to disable the use of the event - * system hardware if desired. - * - * Revision 1.5 1994/10/31 20:36:17 jbk - * added new stuff - * - */ - -/************************************************************************** - * - * Author: Jim Kowalkowski - * - * Modification Log: - * ----------------- - * .01 01-06-94 jbk initial version - * - ***********************************************************************/ - -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ - -#include -#include -#include -#include -#include - -#include - -#ifdef TS_DRIVER -#define TS_EXTERN -#else -#define TS_EXTERN extern -#endif - -#define ER_EVENT_RESET_TICK 0x7d /* Reset the tick counter */ - -#define TS_MAGIC ('T'<<24|'S'<<16|'d'<<8|'r') -#define TS_SLAVE_PORT 18322 -#define TS_MASTER_PORT 18323 -#define TS_RETRY_COUNT 4 -#define TS_TIME_OUT_MS 250 -#define TS_SECS_ASYNC_TRY_MASTER (60*5) /* every five minutes */ -#define TS_SECS_SYNC_TRY_MASTER (60*1) /* every one minute */ - -#define UDP_TIME_PORT 37 -#define UDP_NTP_PORT 123 - -#define TS_BILLION 1000000000 -#define TS_SYNC_RATE_SEC 10 -#define TS_CLOCK_RATE_HZ 1000 -#define TS_TOTAL_EVENTS 128 -/*Following is (SEC_IN_YEAR*90)+(22*SEC_IN_DAY) */ -/*22 is leap years from 1900 to 1990*/ -#define TS_1900_TO_EPICS_EPOCH 2840140800UL -/*Following is (SEC_IN_YEAR*70)+(17*SEC_IN_DAY) */ -/*17 is leap years from 1900 to 1970*/ -#define TS_1900_TO_VXWORKS_EPOCH 2208988800UL -/*Following is (SEC_IN_YEAR*20)+(5*SEC_IN_DAY) */ -/*5 is leap years from 1970 to 1990*/ -#define TS_VXWORKS_TO_EPICS_EPOCH 631152000UL - -#define TS_STAMP_SERVER_PRI 70 -#define TS_SYNC_SERVER_PRI 70 -#define TS_SYNC_CLIENT_PRI 70 -#define TS_ASYNC_CLIENT_PRI 70 - -typedef enum { TS_time_request, TS_sync_request, TS_sync_msg } TStype; -typedef enum { TS_master_alive, TS_master_dead } TSstate; -typedef enum { TS_async_none, TS_async_private, - TS_async_ntp, TS_async_time } TStime_protocol; -typedef enum { TS_sync_master, TS_async_master, - TS_sync_slave, TS_async_slave, - TS_direct_master, TS_direct_slave} TStime_type; - -struct TSstampTransStruct { - unsigned long magic; /* identifier */ - TStype type; /* transaction type */ - struct timespec master_time; /* master time stamp - last sync time */ - struct timespec current_time; /* master current time stamp 1990 epoch */ - struct timespec unix_time; /* time using 1900 epoch */ - unsigned long sync_rate; /* master sends sync at this rate */ - unsigned long clock_hz; /* master clock this frequency (tick rate) */ -}; -typedef struct TSstampTransStruct TSstampTrans; - -struct TSinfoStruct { - TSstate state; - TStime_type type; - TStime_protocol async_type; - int ts_sync_valid; - - struct timespec *event_table; /* timestamp table */ - - unsigned long sync_rate; /* master send sync at this rate */ - unsigned long clock_hz; /* master clock is this frequency */ - unsigned long clock_conv;/* conversion factor for tick_rate->ns */ - unsigned long time_out; /* udp packet time-out in milliseconds */ - int master_timing_IOC; /* 1=master, 0=slave */ - int master_port; /* port that master listens on */ - int slave_port; /* port that slave listens on */ - int total_events; /* this is the total event in the event system*/ - int sync_event; /* this is the sync event number */ - int has_event_system; /* 1=has event system, 0=no event system */ - int has_direct_time; /* 1=has direct time, 0=no direct time */ - int UserRequestedType; /* let user force the setting of type */ - - SEM_ID sync_occurred; - - struct sockaddr hunt; /* broadcast address info */ - struct sockaddr master; /* socket info for contacting master */ -}; -typedef struct TSinfoStruct TSinfo; - -/* global functions */ -#ifdef __cplusplus -extern "C" { -#endif -TS_EXTERN long TSinit(void); -TS_EXTERN long TSgetTimeStamp(int event_number,struct timespec* ts); -TS_EXTERN unsigned long TSepochNtpToUnix(struct timespec* ts); -TS_EXTERN unsigned long TSfractionToNano(unsigned long fraction); -TS_EXTERN unsigned long TSepochNtpToEpics(struct timespec* ts); -TS_EXTERN unsigned long TSepochUnixToEpics(struct timespec* ts); -TS_EXTERN unsigned long TSepochEpicsToUnix(struct timespec* ts); -TS_EXTERN long TScurrentTimeStamp(struct timespec* ts); -TS_EXTERN long TSaccurateTimeStamp(struct timespec* ts); -TS_EXTERN long TSgetFirstOfYearVx(struct timespec* ts); -TS_EXTERN void TSconfigure(int master, int sync_rate_sec, int clock_rate_hz, - int master_port, int slave_port, - unsigned long millisecond_request_time_out, int type); -TS_EXTERN long TSsetClockFromUnix(void); - -#ifndef TS_DRIVER -TS_EXTERN TSinfo TSdata; -TS_EXTERN TSdirectTimeVar; /* set to !=0 to indicate direct time available*/ -TS_EXTERN TSgoodTimeStamps; /* force best time stamps by setting != 0 */ -#endif - -#ifdef __cplusplus -}; -#endif - -/* NTP information - all this is backwards and documentation only */ -#define VN_SHIFT 2 /* Version - 3 bits */ -#define VN_version 3< -#endif -#ifndef INCLvxLibh -#include -#endif - -/* - * Macro equivalent of vxWorks glue for better performance - */ -#ifdef VRTX_KERNEL -# define semGive(SEMID)\ - { if ((SEMID)->count == 0)vrtxPost (&((SEMID)->count), 1); } - -# define semTake(SEMID)\ - {int dummy; vrtxPend (&((SEMID)->count), 0, &dummy); } -#endif - -typedef struct{ - SEM_ID ppend; /* wait for lock sem */ - unsigned short count; /* cnt of tasks waiting for lock */ - unsigned char lock; /* test and set lock bit */ - char pad; /* structure alignment */ -}FAST_LOCK; - -#define SEM_FAST_LOCK - -#if defined(SEM_FAST_LOCK) /* no lock test */ - -#define FASTLOCKINIT(PFAST_LOCK)\ - (((FAST_LOCK *)(PFAST_LOCK))->ppend = \ - semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY)) -#define FASTLOCKFREE(PFAST_LOCK)\ - semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend ) -#define FASTLOCK(PFAST_LOCK)\ - semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER); -#define FASTUNLOCK(PFAST_LOCK)\ - semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend); -#define FASTLOCKNOWAIT(PFAST_LOCK) \ - ((semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend,NO_WAIT)==0) ? TRUE : FALSE) -#define FASTLOCKTEST(PFAST_LOCK) \ -(\ - (semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend,NO_WAIT)==0 )\ - ? (semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend),FALSE)\ - : TRUE \ -) - - -#elif defined(TASK_LOCK_FAST_LOCK) - -#define FASTLOCKINIT(PFAST_LOCK)\ - (\ - ((FAST_LOCK *)(PFAST_LOCK))->count =0, \ - ((FAST_LOCK *)(PFAST_LOCK))->lock =0, \ - ((FAST_LOCK *)(PFAST_LOCK))->ppend = \ - semBCreate(SEM_Q_PRIORITY, SEM_EMPTY) \ - ) -#define FASTLOCKFREE(PFAST_LOCK)\ - semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend ) - -#define FASTLOCK(PFAST_LOCK)\ - {\ - TASK_LOCK;\ - while( ((FAST_LOCK *)(PFAST_LOCK))->lock ){\ - ((FAST_LOCK *)(PFAST_LOCK))->count++;\ - TASK_UNLOCK;\ - semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER);\ - TASK_LOCK;\ - (((FAST_LOCK *)(PFAST_LOCK))->count)--;\ - }\ - ((FAST_LOCK *)(PFAST_LOCK))->lock= TRUE; - TASK_UNLOCK; - } - -#define FASTUNLOCK(PFAST_LOCK)\ - {\ - ((FAST_LOCK *)(PFAST_LOCK))->lock = FALSE;\ - if( ((FAST_LOCK *)(PFAST_LOCK))->count )\ - semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend);\ - }; - -#define FASTLOCKTEST(PFAST_LOCK)\ -( ((FAST_LOCK *)(PFAST_LOCK))->lock ) - -#else /* vxTas() fast lock */ - -/* - * extra paren avoids order of ops problems - * (returns what semBCreate returns on v5 vxWorks) - */ -#define FASTLOCKINIT(PFAST_LOCK)\ - (\ - ((FAST_LOCK *)(PFAST_LOCK))->count =0, \ - ((FAST_LOCK *)(PFAST_LOCK))->lock =0, \ - ((FAST_LOCK *)(PFAST_LOCK))->ppend = \ - semBCreate(SEM_Q_PRIORITY, SEM_EMPTY) \ - ) - -/* - * new requirement with v5 vxWorks - */ -#define FASTLOCKFREE(PFAST_LOCK)\ - semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend ) - -#define FASTLOCK(PFAST_LOCK)\ - {\ - ((FAST_LOCK *)(PFAST_LOCK))->count++;\ - while(!vxTas( (char *)&( ((FAST_LOCK *)(PFAST_LOCK))->lock ) ))\ - semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER);\ - ( ((FAST_LOCK *)(PFAST_LOCK))->count)--;\ - } - -#define FASTUNLOCK(PFAST_LOCK)\ - {\ - ((FAST_LOCK *)(PFAST_LOCK))->lock = FALSE;\ - if( ((FAST_LOCK *)(PFAST_LOCK))->count )\ - semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend);\ - }; - -#define FASTLOCKNOWAIT(PFAST_LOCK) (vxTas((char *)&(((FAST_LOCK *)(PFAST_LOCK))->lock))) - -#define FASTLOCKTEST(PFAST_LOCK)\ -( ((FAST_LOCK *)(PFAST_LOCK))->lock ) - -#endif - -#endif /* Nothing after this endif */ diff --git a/src/libCom/Makefile.Unix b/src/libCom/Makefile.Unix deleted file mode 100644 index 73ff1dad7..000000000 --- a/src/libCom/Makefile.Unix +++ /dev/null @@ -1,139 +0,0 @@ -TOP = ../../.. -include $(TOP)/config/CONFIG_BASE -CMPLR = STRICT - -# OPTIM_YES=-g -USR_CFLAGS = -D_NO_PROTO -USR_INCLUDES = -I$(TOP)/src/include/os/$(T_A) -USR_LDLIBS += -lCom -USR_LDFLAGS += -L. -#USR_CFLAGS = -v -g -#CC = $(PURIFYHOME)/purify $(C_$(CMPLR)) - -VPATH = ../os/generic - -DEPLIBS_BASE = $(INSTALL_LIB) -DEPLIBS += $(DEPLIBS_BASE)/libCom.a - -INC += cvtFast.h -INC += ellLib.h -INC += envDefs.h -INC += epicsAssert.h -INC += epicsPrint.h -INC += errMdef.h -INC += error.h -INC += fdmgr.h -INC += freeList.h -INC += gpHash.h -INC += memDebugLib.h -INC += tsDefs.h -INC += bucketLib.h -INC += pal.h -INC += fdManager.h -INC += osiTime.h -INC += osiTimer.h -INC += macLib.h -INC += impLib.h -INC += dbmf.h - -SRCS.c += ../bucketLib.c -SRCS.c += ../calcPerform.c -SRCS.c += ../cvtFast.c -SRCS.c += ../ellLib.c -SRCS.c += ../envSubr.c -SRCS.c += envData.c -SRCS.c += ../errMtst.c -SRCS.c += ../errPrintfUNIX.c -SRCS.c += ../errSymLib.c -SRCS.c += errSymTbl.c -SRCS.c += ../fdmgr.c -SRCS.c += ../freeListLib.c -SRCS.c += ../gpHashLib.c -SRCS.c += ../memDebugLib.c -SRCS.c += ../nextFieldSubr.c -SRCS.c += ../postfix.c -SRCS.c += ../realpath.c -SRCS.c += ../tsSubr.c -SRCS.c += ../assertUNIX.c -SRCS.c += ../fdManager.cc -SRCS.c += ../osiTimer.cc -SRCS.c += ../macCore.c -SRCS.c += ../macUtil.c -SRCS.c += ../os/generic/ipAddrToA.c -SRCS.c += ../os/generic/osdTime.cc -SRCS.c += ../impLib.c -SRCS.c += ../impExpand.c -SRCS.c += ../dbmf.c - -LIBOBJS += bucketLib.o -LIBOBJS += calcPerform.o -LIBOBJS += cvtFast.o -LIBOBJS += ellLib.o -LIBOBJS += envSubr.o -LIBOBJS += envData.o -LIBOBJS += errMtst.o -LIBOBJS += errPrintfUNIX.o -LIBOBJS += errSymLib.o -LIBOBJS += errSymTbl.o -LIBOBJS += fdmgr.o -LIBOBJS += freeListLib.o -LIBOBJS += gpHashLib.o -LIBOBJS += memDebugLib.o -LIBOBJS += nextFieldSubr.o -LIBOBJS += postfix.o -LIBOBJS += realpath.o -LIBOBJS += tsSubr.o -LIBOBJS += assertUNIX.o -LIBOBJS += fdManager.o -LIBOBJS += osiTimer.o -LIBOBJS += macCore.o -LIBOBJS += macUtil.o -LIBOBJS += ipAddrToA.o -LIBOBJS += osdTime.o -LIBOBJS += impLib.o -LIBOBJS += dbmf.o -#LIBOBJS += impExpand.o # this looks like an error, it's a product!! - -LIBNAME = libCom.a - -#TARGETS = tsTest -PROD += impExpand - -MAN3 = gpHash.3 freeList.3 - -SRC = $(TOP)/src - -ERR_S_FILES += $(TOP)/src/as/asLib.h -ERR_S_FILES += $(TOP)/src/db/dbAccess.h -ERR_S_FILES += $(TOP)/src/db/devLib.h -ERR_S_FILES += $(TOP)/src/db/devSup.h -ERR_S_FILES += $(TOP)/src/db/drvSup.h -ERR_S_FILES += $(TOP)/src/db/recSup.h -ERR_S_FILES += $(TOP)/src/dbStatic/dbStaticLib.h -ERR_S_FILES += $(TOP)/src/drv/ansi/drvEpvxi.h -ERR_S_FILES += $(TOP)/src/drv/old/drvBitBusErr.h -ERR_S_FILES += $(TOP)/src/drv/old/drvGpibErr.h -ERR_S_FILES += ../tsDefs.h -ERR_S_FILES += ../errMdef.h -ERR_S_FILES += $(TOP)/src/cas/generic/casdef.h -ERR_S_FILES += $(TOP)/src/gdd/gddAppFuncTable.h - -include $(TOP)/config/RULES.Unix - -errSymTbl.o: errSymTbl.c - $(COMPILE.c) -o $@ $< - -envData.c: ../envDefs.h $(TOP)/config/CONFIG_ENV \ - $(TOP)/config/CONFIG_SITE_ENV - ../bldEnvData $(TOP)/config - -tsTest: tsSubr.o - $(LINK.c) -o $@ tsSubr.o -lCom -lDb -lCom -lm -s - -clean:: - @$(RM) errSymTbl.c envData.c - -errSymTbl.c: $(ERR_S_FILES) - @/bin/rm -f errSymTbl.c ;\ - ../makeStatTbl $(ERR_S_FILES) >errSymTbl.c - diff --git a/src/libCom/ansidecl.h b/src/libCom/ansidecl.h deleted file mode 100644 index c351653b6..000000000 --- a/src/libCom/ansidecl.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (C) 1991 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU C Library; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* ANSI and traditional C compatibility macros - - ANSI C is assumed if __STDC__ is #defined. - - Macro ANSI C definition Traditional C definition - ----- ---- - ---------- ----------- - ---------- - PTR `void *' `char *' - LONG_DOUBLE `long double' `double' - CONST `const' `' - VOLATILE `volatile' `' - SIGNED `signed' `' - PTRCONST `void *const' `char *' - - DEFUN(name, arglist, args) - - Defines function NAME. - - ARGLIST lists the arguments, separated by commas and enclosed in - parentheses. ARGLIST becomes the argument list in traditional C. - - ARGS list the arguments with their types. It becomes a prototype in - ANSI C, and the type declarations in traditional C. Arguments should - be separated with `AND'. For functions with a variable number of - arguments, the last thing listed should be `DOTS'. - - DEFUN_VOID(name) - - Defines a function NAME, which takes no arguments. - - EXFUN(name, prototype) - - Is used in an external function declaration. - In ANSI C it is `NAMEPROTOTYPE' (so PROTOTYPE should be enclosed in - parentheses). In traditional C it is `NAME()'. - For a function that takes no arguments, PROTOTYPE should be `(NOARGS)'. - - For example: - extern int EXFUN(printf, (CONST char *format DOTS)); - int DEFUN(fprintf, (stream, format), - FILE *stream AND CONST char *format DOTS) { ... } - void DEFUN_VOID(abort) { ... } -*/ - -#ifndef _ANSIDECL_H - -#define _ANSIDECL_H 1 - - -/* Every source file includes this file, - so they will all get the switch for lint. */ -/* LINTLIBRARY */ - - -#ifdef __STDC__ - -#define PTR void * -#define PTRCONST void *CONST -#define LONG_DOUBLE long double - -#define AND , -#define NOARGS void -#define CONST const -#define VOLATILE volatile -#define SIGNED signed -#define DOTS , ... - -#define EXFUN(name, proto) name proto -#define DEFUN(name, arglist, args) name(args) -#define DEFUN_VOID(name) name(NOARGS) - -#else /* Not ANSI C. */ - -#define PTR char * -#define PTRCONST PTR -#define LONG_DOUBLE double - -#define AND ; -#define NOARGS -#define CONST -#define VOLATILE -#define SIGNED -#define DOTS - -#define EXFUN(name, proto) name() -#define DEFUN(name, arglist, args) name arglist args; -#define DEFUN_VOID(name) name() - -#endif /* ANSI C. */ - - -#endif /* ansidecl.h */ diff --git a/src/libCom/arAccessLib.c b/src/libCom/arAccessLib.c deleted file mode 100644 index ae756b795..000000000 --- a/src/libCom/arAccessLib.c +++ /dev/null @@ -1,2915 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 03-09-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1990-92, 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 03-09-90 rac initial version - * .02 07-31-91 rac installed in SCCS - * .03 09-18-91 rac change arg for arCFChanRead to int--short - * causes problems on Sun4; other minor fixes - * .04 04-04-92 rac add arCFChanWrite_args; handle flags for begin - * and end of snapshot - * .05 09-14-92 rac remove use of special malloc and free routines - * .06 09-30-92 rac ignore time running backward - * - * make options - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code - */ -/*+/mod*********************************************************************** -* TITLE arAccessLib.c - AR access library for AR data set files -* -* DESCRIPTION -* -* QUICK REFERENCE -* AR_CHAN_DESC *pCFDesc; pointer to 'AR channel file' descriptor -* -* #include some general use definitions -* #include definitions for time stamps -* #include definitions for Channel Access -* #include definitions for database related items -* #include structures for AR access library routines -* #include obtain mode definitions for SunOS -* -* AR_CHAN_DESC *pChanDesc; pointer to channel descriptor in chan file -* AR_CF_DESC *pCfDesc; pointer to channel file descriptor -* chtype type; one of the DBR_xxx types -* TS_STAMP *pStamp; pointer to a time stamp structure -* int mode; mode to open file or channel--O_RDONLY -* or O_RDWR -* -* long arCFChanClose( >ppChanDesc ) -* long arCFChanDel( >ppChanDesc ) -* long arCFChanFind( pCfDesc, chanName ) -* AR_CHAN_DESC *arCFChanOpen( pCfDesc, chanName, mode ) -* long arCFChanPosition( pChanDesc, pStamp ) -* long arCFChanPurge( pChanDesc, pStamp ) -* long arCFChanRead( pChanDesc, type, >pDbrBuf, count) -* long arCFChanWrite( pChanDesc, pEvHandArg ) -* long arCFChanWrite_args( pChanDesc, stamp, dbfType, -* count, pData, alStat, alSevr) -* long arCFChanWriteByte( pArChanDesc, value ) -* long arCFChanWriteGR( pChanDesc, pEvHandArg ) -* long arCFClose( >ppCfDesc ) -* AR_CF_DESC *arCFCreate( name, maxBytes ) -* AR_CF_DESC *arCFOpen( name, mode ) -* long arCFSyncRead( pCfDesc ) -* long arCFSyncWrite( pCfDesc ) -* -* int ArCFChanElementCount( pChanDesc ) -* chtype ArCFChanFieldType( pChanDesc ) -* char *ArCFChanName( pChanDesc ) -* int ArCFChanNStates( pChanDesc ) -* int ArCFChanPrec( pChanDesc ) -* char *ArCFChanStates( pChanDesc ) -* char *ArCFChanUnits( pChanDesc ) -* -*-***************************************************************************/ - -#include -#ifndef INC_genDefs_h -# include -#endif -#ifndef INC_tsDefs_h -# include -#endif -#ifndef INC_arCS_h -# include -#endif -#ifndef INCLcadefh -# include -#endif -#ifndef INCLdb_accessh -# include -#endif - -#include -#include /* for O_RDWR and O_RDONLY definitions */ -#include - -/*+/internal------------------------------------------------------------------ -* NAME arCF_malloc/arCF_free -* -* malloc and free routines for arCF routines to use for the various kinds -* of data structures. Should the need arise, these routines will -* be enhanced to maintain lists of free data structures of the various -* kinds, to eliminate malloc()/free() overhead and memory fragmentation. -* -* The following routines are used for calling malloc() and free() for -* some common data structures in arAccessLib. They have two versions, -* depending on whether DEBUG is defined. Both versions perform the -* described function. The DEBUG version provides the capability for -* `bounds checking' on allocated buffers, and also for filling buffers -* with a known pattern for use in `un-initialized buffer' bug detection. -* -* AR_CF_DESC *arCF_mallocCF_DESC() void arCF_freeCF_DESC(pCFDesc) -* AR_CHAN_DESC *arCF_mallocCHAN_DESC() void arCF_freeCHAN_DESC(pChanDesc) -*---------------------------------------------------------------------------*/ - - -/* Forward declarations */ -long arCFChanReadTs(); -long arCFReadMIBuffers(); - -AR_CHAN_DESC * -arCF_mallocCHAN_DESC() -{ -#ifdef DEBUG - return (AR_CHAN_DESC *)arMalloc(sizeof(AR_CHAN_DESC), "AR_CHAN_DESC"); -#else - return (AR_CHAN_DESC *)malloc(sizeof(AR_CHAN_DESC)); -#endif -} -void -arCF_freeCHAN_DESC(ptr) -AR_CHAN_DESC *ptr; -{ -#ifdef DEBUG - arFree(ptr, sizeof(AR_CHAN_DESC), "AR_CHAN_DESC"); -#else - free(ptr); -#endif -} - -AR_CF_DESC * -arCF_mallocCF_DESC() -{ -#ifdef DEBUG - return (AR_CF_DESC *)arMalloc(sizeof(AR_CF_DESC), "AR_CF_DESC"); -#else - return (AR_CF_DESC *)malloc(sizeof(AR_CF_DESC)); -#endif -} -void -arCF_freeCF_DESC(ptr) -AR_CF_DESC *ptr; -{ -#ifdef DEBUG - arFree(ptr, sizeof(AR_CF_DESC), "AR_CF_DESC"); -#else - free(ptr); -#endif -} - -/*+/macro********************************************************************* -* NAME ArCFChanXxx - convenience macros for channel files -* -* DESCRIPTION -* These macros provide easy access to information about a channel in -* a channel file. The macros are defined in arAccessLib.h -* -* int ArCFChanElementCount( pArChanDesc ) -* chtype ArCFChanFieldType( pArChanDesc ) -* char *ArCFChanName( pArChanDesc ) -* -* The following marcos for obtaining graphics information bypasses -* the need to do a read with DBR_GR_xxx, and thus simplifies -* programming. However, programs which must run with both -* Channel Access and the AR access library should probably use a -* read to obtain the information. -* -* int ArCFChanNStates( pArChanDesc ) -* int ArCFChanPrec( pArChanDesc ) -* char *ArCFChanStates( pArChanDesc ) -* char *ArCFChanUnits( pArChanDesc ) -* -* RETURNS -* as indicated -* -* NOTES -* 1. These macros assume, but do not check, that the channel descriptor -* is open. -* 2. The macros for obtaining graphics information assume, but do not -* check, that the macro being used is appropriate for the native -* type of the channel. -* -*-*/ - - -/*+/subr********************************************************************** -* NAME arCFChanClose - close a channel of an AR channel data file -* -* DESCRIPTION -* Close a channel descriptor. If any I/O is outstanding for the -* descriptor, that I/O is forced to completion; this may include -* writing data and index blocks to disk and updating oldestStamp and -* newestStamp in the chanHdr. Memory buffers for data and index blocks -* are free()'d. -* -* The count of channel descriptors open to the channel is decremented. -* -* The channel descriptor is removed from the channel descriptor list -* in the channel file descriptor. The channel descriptor is free()'d -* and NULL is stored in caller's pointer to prevent further use -* -* RETURNS -* OK -* -* BUGS -* o doesn't flush the MI buffer -* o primitive error handling -* -* SEE ALSO -* arCFChanOpen(), arCFChanDel() -* -*-*/ -long -arCFChanClose(ppArChanDesc) -AR_CHAN_DESC **ppArChanDesc; /* IO ptr to ptr to channel descriptor; - will be NULL at completion */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status to caller */ - AR_CHAN_DESC *pArChanDesc; /* pointer to channel descriptor */ - AR_CHAN_HDR *pChanHdr; /* pointer to channel header */ - - assert(*ppArChanDesc != NULL); - pArChanDesc = *ppArChanDesc; - assert(pArChanDesc != NULL); - assert(pArChanDesc->pArCfDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - pChanHdr = &ArCDChanHdr(pArChanDesc); - assert(pChanHdr->count > 0); - -/*---------------------------------------------------------------------------- -* flush data and index buffers and free() them. -* if the MI for this channel has been altered, write it -*---------------------------------------------------------------------------*/ - if (pArChanDesc->pDataBuf != NULL) { - stat = arCF_DFlushAndFree(pArChanDesc); - assert(stat == OK); - } - if (pArChanDesc->pIndexBuf != NULL) { - stat = arCF_IFlushAndFree(pArChanDesc); - assert(stat == OK); - } - if (pArChanDesc->pMIBuf != NULL) { - stat = arCF_MIFlush(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - assert(stat == OK); - } -/*---------------------------------------------------------------------------- -* remove this channel descriptor from the list of channel descriptors. -*---------------------------------------------------------------------------*/ - if (pArChanDesc->pNextDesc != NULL) - pArChanDesc->pNextDesc->pPrevDesc = pArChanDesc->pPrevDesc; - else - pArChanDesc->pArCfDesc->pChanDescTail = pArChanDesc->pPrevDesc; - if (pArChanDesc->pPrevDesc != NULL) - pArChanDesc->pPrevDesc->pNextDesc = pArChanDesc->pNextDesc; - else - pArChanDesc->pArCfDesc->pChanDescHead = pArChanDesc->pNextDesc; -/*---------------------------------------------------------------------------- -* decrement count of descriptors open to this chanHdr -* if this descriptor had the chanHdr open in O_RDWR mode, reset the -* flag in the chanHdr -*---------------------------------------------------------------------------*/ - pChanHdr->count -= 1; - if ((pArChanDesc->flags & AR_CDESC_WRITE) != 0) { - assert((pChanHdr->flags & AR_CHDR_WRITE) != 0); - pChanHdr->flags ^= AR_CHDR_WRITE; - } - -/*---------------------------------------------------------------------------- -* free the descriptor and put NULL in the caller's pointer, to prevent -* further use of the descriptor -*---------------------------------------------------------------------------*/ - arCF_freeCHAN_DESC(pArChanDesc); - *ppArChanDesc = NULL; - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCFChanDel - delete a channel of an AR channel data file -* -* DESCRIPTION -* Deletes all data and index buffers for the channel, deletes the -* chanHdr for the channel, and closes the channel descriptor. If the -* delete is successful, then the channel descriptor has been changed -* to NULL, preventing further use; memory associated with data buffers, -* index buffers, and the channel descriptor has been free()'d. Disk -* blocks which are deleted from the channel are added to the channel -* file's free block list; the chanHdr is added to the free chanHdr list. -* -* The channel descriptor must be open O_RDWR, and there must be no -* other channel descriptors open to the channel. -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCFChanDel(ppArChanDesc) -AR_CHAN_DESC **ppArChanDesc; /* IO ptr to ptr to channel descriptor */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status to caller */ - AR_CHAN_DESC *pArChanDesc; /* pointer to channel descriptor */ - AR_CHAN_HDR *pChanHdr; /* pointer to channel header */ - - assert(*ppArChanDesc != NULL); - pArChanDesc = *ppArChanDesc; - assert(pArChanDesc != NULL); - assert(pArChanDesc->pArCfDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - pChanHdr = &ArCDChanHdr(pArChanDesc); - assert(pChanHdr->count > 0); - - if ((pArChanDesc->flags & AR_CDESC_WRITE) == 0) { - (void)fprintf(stderr, "arCFChanDel: %s not open O_RDWR\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - if (pChanHdr->count > 1) { - (void)fprintf(stderr, "arCFChanDel: others have %s open\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - -/*---------------------------------------------------------------------------- -* free all the data and index buffers for this channel -*---------------------------------------------------------------------------*/ - if (retStat == OK) { - if ((stat = arCFChanPurge(pArChanDesc, (TS_STAMP *)NULL)) != OK) { - (void)fprintf(stderr, -"arCFChanDel: error deleting data and/or index buffers for %s\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - } - -/*---------------------------------------------------------------------------- -* remove this channel descriptor from the list of channel descriptors. -*---------------------------------------------------------------------------*/ - if (retStat == OK) { - if (pArChanDesc->pNextDesc != NULL) - pArChanDesc->pNextDesc->pPrevDesc = pArChanDesc->pPrevDesc; - else - pArChanDesc->pArCfDesc->pChanDescTail = pArChanDesc->pPrevDesc; - if (pArChanDesc->pPrevDesc != NULL) - pArChanDesc->pPrevDesc->pNextDesc = pArChanDesc->pNextDesc; - else - pArChanDesc->pArCfDesc->pChanDescHead = pArChanDesc->pNextDesc; - -/*---------------------------------------------------------------------------- -* move the chanHdr to the free chanHdr list and mark the MI block -* as MODIFIED -*---------------------------------------------------------------------------*/ - stat = arCF_MIDelChan(pArChanDesc->pArCfDesc, - pArChanDesc->pMIBuf, pArChanDesc->hdrNum); - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - -/*---------------------------------------------------------------------------- -* free the descriptor and put NULL in the caller's pointer, to prevent -* further use of the descriptor -*---------------------------------------------------------------------------*/ - arCF_freeCHAN_DESC(pArChanDesc); - *ppArChanDesc = NULL; - } - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCFChanFind - find a channel in an AR channel data file -* -* DESCRIPTION -* Find a channel in a channel data file. This routine is intended -* to be used in cases where it is necessary to know prior to doing -* an arCFChanOpen() whether the file contains a particular channel. -* -* RETURNS -* OK if channel is found, or -* ERROR -* -* BUGS -* o text -* -* EXAMPLE -* -*-*/ -long -arCFChanFind(pArCfDesc, chanName) -AR_CF_DESC *pArCfDesc; /* I pointer to channel file descriptor */ -char *chanName; /* I channel name */ -{ - AR_MI_BUF *pMIBuf; /* ptr to MI block containing chanHdr */ - int indx; /* index in MI block of chanHdr */ - int l; /* length of chanName */ - char name[AR_NAME_DIM]; /* buffer for appending .VAL */ - - assert(pArCfDesc != NULL); - l = strlen(chanName); - - if (strchr(chanName, '.') == 0) { - if (l <= 0 || l >= AR_NAME_DIM-5) { - (void)fprintf(stderr, "arCFChanFind: chanName illegal length\n"); - return ERROR; - } - (void)strcpy(name, chanName); - (void)strcat(name, ".VAL"); - chanName = name; - } - else { - if (l <= 0 || l >= AR_NAME_DIM) { - (void)fprintf(stderr, "arCFChanFind: chanName illegal length\n"); - return ERROR; - } - } - return arCF_MIFindChan(pArCfDesc, chanName, &pMIBuf, &indx); -} - -/*+/subr********************************************************************** -* NAME arCFChanOpen - open a channel to an AR channel data file -* -* DESCRIPTION -* Open a channel in a channel data file. If the open is successful, -* a channel descriptor is returned. If the channel doesn't exist, -* one is created if mode is O_RDWR; in this case, the .flags item in -* the channel descriptor will have AR_CDESC_NEW set. -* -* When the open is complete, the relevent index and data blocks will -* be in memory. If the mode is O_RDWR, the position will be at the -* end of the channel's data, ready for writing; for O_RDONLY, at the -* start of the channel's data, ready for reading. -* -* If the channel descriptor isn't closed before the channel data file -* is closed, it will be closed automatically, with updated blocks -* written to the channel data file. -* -* If O_RDWR is specified, the channel data file must have been opened -* with O_RDWR and there must be no other channel descriptor open in -* O_RDWR mode to the desired channel. -* -* The count of channel descriptors open to the desired channel is -* incremented. -* -* RETURNS -* pointer to channel descriptor, or -* NULL -* -* BUGS -* o no exit handler (this will probably be covered by the exit handler -* for the file, which isn't presently done) -* o for reading, the possibility of opening to a position (date/time) -* would potentially avoid wasting a disk read -* -* SEE ALSO -* arCFChanClose(), arCFOpen(), arCFClose() -* -* EXAMPLE -* -*-*/ -AR_CHAN_DESC * -arCFChanOpen(pArCfDesc, chanName, mode) -AR_CF_DESC *pArCfDesc; /* IO pointer to channel file descriptor */ -char *chanName; /* I channel name */ -int mode; /* I mode for open--O_RDONLY or O_RDWR; if mode is - O_RDWR and the channel doesn't exist, it - is created */ -{ - int stat; /* status return from calls */ - int retStat=OK; /* cumulative status in this routine */ - AR_MI_BUF *pMIBuf; /* ptr to MI block containing chanHdr */ - int indx; /* index in MI block of chanHdr */ - AR_CHAN_HDR *pChanHdr; /* pointer to chanHdr for this channel */ - AR_CHAN_DESC *pChanDesc=NULL;/* pointer to channel descriptor */ - int l; /* length of chanName */ - char name[AR_NAME_DIM]; /* buffer for appending .VAL */ - - assert(pArCfDesc != NULL); - assert(mode == O_RDONLY || mode == O_RDWR); - -/*---------------------------------------------------------------------------- -* check chanName to see if it specifies a .field ; if it doesn't, copy -* chanName to 'name' and append .VAL , then change chanName to point to -* 'name' -*---------------------------------------------------------------------------*/ - l = strlen(chanName); - if (strchr(chanName, '.') == 0) { - if (l <= 0 || l >= AR_NAME_DIM-5) { - (void)fprintf(stderr, "arCFChanOpen: chanName illegal length\n"); - retStat = ERROR; - } - else { - (void)strcpy(name, chanName); - (void)strcat(name, ".VAL"); - chanName = name; - } - } - else { - if (l <= 0 || l >= AR_NAME_DIM) { - (void)fprintf(stderr, "arCFChanOpen: chanName illegal length\n"); - retStat = ERROR; - } - } - -/*---------------------------------------------------------------------------- -* make sure file is O_RDWR if ChanOpen request is O_RDWR -*---------------------------------------------------------------------------*/ - if ( (mode == O_RDWR) && - ((pArCfDesc->pBfDesc->flags & BF_DESC_WRITE) == 0) ) { - (void)fprintf(stderr, - "arCFChanOpen: can't open %s O_RDWR--file not O_RDWR\n", - chanName); - retStat = ERROR; - } - -/*---------------------------------------------------------------------------- -* allocate a channel descriptor and clear the 'flags' item. If the open -* is with O_RDWR, set the AR_CDESC_WRITE bit in the 'flags' item. -*---------------------------------------------------------------------------*/ - if (retStat == OK) { - if ((pChanDesc = arCF_mallocCHAN_DESC()) == NULL) { - (void)fprintf(stderr, - "arCFChanOpen: can't malloc for chan desc for %s\n", - chanName); - retStat = ERROR; - } - else { - pChanDesc->flags = 0; - if (mode == O_RDWR) - pChanDesc->flags |= AR_CDESC_WRITE; - } - } - -/*---------------------------------------------------------------------------- -* try to locate the chanHdr for the channel. If no chanHdr is found, -* create one, providing that mode is O_RDWR; if mode is O_RDONLY, then -* not finding a chanHdr is an error. If a new chanHdr is created, then -* set AR_CDESC_NEW in the channel descriptor. -*---------------------------------------------------------------------------*/ - if (retStat == OK) { - stat = arCF_MIFindChan(pArCfDesc, chanName, &pMIBuf, &indx); - if (stat != OK) { - if ((pChanDesc->flags & AR_CDESC_WRITE) != 0) { - stat = arCF_MIAddChan(pArCfDesc, chanName, &pMIBuf, &indx); - if (stat == OK) - pChanDesc->flags |= AR_CDESC_NEW; - else { - (void)fprintf(stderr, - "arCFChanOpen: error adding chanHdr for %s\n", - chanName); - retStat = ERROR; - } - } - else { - (void)fprintf(stderr, "arCFChanOpen: %s not found\n", chanName); - retStat = ERROR; - } - } - } - if (retStat == OK) { -/*---------------------------------------------------------------------------- -* compute the actual address of the chanHdr, for easier manipulation. If -* the chanHdr is already open in O_RDWR mode, and if this open is for -* O_RDWR, an error exists. If this is the only request for O_RDWR, flag -* AR_CHDR_WRITE in the chanHdr to disallow other writers. If all is well, -* increment in the chanHdr the count of descriptors open to it. -*---------------------------------------------------------------------------*/ - assert(pMIBuf != NULL); - pChanHdr = &pMIBuf->chanHdr[indx]; - if ((pChanDesc->flags & AR_CDESC_WRITE) != 0) { - if ((pChanHdr->flags & AR_CHDR_WRITE) != 0) { - (void)fprintf(stderr, - "arCFChanOpen: %s already open for writing\n", - chanName); - retStat = ERROR; - } - else { - pChanHdr->flags |= AR_CHDR_WRITE; - pChanHdr->count += 1; - } - } - else - pChanHdr->count += 1; - - } - if (retStat == OK) { -/*---------------------------------------------------------------------------- -* the channel file descriptor has a list of open channel descriptors; -* link this channel descriptor onto the end of that list (which is -* a doubly linked list). -*---------------------------------------------------------------------------*/ - pChanDesc->pNextDesc = NULL; - pChanDesc->pPrevDesc = pArCfDesc->pChanDescTail; - if (pArCfDesc->pChanDescHead != NULL) { - assert(pArCfDesc->pChanDescTail != NULL); - pArCfDesc->pChanDescTail->pNextDesc = pChanDesc; - } - else { - assert(pArCfDesc->pChanDescTail == NULL); - pArCfDesc->pChanDescHead = pChanDesc; - } - pArCfDesc->pChanDescTail = pChanDesc; - -/*---------------------------------------------------------------------------- -* set up the channel descriptor. Part of this setup includes getting -* an index buffer and a data buffer. If the open is O_RDONLY, then -* the position will be at the first index block and first data block; -* for O_RDWR, the last index block and last data block will be used. -*---------------------------------------------------------------------------*/ - pChanDesc->pArCfDesc = pArCfDesc; - pChanDesc->pMIBuf = pMIBuf; - pChanDesc->hdrNum = indx; - pChanDesc->pIndexBuf = NULL; - pChanDesc->pDataBuf = NULL; - pChanDesc->pData = NULL; - pChanDesc->remainCount = -10; - pChanDesc->datInfNum = -10; - pChanDesc->timeStamp.secPastEpoch = 0; - pChanDesc->timeStamp.nsec = 0; - stat = arCF_DNextBlock(pChanDesc); - if (stat == ERROR && (pChanDesc->flags & AR_CDESC_EOF) == 0) - assertAlways(0); - } - else { - if (pChanDesc != NULL) { - arCF_freeCHAN_DESC(pChanDesc); - pChanDesc = NULL; - } - } - - return pChanDesc; -} - -/*+/subr********************************************************************** -* NAME arCFChanPosition - position channel decscriptor based on time stamp -* -* DESCRIPTION -* Position a channel descriptor so it is ready to read the data with -* the specified time stamp. If no data with the specified time stamp -* is available, the positioning is for the first data following. -* -* End of file results in an error return, with the AR_CDESC_EOF flag -* set in chanDesc.flags . -* -* RETURNS -* OK, or -* ERROR -* -* SEE ALSO -* arCFChanRead() -* -* EXAMPLE -* -*-*/ -long -arCFChanPosition(pArChanDesc, pPosStamp) -AR_CHAN_DESC *pArChanDesc;/* IO pointer to channel descriptor */ -TS_STAMP *pPosStamp; /* I stamp for desired data; NULL for `rewind' */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status to caller */ - AR_CHAN_HDR *pChanHdr; /* pointer to chanHdr */ - AR_INDEX_BUF *pIndexBuf; /* pointer to buffer for index buffer */ - AR_DATA_BUF *pDataBuf; /* pointer to buffer for data buffer */ - BF_BLKNUM indexBlock; /* block # for index block */ - BF_BLKNUM nextIndexBlock; /* block # for next index block */ - BF_BLKNUM dataBlock; /* block # for data block */ - int firstDatInf; /* first datInfo in index block */ - int curDatInf; /* current datInfo in index block */ - int lastDatInf; /* last datInfo in index block */ - int i; /* temp for loops */ - chtype type; - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pArCfDesc != NULL); - pChanHdr = &ArCDChanHdr(pArChanDesc); - assert(pChanHdr != NULL); - - if (pChanHdr->newestSecPastEpoch == 0) { - pArChanDesc->flags |= AR_CDESC_EOF; - return ERROR; - } - else if (pPosStamp == NULL || - pPosStamp->secPastEpoch < pChanHdr->oldestSecPastEpoch) { -/*---------------------------------------------------------------------------- -* rewind -* either a rewind was requested, or else the requested stamp is prior -* to the oldest data for the file -*----------------------------------------------------------------------------*/ - pArChanDesc->datInfNum = -10; - pArChanDesc->remainCount = -10; - stat = arCF_DNextBlock(pArChanDesc); - if (stat == ERROR && (pArChanDesc->flags & AR_CDESC_EOF) == 0) - assertAlways(0); - return stat; - } - -/*---------------------------------------------------------------------------- -* search is required -* It isn't known yet whether the search will be forward or reverse. -* If the desired stamp is less than that of the first datInf, -* then a backward search is required. If the desired stamp -* is greater than that of the first datInf, then a forward -* search (possibly confined to this index block) is required. -* -* A special case occurs when the present index block contains no -* datInf's with time stamps. In this case, a backward search is -* done. (This case arises because data blocks which contain only -* data items don't have a time stamp in their datInf entry.) -*----------------------------------------------------------------------------*/ - pIndexBuf = pArChanDesc->pIndexBuf; - lastDatInf = (pIndexBuf->bfInfo.lastByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - while (lastDatInf > 0 && - pIndexBuf->datInfo[lastDatInf].stamp.secPastEpoch == 0) { - lastDatInf--; - } - firstDatInf = (pIndexBuf->bfInfo.firstByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - while (firstDatInf < lastDatInf && - pIndexBuf->datInfo[firstDatInf].stamp.secPastEpoch == 0) { - firstDatInf++; - } - if (firstDatInf > lastDatInf || - TsCmpStampsLT(pPosStamp, &pIndexBuf->datInfo[firstDatInf].stamp)) { -/*---------------------------------------------------------------------------- -* reverse search -* Since the file contains extremely little information to allow -* `going backward', a reverse search is accomplished with a rewind -* followed by a forward search. -*----------------------------------------------------------------------------*/ - pArChanDesc->datInfNum = -10; - pArChanDesc->remainCount = -10; - stat = arCF_INextDatInfo(pArChanDesc); - if (stat == ERROR && (pArChanDesc->flags & AR_CDESC_EOF) == 0) - assertAlways(0); - if (stat == ERROR) - return stat; - } - pIndexBuf = pArChanDesc->pIndexBuf; - lastDatInf = (pIndexBuf->bfInfo.lastByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - while (lastDatInf > 0 && - pIndexBuf->datInfo[lastDatInf].stamp.secPastEpoch == 0) { - lastDatInf--; - } -/*---------------------------------------------------------------------------- -* forward search -*----------------------------------------------------------------------------*/ - while (lastDatInf >= 0 && - TsCmpStampsGT(pPosStamp, &pIndexBuf->datInfo[lastDatInf].stamp)) { -/*---------------------------------------------------------------------------- -* desired position may be in this index block, or it may be in a -* following one. In order to find out, we'll have to read the next -* one and do an explicit check. -*----------------------------------------------------------------------------*/ - indexBlock = pIndexBuf->blkNum; - if ((nextIndexBlock = pIndexBuf->bfInfo.flink) != 0) { - stat = arCF_IRead(pArChanDesc, pIndexBuf, nextIndexBlock); - if (stat == OK) { - lastDatInf = (pIndexBuf->bfInfo.lastByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - while (lastDatInf > 0 && - pIndexBuf->datInfo[lastDatInf].stamp.secPastEpoch == 0) { - lastDatInf--; - } - firstDatInf = (pIndexBuf->bfInfo.firstByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - while (firstDatInf < lastDatInf && - pIndexBuf->datInfo[firstDatInf].stamp.secPastEpoch == 0) { - firstDatInf++; - } - if (firstDatInf > lastDatInf || - TsCmpStampsLE(pPosStamp, - &pIndexBuf->datInfo[firstDatInf].stamp)) { - /* woops!!! time to back up! */ - stat = arCF_IRead(pArChanDesc, pIndexBuf, indexBlock); - if (stat != OK) - assertAlways(0); - else - break; - } - } - else { - /* error reading next block; back up and let normal code - handle the error */ - stat = arCF_IRead(pArChanDesc, pIndexBuf, indexBlock); - if (stat != OK) - assertAlways(0); - else - break; - } - } - else - break; - } -/*---------------------------------------------------------------------------- -* desired position may be somewhere in this index block; this is the -* index block where we'll start narrowing down the search. -* -* First, the datInfo whose stamp is greater than or equal to the -* desired stamp will be found. Then reading will start with the -* preceding datInfo until a stamp equal to or greater than the -* desired stamp is found. -*----------------------------------------------------------------------------*/ - indexBlock = pIndexBuf->blkNum; - lastDatInf = (pIndexBuf->bfInfo.lastByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - while (lastDatInf > 0 && - pIndexBuf->datInfo[lastDatInf].stamp.secPastEpoch == 0) { - lastDatInf--; - } - assert(lastDatInf >= 0); - firstDatInf = (pIndexBuf->bfInfo.firstByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - while (firstDatInf < lastDatInf && - pIndexBuf->datInfo[firstDatInf].stamp.secPastEpoch == 0) { - firstDatInf++; - } - assert(firstDatInf >= 0); - i = curDatInf = firstDatInf; - while (i < lastDatInf) { - if (pIndexBuf->datInfo[i+1].stamp.secPastEpoch == 0) - i++; - else if (TsCmpStampsGE(&pIndexBuf->datInfo[i+1].stamp, pPosStamp)) - break; - else { - i++; - curDatInf = i; - } - } - pArChanDesc->datInfNum = curDatInf; - pArChanDesc->timeStamp= pIndexBuf->datInfo[curDatInf].stamp; - pArChanDesc->remainCount = -10; - stat = arCF_DRead(pArChanDesc, pArChanDesc->pDataBuf, - pIndexBuf->datInfo[curDatInf].dataBlock); - if (stat != OK) - assertAlways(0); - while (1) { - stat = arCFChanReadTs(pArChanDesc); - if (stat != OK) { - if ((pArChanDesc->flags & - (AR_CDESC_BEGIN|AR_CDESC_INACT| - AR_CDESC_SNAP_BEGIN|AR_CDESC_SNAP_END)) == 0) { - retStat = ERROR; - break; - } - } - else if (TsCmpStampsGE(&pArChanDesc->timeStamp, pPosStamp)) - break; - else { - type = dbf_type_to_DBR(ArCFChanFieldType(pArChanDesc)); - stat = arCFChanRead(pArChanDesc, type, (void *)NULL, 0); - if (stat != OK) { - retStat = ERROR; - break; - } - } - } - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCFChanPurge - purge data for a channel of an AR channel data file -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o doesn't update oldestSecPastEpoch and newestSecPastEpoch -* o doesn't initialize the read/write items in the chanDesc -* o always does TOTAL purge, ignoring requested time stamp -* o there are some critical sections unprotected -* - between malloc() and storing pointer in descriptor -* - between releasing blocks and updating pointers and links -* o error handling is shakey, at best -* -* SEE ALSO -* arCFChanDel() -* -* EXAMPLE -* -*-*/ -long -arCFChanPurge(pArChanDesc, pKeepStamp) -AR_CHAN_DESC *pArChanDesc;/* IO pointer to channel descriptor */ -TS_STAMP *pKeepStamp; /* I stamp for oldest data to keep; NULL says - delete all data */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status to caller */ - AR_CHAN_HDR *pChanHdr; /* pointer to chanHdr */ - BF_DESC *pBfDesc; /* pointer to block file descriptor */ - AR_INDEX_BUF *pIndexBuf; /* pointer to buffer for index buffer */ - AR_DATA_BUF *pDataBuf; /* pointer to buffer for data buffer */ - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pArCfDesc != NULL); - pBfDesc = pArChanDesc->pArCfDesc->pBfDesc; - assert(pBfDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - pChanHdr = &ArCDChanHdr(pArChanDesc); - assert(pChanHdr->count > 0); - - if ((pArChanDesc->flags & AR_CDESC_WRITE) == 0) { - (void)fprintf(stderr, "arCFChanPurge: %s not open O_RDWR\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - if (pChanHdr->count > 1) { - (void)fprintf(stderr, "arCFChanPurge: others have %s open\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - -/*---------------------------------------------------------------------------- -* o if a read block is in memory, free it -* o if a write block is in memory, ???? -* o get buffers for index and data blocks, and put their pointers in -* the channel descriptor -* o traverse the index buffer chain, and all the data buffers, freeing -* the appropriate buffers -*---------------------------------------------------------------------------*/ - if (retStat == OK) { - if ((pIndexBuf = arCF_mallocINDEX_BUF()) == NULL) { - (void)fprintf(stderr, "arCFChanPurge: can't malloc to purge %s\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - else - pArChanDesc->pIndexBuf = pIndexBuf; - - if (retStat == OK) { - if ((pDataBuf = arCF_mallocDATA_BUF()) == NULL) { - (void)fprintf(stderr, - "arCFChanPurge: can't malloc to purge %s\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - else - pArChanDesc->pDataBuf = pDataBuf; - } - } - if (retStat == OK) { - BF_BLKNUM indexBlock; /* block # for index block */ - BF_BLKNUM nextIndexBlock; /* block # for next index block */ - BF_BLKNUM dataBlock; /* block # for data block */ - int curDatInf; /* current datInfo in index block */ - int lastDatInf; /* last datInfo in index block */ - - indexBlock = pChanHdr->indexHead; - while (retStat == OK && indexBlock != 0) { - stat = bfRead(pBfDesc, &pIndexBuf->bfInfo, indexBlock); - if (stat == OK) { - nextIndexBlock = pIndexBuf->bfInfo.flink; - pIndexBuf->blkNum = indexBlock; - ArCFModifyInit(pIndexBuf); - pIndexBuf->pBlock = &pIndexBuf->bfInfo; - } - else { - (void)fprintf(stderr, - "arCFChanPurge: bfRead error, indxBlk for %s\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - if (stat == OK && pIndexBuf->bfInfo.lastByte > BF_BLOCK_DATA) { -/*---------------------------------------------------------------------------- -* march through all the datInfo entries in this index block. Use -* firstByte and lastByte to figure out how many datInfo's there are. -* -* for each datInfo entry, -* o read the block -* o release the block to the free block list -* o adjust firstByte in the index block to be past the datInfo just -* processed (this keeps firstByte valid) -* -* BUGS -* o this section of code should actually compare time stamps in datInfo -* with the caller supplied time stamp. If newestSecPastEpoch is newer -* than the caller's time stamp, delete the whole data block; otherwise, -* either the purge is complete, or only part of the data is to be -* purged (which means keeping the datInfo entry, adjusting its -* time stamp value, and adjusting firstByte in the data block). In -* addition, it must be taken into account that the stamps in some -* datInfo are zero--for the data blocks which don't have a time item. -*---------------------------------------------------------------------------*/ - curDatInf = (pIndexBuf->bfInfo.firstByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - lastDatInf = (pIndexBuf->bfInfo.lastByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - - while (curDatInf < lastDatInf && retStat == OK) { - dataBlock = pIndexBuf->datInfo[curDatInf].dataBlock; - stat = bfRead(pBfDesc, &pDataBuf->bfInfo, dataBlock); - if (stat == OK) { - pDataBuf->blkNum = dataBlock; - ArCFModifyInit(pDataBuf); - pDataBuf->pBlock = &pDataBuf->bfInfo; - } - else { - (void)fprintf(stderr, - "arCFChanPurge: bfRead error, dataBlk for %s\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - if (retStat == OK) - stat = bfRelease(pBfDesc, &pDataBuf->bfInfo, dataBlock); - if (stat == OK) { - /* adjust firstByte in index block to indicate that - * this blockInfo entry is no longer valid, just in - * case */ - pIndexBuf->bfInfo.firstByte += sizeof(AR_DAT_INFO); - } - else { - (void)fprintf(stderr, - "arCFChanPurge: bfRelease error, dataBlk for %s\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - curDatInf++; - } - } - if (retStat == OK) { -/*---------------------------------------------------------------------------- -* now release the index block back to the free block list. -* -* set to process the next index block, using the forward link which -* was saved earlier. Also, set the pointer the the index list in the -* chanHdr to point to the next index block. -* -* BUGS -* o if purging by time stamp is being done, then not all datInfo -* structures may have been deleted from the index block. In that case, -* it would be necessary to write the updated index block back to the -* file and leave it as the head of the index block list. -*---------------------------------------------------------------------------*/ - stat = bfRelease(pBfDesc, &pIndexBuf->bfInfo, indexBlock); - if (stat != OK) { - (void)fprintf(stderr, - "arCFChanPurge: bfRelease error, indexBlk for %s\n", - ArCDChanHdr(pArChanDesc).name); - retStat = ERROR; - } - indexBlock = nextIndexBlock; - pChanHdr->indexHead = indexBlock; - } - } - } -/*---------------------------------------------------------------------------- -* final cleanup -* -* BUGS -* o cleanup assumes total purge -*----------------------------------------------------------------------------*/ - arCF_freeDATA_BUF(pDataBuf); - pArChanDesc->pDataBuf = NULL; - arCF_freeINDEX_BUF(pIndexBuf); - pArChanDesc->pIndexBuf = NULL; - pArChanDesc->pData = NULL; - pArChanDesc->remainCount = -10; - pArChanDesc->datInfNum = -10; - if (pChanHdr->indexHead == 0) - pChanHdr->indexTail = 0; - - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - - return retStat; -} - -/*---------------------------------------------------------------------------- -* macros for use by arCFChanRead() and friends -* -* int ArCRFetch fetch as an int the next character from the current -* read buffer; if there isn't a next character -* (or if there isn't a current read buffer), -* get the next read buffer and fetch the -* first available character from it. On error -* or at end of file, returns ERROR. -*---------------------------------------------------------------------------*/ -#define ArCRFetch \ - ( (--pArChanDesc->remainCount >= 0) \ - ? ((int)*(++pArChanDesc->pData))&0xff \ - : arCF_DFillRbufAndGetc(pArChanDesc) ) - -/*+/subr********************************************************************** -* NAME arCFChanRead - read next value from a channel -* -* DESCRIPTION -* This routine reads the next value for a channel and fills in the -* caller's db_access_val union with the value, time stamp, etc. -* as appropriate. -* -* An ERROR return indicates that a valid value wasn't put into the -* caller's buffer. The .flags item in the channel descriptor must be -* examined to determine the reason: -* -* AR_CDESC_EOF indicates that the stream for the channel is at -* end of file -* AR_CDESC_BEGIN indicates that a new run of data is beginning -* for the channel -* AR_CDESC_SNAP_BEGIN indicates that a new run of data is beginning -* for the channel, where the run is a synchronous snapshot -* AR_CDESC_SNAP_END indicates that the following value is the -* last in a snapshot (may occur with AR_CDESC_SNAP_BEGIN) -* AR_CDESC_INACT indicates that the run of data is done, because -* the archive request was inactivated (or disabled) -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o assumes that representation of numbers is the same on `retrieval -* host' as on original `store host' -* o the type of the read request must be the same `flavor' as that of -* the channel--no conversions are provided from short to string, etc. -* o need a way to return to caller number of elements actually read -* -* NOTES -* 1. `count' need not match native count. If the count is less than -* the native count, excess values will be discarded. If the requested -* type is not a `plain' type (e.g., DBR_FLOAT), then information -* will be stored in the caller's buffer even if count is 0 (assuming -* the caller's buffer pointer isn't NULL). -* -*-*/ -long -arCFChanRead(pArChanDesc, type, pAccessBuf, count) -register -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -chtype type; /* I buffer type; DBR_xxx */ -register -union db_access_val *pAccessBuf;/* IO pointer to caller's buffer, or NULL */ -int count; /* I array element count for caller's buffer */ -{ - int retStat=OK; /* return status to caller */ - int nBytes; /* number of value bytes in file item value */ - int countBytes; /* number of bytes allowed by caller's buf */ - int i; /* temp for loops */ - int byte0, byteN; /* bytes from the entry */ - char *pBuf; /* temporary pointer for moving data */ - chtype recType; /* type of buffer */ - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - assert(dbr_type_is_valid(type) || count == 0); - assert(pAccessBuf != NULL || count == 0); - assert(count >= 0); - -/*---------------------------------------------------------------------------- -* handle time stamp -* -* (arCFChanReadTs() resets the various flags) -* -* put the proper time stamp information into the access buffer if -* the type is DBR_TIME_xxx. -*----------------------------------------------------------------------------*/ - if ((retStat = arCFChanReadTs(pArChanDesc)) == OK) { - if (dbr_type_is_TIME(type)) - pAccessBuf->tstrval.stamp = pArChanDesc->timeStamp; - } - -/*---------------------------------------------------------------------------- -* handle alarm status/severity if this item has it. If the item does -* have it, process it and then exit this section with a make believe -* item code of value without status. -* -* This section assumes that all DBR_ types which have status have -* the status and severity structure items in the same place as -* struct dbr_sts_string . -*---------------------------------------------------------------------------*/ - if (retStat == OK) { - byte0 = ArCRFetch; - if (byte0 == AR_DAT_IC_VAL_STAT) { - byte0 = ArCRFetch; - byteN = ArCRFetch; - if (!dbr_type_is_plain(type)) { - pAccessBuf->sstrval.status = byte0; - pAccessBuf->sstrval.severity = byteN; - } - if (byteN == ERROR) - retStat = ERROR; - else - byte0 = AR_DAT_IC_VAL; - } - } - -/*---------------------------------------------------------------------------- -* if this is DBR_GR_xxx, get graphics info from chanHdr -*---------------------------------------------------------------------------*/ - if (retStat == OK && dbr_type_is_GR(type)) { - switch (type) { - case DBR_GR_STRING: - break; /* no graphics for string */ - case DBR_GR_SHORT: -#define ArCRShrtGr ArCDChanHdr(pArChanDesc).graphics.shortGr - (void)strcpy(pAccessBuf->gshrtval.units, ArCRShrtGr.units); - pAccessBuf->gshrtval.upper_disp_limit = ArCRShrtGr.upDispLim; - pAccessBuf->gshrtval.lower_disp_limit = ArCRShrtGr.lowDispLim; - pAccessBuf->gshrtval.upper_alarm_limit = ArCRShrtGr.upAlmLim; - pAccessBuf->gshrtval.upper_warning_limit = ArCRShrtGr.upWarnLim; - pAccessBuf->gshrtval.lower_warning_limit = - ArCRShrtGr.lowWarnLim; - pAccessBuf->gshrtval.lower_alarm_limit = ArCRShrtGr.lowAlmLim; - break; - case DBR_GR_LONG: -#define ArCRLngGr ArCDChanHdr(pArChanDesc).graphics.longGr - (void)strcpy(pAccessBuf->glngval.units, ArCRLngGr.units); - pAccessBuf->glngval.upper_disp_limit = ArCRLngGr.upDispLim; - pAccessBuf->glngval.lower_disp_limit = ArCRLngGr.lowDispLim; - pAccessBuf->glngval.upper_alarm_limit = ArCRLngGr.upAlmLim; - pAccessBuf->glngval.upper_warning_limit = ArCRLngGr.upWarnLim; - pAccessBuf->glngval.lower_warning_limit = - ArCRLngGr.lowWarnLim; - pAccessBuf->glngval.lower_alarm_limit = ArCRLngGr.lowAlmLim; - break; - case DBR_GR_CHAR: -#define ArCRChrGr ArCDChanHdr(pArChanDesc).graphics.shortGr - (void)strcpy(pAccessBuf->gchrval.units, ArCRChrGr.units); - pAccessBuf->gchrval.upper_disp_limit = ArCRChrGr.upDispLim; - pAccessBuf->gchrval.lower_disp_limit = ArCRChrGr.lowDispLim; - pAccessBuf->gchrval.upper_alarm_limit = ArCRChrGr.upAlmLim; - pAccessBuf->gchrval.upper_warning_limit = ArCRChrGr.upWarnLim; - pAccessBuf->gchrval.lower_warning_limit = ArCRChrGr.lowWarnLim; - pAccessBuf->gchrval.lower_alarm_limit = ArCRChrGr.lowAlmLim; - break; - case DBR_GR_FLOAT: -#define ArCRFltGr ArCDChanHdr(pArChanDesc).graphics.floatGr - pAccessBuf->gfltval.precision = ArCRFltGr.precision; - (void)strcpy(pAccessBuf->gfltval.units, ArCRFltGr.units); - pAccessBuf->gfltval.upper_disp_limit = ArCRFltGr.upDispLim; - pAccessBuf->gfltval.lower_disp_limit = ArCRFltGr.lowDispLim; - pAccessBuf->gfltval.upper_alarm_limit = ArCRFltGr.upAlmLim; - pAccessBuf->gfltval.upper_warning_limit = ArCRFltGr.upWarnLim; - pAccessBuf->gfltval.lower_warning_limit = ArCRFltGr.lowWarnLim; - pAccessBuf->gfltval.lower_alarm_limit = ArCRFltGr.lowAlmLim; - break; - case DBR_GR_DOUBLE: -#define ArCRDblGr ArCDChanHdr(pArChanDesc).graphics.doubleGr - pAccessBuf->gdblval.precision = ArCRDblGr.precision; - (void)strcpy(pAccessBuf->gdblval.units, ArCRDblGr.units); - pAccessBuf->gdblval.upper_disp_limit = ArCRDblGr.upDispLim; - pAccessBuf->gdblval.lower_disp_limit = ArCRDblGr.lowDispLim; - pAccessBuf->gdblval.upper_alarm_limit = ArCRDblGr.upAlmLim; - pAccessBuf->gdblval.upper_warning_limit = ArCRDblGr.upWarnLim; - pAccessBuf->gdblval.lower_warning_limit = ArCRDblGr.lowWarnLim; - pAccessBuf->gdblval.lower_alarm_limit = ArCRDblGr.lowAlmLim; - break; - case DBR_GR_ENUM: -#define ArCREnmGr ArCDChanHdr(pArChanDesc).graphics.enumGr.pGRBuf - pAccessBuf->genmval.no_str = ArCREnmGr->numStrings; - for (i=0; inumStrings; i++) { - (void)strcpy(pAccessBuf->genmval.strs[i], - ArCREnmGr->states[i]); - } - break; - default: - (void)fprintf(stderr, "arCFChanRead: unimplemented GR type\n"); - retStat = ERROR; - break; - } - } - -/*---------------------------------------------------------------------------- -* now handle the value item. Only the actual values are handled here, since -* status, time stamp, etc. have already been handled. -*---------------------------------------------------------------------------*/ - if (retStat != OK) - ; /* no action */ - else if (byte0 != AR_DAT_IC_VAL) { - (void)fprintf(stderr, "arCFChanRead: unexpected item code %d\n", byte0); - retStat = ERROR; - } - else { - assert(dbr_type_is_valid(type)); - recType = ArCDChanHdr(pArChanDesc).chanType; - if (count <= 0) pBuf = NULL; - else pBuf = ((char *)dbr_value_ptr(pAccessBuf, type)) - 1; - /* set byte count one byte shy to allow checking status on the - last one. This is done as a time saving measure */ - nBytes = ArCDChanHdr(pArChanDesc).elCount*dbr_value_size[recType] - 1; - countBytes = count * dbr_value_size[recType]; - for (i=0; i nBytes) *(++pBuf) = byteN; - if (byteN == ERROR) retStat = ERROR; - } - - return retStat; -} - -/*+/internal****************************************************************** -* NAME arCFChanReadTs - read and process time stamp items -* -* DESCRIPTION -* This routine reads successive items until a non-time stamp item -* is found. The chanDesc time stamp is updated appropriately. -* -* End of file results in an error return, with the AR_CDESC_EOF flag -* set in chanDesc.flags . -* -* Encountering one of the AR_DAT_IC_MON_xxx flags results in an error -* return, with an appropriate AR_CDESC_xxx flag set in chanDesc.flags . -* -* RETURNS -* OK, or -* ERROR -* -*-*/ -long -arCFChanReadTs(pArChanDesc) -register -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -{ - int retStat=OK; /* return status to caller */ - TS_STAMP timeDel; /* delta time */ - int byte0, byteN; /* bytes from the entry */ - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - - /* turn off various flags */ - pArChanDesc->flags &= ~(AR_CDESC_EOF | AR_CDESC_BEGIN | AR_CDESC_INACT | - AR_CDESC_SNAP_BEGIN | AR_CDESC_SNAP_END | - AR_CDESC_DISCON | AR_CDESC_SUP); - -/*---------------------------------------------------------------------------- -* handle time stamp -* -* if the first byte indicates a time stamp, process it, -* updating the time information in the channel descriptor. -* -* this section of code loops until a non-time item is found, since -* several time related items can follow each other. The chanDesc -* is left so that the next read will start with the non-time item. -* -* this section assumes that all DBR_ types which have time have -* the the time structure items in the same place as -* struct dbr_time_string . -*---------------------------------------------------------------------------*/ - while (retStat == OK) { - timeDel.secPastEpoch = 0; - timeDel.nsec = 0; - if ( (byte0 = ArCRFetch) != ERROR) { - if ((byte0 & 0x80) == 0) { /* delta time, milli-sec */ - if ( (byteN = ArCRFetch) != ERROR) { - if ((timeDel.nsec = ((byte0<<8) + byteN)) < 1000) - timeDel.nsec *= 1000000; - else { - timeDel.secPastEpoch = timeDel.nsec / 1000; - timeDel.nsec = 1000000 * (timeDel.nsec % 1000); - } - TsAddStamps(&pArChanDesc->timeStamp, - &pArChanDesc->timeStamp, &timeDel); - } - else - retStat = ERROR; - } - else if (byte0 == AR_DAT_IC_MON_BEGIN) { /* begin monitor */ - pArChanDesc->flags |= AR_CDESC_BEGIN; - retStat = ERROR; - } - else if (byte0 == AR_DAT_IC_SNAP_BEGIN) { /* begin snapshot */ - pArChanDesc->flags |= AR_CDESC_SNAP_BEGIN; - retStat = ERROR; - } - else if (byte0 == AR_DAT_IC_SNAP_SINGLE) { /* 1 sample snapshot */ - pArChanDesc->flags |= AR_CDESC_SNAP_BEGIN | AR_CDESC_SNAP_END; - retStat = ERROR; - } - else if (byte0 == AR_DAT_IC_SNAP_END) { /* end snapshot */ - pArChanDesc->flags |= AR_CDESC_SNAP_END; - retStat = ERROR; - } - else if (byte0 == AR_DAT_IC_MON_INACT) { /* req inactivated */ - pArChanDesc->flags |= AR_CDESC_INACT; - retStat = ERROR; - } - else if (byte0 == AR_DAT_IC_MON_DISCON) { /* chan disconnected */ - pArChanDesc->flags |= AR_CDESC_DISCON; - retStat = ERROR; - } - else if ((byte0 & 0xf0) != AR_DAT_IC_TIME_XXX) { - pArChanDesc->remainCount++; /* `un-read' the byte */ - pArChanDesc->pData--; - goto timeDone; /* not a time code; bail out */ - } - else if (byte0 == AR_DAT_IC_TIME_STAMP) { - timeDel.secPastEpoch = ArCRFetch <<8; - timeDel.secPastEpoch = (timeDel.secPastEpoch + ArCRFetch)<<8; - timeDel.secPastEpoch = (timeDel.secPastEpoch + ArCRFetch)<<8; - timeDel.secPastEpoch += (byteN = ArCRFetch); - if (byteN != ERROR) - pArChanDesc->timeStamp = timeDel; - else - retStat = ERROR; - } - else if (byte0 == AR_DAT_IC_TIME_USEC) { /* delta time, micro-sec */ - timeDel.nsec = ArCRFetch <<8; - timeDel.nsec = (timeDel.nsec + ArCRFetch)<<8; - if ((timeDel.nsec += (byteN = ArCRFetch)) < 1000000) - timeDel.nsec *= 1000; - else { - timeDel.secPastEpoch = timeDel.nsec / 1000000; - timeDel.nsec = 1000 * (timeDel.nsec % 1000000); - } - if (byteN != ERROR) { - TsAddStamps(&pArChanDesc->timeStamp, - &pArChanDesc->timeStamp, &timeDel); - } - else - retStat = ERROR; - } - else if (byte0 == AR_DAT_IC_TIME_NSEC) { /* delta time, nano-sec */ - timeDel.nsec = ArCRFetch <<8; - timeDel.nsec = (timeDel.nsec + ArCRFetch)<<8; - timeDel.nsec = (timeDel.nsec + ArCRFetch)<<8; - timeDel.nsec += (byteN = ArCRFetch); - if (byteN != ERROR) { - TsAddStamps(&pArChanDesc->timeStamp, - &pArChanDesc->timeStamp, &timeDel); - } - else - retStat = ERROR; - } - else - assertAlways(0); /* not one of the expected codes */ - - } - if (byte0 == ERROR) - retStat = ERROR; - } -timeDone: /* must FOLLOW the while loop */ - return retStat; -} - -/*---------------------------------------------------------------------------- -* macros for use by arCFChanWrite() and friends -* -* int ArCWStore(c) insert character into current write buffer; if -* there isn't room (or if there isn't a current -* buffer) flush current buffer and insert -* character into new buffer -* -* int ArCWFlushAndStore(c) flush current write buffer (if any) and -* insert character into new buffer -*---------------------------------------------------------------------------*/ -#define ArCWFlushAndStore(c) ArCFFlushAndStore((c), pArChanDesc) -#define ArCWStore(c) ArCFStore((c), pArChanDesc) - -/*+/subr********************************************************************** -* NAME arCFChanWrite - write a channel access buffer to a channel -* -* DESCRIPTION -* This routine accepts an event_handler_args structure for a channel and -* writes time stamp, alarm status/severity, and value(s) to the -* channel data file for the channel. The buffer must be one of the -* DBR_TIME_xxx types. -* -* The header information for the channel must exist prior to calling -* this routine. In addition, the buffer type must agree with the -* native type stored in the header (e.g., if buffer type is -* DBR_TIME_SHORT, then the header must indicate DBF_SHORT). If -* any of these requirements are violated, then no write is done and -* ERROR status is returned. -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o error handling needs to be validated -* o no attention is paid to issues related to calling this routine from -* Channel Access event handler. In particular, there should be -* queues and tasks for: receiving full buffers from this routine; -* supplying empty buffers to this routine; and supplying free blocks -* to this routine. THIS ROUTINE SHOULD NEVER BLOCK!!! -* -* NOTES -* 1. This routine uses the smallest delta time item consistent with the -* significance present in the .nsec member of the time stamp. E.g., -* if .nsec is a multiple of 1000000, then a milli-sec delta time will -* be used. -* -*-*/ -long -arCFChanWrite(pArChanDesc, pArg) -register -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -struct event_handler_args *pArg;/* I pointer to monitor structure */ -{ -#define CW_NSEC ((struct dbr_time_string *)pCaBuf)->stamp.nsec -#define CW_SPE ((struct dbr_time_string *)pCaBuf)->stamp.secPastEpoch - register - void *pCaBuf; /* pointer to buffer */ - - int stat; /* status from calls */ - int deltaCode; /* AR_DAT_IC_TIME_xxx code for delta time */ - int deltaCount; /* count of bytes to represent delta time */ - TS_STAMP diff; /* difference between data stamp and chanDesc */ - ULONG fraction; /* fractional part of second, units vary */ - int fracCode; /* AR_DAT_IC_TIME_xxx code for delta time */ - int fracCount; /* count of bytes to represent delta time */ - register - char *ptr; /* temp for pointer in loops */ - register - char *ptrEnd; /* temp for pointer bound in loops */ - -/*---------------------------------------------------------------------------- -* get some stuff out of the structure supplied as input pArg -*---------------------------------------------------------------------------*/ - pCaBuf = pArg->dbr; - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - assert(pCaBuf != NULL); - if (!dbr_type_is_TIME(pArg->type)) - goto error; - if (pArg->count != ArCDChanHdr(pArChanDesc).elCount) - goto error; /* ignore changed count */ - - pArChanDesc->flags &= ~AR_CDESC_SUP; /* turn off suppress */ - -/*---------------------------------------------------------------------------- -* time stamp handling -* -* (This is done 'in-line' as an optimization strategy. When done as a -* separate routine, this used as much CPU time as all the rest of -* arCFChanWrite() used for status and data for DBR_TIME_FLOAT.) -* -* NOTES -* 1. A lot of the logic in this routine is in support of the rule that -* when a "time item" is used, the item can't cross a block -* boundary. -*---------------------------------------------------------------------------*/ - - if (TsCmpStampsLE(&((struct dbr_time_string *)pCaBuf)->stamp, - &pArChanDesc->timeStamp)) { - goto ignore; /* ignore time running backward */ - } - if (ArCDDatInfo(pArChanDesc).stamp.secPastEpoch == 0) { -/*---------------------------------------------------------------------------- -* case 1 -* this is the first item which has its beginning in this block. A -* time stamp in the datInfo is needed; there must be enough room -* in the block to avoid starting a new block--i.e., to hold the item -* code for the data entry. -* -* Since this is the first item which has its beginning in this block, -* datInfo.stamp must be set. The .firstByte item may also need to be set. -* -* This may also be the first item for the channel. If this is the case, -* then .oldestSecPastEpoch in chanHdr needs to be set. -*---------------------------------------------------------------------------*/ - if (pArChanDesc->remainCount < 1) { - if (ArCWFlushAndStore(AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - else { - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - if (pArChanDesc->pDataBuf->bfInfo.firstByte == 0) { - pArChanDesc->pDataBuf->bfInfo.firstByte = pArChanDesc->pData - - (char *)(&pArChanDesc->pDataBuf->bfInfo); - } - ArCDDatInfo(pArChanDesc).stamp = - ((struct dbr_time_string *)pCaBuf)->stamp; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pIndexBuf); - - if (ArCDChanHdr(pArChanDesc).oldestSecPastEpoch == 0) { - ArCDChanHdr(pArChanDesc).oldestSecPastEpoch = CW_SPE; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - } - } - else { -/*---------------------------------------------------------------------------- -* not first item beginning in this block. Figure out first what's -* going to be needed to handle the time stamp. The questions are: -* o without loss of significance, what type of delta time item is -* required? For that type of delta time item, is the delta time -* less than the maximum? If so, is there enough space left in the -* block to hold the delta time item and the first byte of a data item? -* o if a delta time item can't be used or if there isn't enough room -* in the block, then a full time stamp is needed. -*---------------------------------------------------------------------------*/ - TsDiffAsStamp(&diff, &((struct dbr_time_string *)pCaBuf)->stamp, - &pArChanDesc->timeStamp); - if (diff.nsec % 1000000 == 0 && diff.secPastEpoch < 30 && - pArChanDesc->remainCount >= 2+1) { -/*---------------------------------------------------------------------------- -* case 2 -* the change can be represented as a delta milli-second (and, there is -* room enough to store the item and the first byte of value) -*----------------------------------------------------------------------------*/ - fraction = diff.secPastEpoch*1000 + diff.nsec/1000000; - (void)ArCWStore( fraction>> 8 ); - (void)ArCWStore( fraction ); - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - else if (diff.nsec % 1000 == 0 && diff.secPastEpoch < 15 && - pArChanDesc->remainCount >= 4+1) { -/*---------------------------------------------------------------------------- -* case 3 -* the change can be represented as a delta micro-second (and, there is -* room enough to store the item and the first byte of value) -*----------------------------------------------------------------------------*/ - fraction = diff.secPastEpoch*1000000 + diff.nsec/1000; - (void)ArCWStore( AR_DAT_IC_TIME_USEC ); - (void)ArCWStore( fraction>>16 ); - (void)ArCWStore( fraction>> 8 ); - (void)ArCWStore( fraction ); - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - else if (diff.secPastEpoch < 4 && pArChanDesc->remainCount >= 5+1) { -/*---------------------------------------------------------------------------- -* case 4 -* the change can be represented as a delta nano-second (and, there is -* room enough to store the item and the first byte of value) -*----------------------------------------------------------------------------*/ - fraction = diff.secPastEpoch*1000000000 + diff.nsec; - (void)ArCWStore( AR_DAT_IC_TIME_NSEC ); - (void)ArCWStore( fraction>>24 ); - (void)ArCWStore( fraction>>16 ); - (void)ArCWStore( fraction>> 8 ); - (void)ArCWStore( fraction ); - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - else { -/*---------------------------------------------------------------------------- -* case 5 -* the change is either too large to be accomodated by a delta time -* item or else there isn't enough room left in the block for a delta -* time item followed by the first byte of a data item. If there isn't -* enough space left in the block for the required items, a new block -* will be started. -*---------------------------------------------------------------------------*/ - deltaCode = AR_DAT_IC_TIME_STAMP; /* full time stamp needed */ - deltaCount = 5+1; /* 5 for stamp, 1 for value code */ - if (CW_NSEC == 0) { - fracCount = 2; - fracCode = AR_DAT_IC_TIME_MSEC; /* delta msec */ - /* don't add to deltaCount, since this item is optional */ - fraction = 0; - } - else if (CW_NSEC % 1000000 == 0) { - fracCount = 2; - fracCode = AR_DAT_IC_TIME_MSEC; /* delta msec */ - deltaCount += fracCount; - fraction = CW_NSEC / 1000000; - } - else if (CW_NSEC % 1000 == 0) { - fracCount = 4; - fracCode = AR_DAT_IC_TIME_USEC; /* delta usec */ - deltaCount += fracCount; - fraction = CW_NSEC / 1000; - } - else { - fracCount = 5; - fracCode = AR_DAT_IC_TIME_NSEC; /* delta nsec */ - deltaCount += fracCount; - fraction = CW_NSEC; - } - - if (pArChanDesc->remainCount < deltaCount) { - if (ArCWFlushAndStore(AR_DAT_IC_VAL_STAT ) != OK) - goto error; - pArChanDesc->pDataBuf->bfInfo.firstByte = pArChanDesc->pData - - (char *)(&pArChanDesc->pDataBuf->bfInfo); - ArCDDatInfo(pArChanDesc).stamp = - ((struct dbr_time_string *)pCaBuf)->stamp; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pIndexBuf); - } - else { - (void)ArCWStore(deltaCode ); - (void)ArCWStore(CW_SPE >>24 ); - (void)ArCWStore(CW_SPE >>16 ); - (void)ArCWStore(CW_SPE >> 8 ); - (void)ArCWStore(CW_SPE ); - if (fraction != 0) { - if (fracCode != AR_DAT_IC_TIME_MSEC) { - (void)ArCWStore(fracCode ); - if (fracCode == AR_DAT_IC_TIME_NSEC) - (void)ArCWStore(fraction>>24 ); - (void)ArCWStore(fraction>>16 ); - } - (void)ArCWStore( fraction>> 8 ); - (void)ArCWStore( fraction ); - } - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - } - } - pArChanDesc->timeStamp = ((struct dbr_time_string *)pCaBuf)->stamp; - -/*---------------------------------------------------------------------------- -* now store the status and data. The code above has already stored -* an AR_DAT_IC_VAL_STAT item code in the file. -*----------------------------------------------------------------------------*/ - (void)ArCWStore(((struct dbr_time_string *)pCaBuf)->status); - (void)ArCWStore(((struct dbr_time_string *)pCaBuf)->severity); - if (pArg->type == DBR_TIME_STRING) { -#define ArString ((struct dbr_time_string *)pCaBuf) - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_STRING); - ptr = (char *)(ArString->value); - ptrEnd = ptr + pArg->count*db_strval_dim - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; -#undef ArString - } - else if (pArg->type == DBR_TIME_SHORT) { -#define ArShort ((struct dbr_time_short *)pCaBuf) - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_SHORT); - ptr = (char *)(&ArShort->value); - ptrEnd = ptr + pArg->count * sizeof(short) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; -#undef ArShort - } - else if (pArg->type == DBR_TIME_FLOAT) { -#define ArFloat ((struct dbr_time_float *)pCaBuf) - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_FLOAT); - ptr = (char *)(&ArFloat->value); - ptrEnd = ptr + pArg->count * sizeof(float) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; -#undef ArFloat - } - else if (pArg->type == DBR_TIME_LONG) { -#define ArLong ((struct dbr_time_long *)pCaBuf) - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_LONG); - ptr = (char *)(&ArLong->value); - ptrEnd = ptr + pArg->count * sizeof(long) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; -#undef ArLong - } - else if (pArg->type == DBR_TIME_DOUBLE) { -#define ArDouble ((struct dbr_time_double *)pCaBuf) - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_DOUBLE); - ptr = (char *)(&ArDouble->value); - ptrEnd = ptr + pArg->count * sizeof(double) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; -#undef ArDouble - } - else if (pArg->type == DBR_TIME_ENUM) { -#define ArEnum ((struct dbr_time_enum *)pCaBuf) - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_ENUM); - ptr = (char *)(&ArEnum->value); - ptrEnd = ptr + pArg->count * sizeof(short) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; -#undef ArEnum - } - else if (pArg->type == DBR_TIME_CHAR) { -#define ArChar ((struct dbr_time_char *)pCaBuf) - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_CHAR); - ptr = (char *)(&ArChar->value); - ptrEnd = ptr + pArg->count * sizeof(char) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; -#undef ArChar - } - else - assertAlways(0); - -/*----------------------------------------------------------------------------- -* update bookkeeping information -* -* .lastByte -* .modified in data buffer -* .newestStamp in MI buffer -* .modified in MI buffer -*----------------------------------------------------------------------------*/ - if (pArChanDesc->pData != NULL) { - pArChanDesc->pDataBuf->bfInfo.lastByte = pArChanDesc->pData - - (char *)&pArChanDesc->pDataBuf->bfInfo; - assert(pArChanDesc->pDataBuf->bfInfo.lastByte > 0); - assert(pArChanDesc->pDataBuf->bfInfo.lastByte < 2000); - } - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pDataBuf); - ArCDChanHdr(pArChanDesc).newestSecPastEpoch = - pArChanDesc->timeStamp.secPastEpoch; - ArCDChanHdr(pArChanDesc).newestNsec = pArChanDesc->timeStamp.nsec; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - - return OK; -error: - return ERROR; -ignore: - return OK; -#undef CW_NSEC -#undef CW_SPE -} - -/*+/subr********************************************************************** -* NAME arCFChanWrite_args -* -*-*/ -long -arCFChanWrite_args(pArChanDesc, stamp, dbfType, count, pData, alStat, alSevr) -register -AR_CHAN_DESC *pArChanDesc;/* IO pointer to channel descriptor */ -TS_STAMP stamp; /* I time stamp for data */ -chtype dbfType; /* I type of data, one of the DBF_... */ -int count; /* I element count for data */ -void *pData; /* I pointer to actual data */ -int alStat; /* I alarm status for data */ -int alSevr; /* I alarm severity for data */ -{ -#define CW_NSEC stamp.nsec -#define CW_SPE stamp.secPastEpoch - - int stat; /* status from calls */ - int deltaCode; /* AR_DAT_IC_TIME_xxx code for delta time */ - int deltaCount; /* count of bytes to represent delta time */ - TS_STAMP diff; /* difference between data stamp and chanDesc */ - ULONG fraction; /* fractional part of second, units vary */ - int fracCode; /* AR_DAT_IC_TIME_xxx code for delta time */ - int fracCount; /* count of bytes to represent delta time */ - register - char *ptr; /* temp for pointer in loops */ - register - char *ptrEnd; /* temp for pointer bound in loops */ - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - - if (count != ArCDChanHdr(pArChanDesc).elCount) - goto error; /* ignore changed count */ - - pArChanDesc->flags &= ~AR_CDESC_SUP; /* turn off suppress */ - -/*---------------------------------------------------------------------------- -* time stamp handling -* -* (This is done 'in-line' as an optimization strategy. When done as a -* separate routine, this used as much CPU time as all the rest of -* arCFChanWrite() used for status and data for DBR_FLOAT.) -* -* NOTES -* 1. A lot of the logic in this routine is in support of the rule that -* when a "time item" is used, the item can't cross a block -* boundary. -*---------------------------------------------------------------------------*/ - - if (TsCmpStampsLE(&stamp, &pArChanDesc->timeStamp)) - goto ignore; /* ignore time running backward */ - if (ArCDDatInfo(pArChanDesc).stamp.secPastEpoch == 0) { -/*---------------------------------------------------------------------------- -* case 1 -* this is the first item which has its beginning in this block. A -* time stamp in the datInfo is needed; there must be enough room -* in the block to avoid starting a new block--i.e., to hold the item -* code for the data entry. -* -* Since this is the first item which has its beginning in this block, -* datInfo.stamp must be set. The .firstByte item may also need to be set. -* -* This may also be the first item for the channel. If this is the case, -* then .oldestSecPastEpoch in chanHdr needs to be set. -*---------------------------------------------------------------------------*/ - if (pArChanDesc->remainCount < 1) { - if (ArCWFlushAndStore(AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - else { - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - if (pArChanDesc->pDataBuf->bfInfo.firstByte == 0) { - pArChanDesc->pDataBuf->bfInfo.firstByte = pArChanDesc->pData - - (char *)(&pArChanDesc->pDataBuf->bfInfo); - } - ArCDDatInfo(pArChanDesc).stamp = stamp; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pIndexBuf); - - if (ArCDChanHdr(pArChanDesc).oldestSecPastEpoch == 0) { - ArCDChanHdr(pArChanDesc).oldestSecPastEpoch = CW_SPE; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - } - } - else { -/*---------------------------------------------------------------------------- -* not first item beginning in this block. Figure out first what's -* going to be needed to handle the time stamp. The questions are: -* o without loss of significance, what type of delta time item is -* required? For that type of delta time item, is the delta time -* less than the maximum? If so, is there enough space left in the -* block to hold the delta time item and the first byte of a data item? -* o if a delta time item can't be used or if there isn't enough room -* in the block, then a full time stamp is needed. -*---------------------------------------------------------------------------*/ - TsDiffAsStamp(&diff, &stamp, &pArChanDesc->timeStamp); - if (diff.nsec % 1000000 == 0 && diff.secPastEpoch < 30 && - pArChanDesc->remainCount >= 2+1) { -/*---------------------------------------------------------------------------- -* case 2 -* the change can be represented as a delta milli-second (and, there is -* room enough to store the item and the first byte of value) -*----------------------------------------------------------------------------*/ - fraction = diff.secPastEpoch*1000 + diff.nsec/1000000; - (void)ArCWStore( fraction>> 8 ); - (void)ArCWStore( fraction ); - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - else if (diff.nsec % 1000 == 0 && diff.secPastEpoch < 15 && - pArChanDesc->remainCount >= 4+1) { -/*---------------------------------------------------------------------------- -* case 3 -* the change can be represented as a delta micro-second (and, there is -* room enough to store the item and the first byte of value) -*----------------------------------------------------------------------------*/ - fraction = diff.secPastEpoch*1000000 + diff.nsec/1000; - (void)ArCWStore( AR_DAT_IC_TIME_USEC ); - (void)ArCWStore( fraction>>16 ); - (void)ArCWStore( fraction>> 8 ); - (void)ArCWStore( fraction ); - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - else if (diff.secPastEpoch < 4 && pArChanDesc->remainCount >= 5+1) { -/*---------------------------------------------------------------------------- -* case 4 -* the change can be represented as a delta nano-second (and, there is -* room enough to store the item and the first byte of value) -*----------------------------------------------------------------------------*/ - fraction = diff.secPastEpoch*1000000000 + diff.nsec; - (void)ArCWStore( AR_DAT_IC_TIME_NSEC ); - (void)ArCWStore( fraction>>24 ); - (void)ArCWStore( fraction>>16 ); - (void)ArCWStore( fraction>> 8 ); - (void)ArCWStore( fraction ); - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - else { -/*---------------------------------------------------------------------------- -* case 5 -* the change is either too large to be accomodated by a delta time -* item or else there isn't enough room left in the block for a delta -* time item followed by the first byte of a data item. If there isn't -* enough space left in the block for the required items, a new block -* will be started. -*---------------------------------------------------------------------------*/ - deltaCode = AR_DAT_IC_TIME_STAMP; /* full time stamp needed */ - deltaCount = 5+1; /* 5 for stamp, 1 for value code */ - if (CW_NSEC == 0) { - fracCount = 2; - fracCode = AR_DAT_IC_TIME_MSEC; /* delta msec */ - /* don't add to deltaCount, since this item is optional */ - fraction = 0; - } - else if (CW_NSEC % 1000000 == 0) { - fracCount = 2; - fracCode = AR_DAT_IC_TIME_MSEC; /* delta msec */ - deltaCount += fracCount; - fraction = CW_NSEC / 1000000; - } - else if (CW_NSEC % 1000 == 0) { - fracCount = 4; - fracCode = AR_DAT_IC_TIME_USEC; /* delta usec */ - deltaCount += fracCount; - fraction = CW_NSEC / 1000; - } - else { - fracCount = 5; - fracCode = AR_DAT_IC_TIME_NSEC; /* delta nsec */ - deltaCount += fracCount; - fraction = CW_NSEC; - } - - if (pArChanDesc->remainCount < deltaCount) { - if (ArCWFlushAndStore(AR_DAT_IC_VAL_STAT ) != OK) - goto error; - pArChanDesc->pDataBuf->bfInfo.firstByte = pArChanDesc->pData - - (char *)(&pArChanDesc->pDataBuf->bfInfo); - ArCDDatInfo(pArChanDesc).stamp = stamp; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pIndexBuf); - } - else { - (void)ArCWStore(deltaCode ); - (void)ArCWStore(CW_SPE >>24 ); - (void)ArCWStore(CW_SPE >>16 ); - (void)ArCWStore(CW_SPE >> 8 ); - (void)ArCWStore(CW_SPE ); - if (fraction != 0) { - if (fracCode != AR_DAT_IC_TIME_MSEC) { - (void)ArCWStore(fracCode ); - if (fracCode == AR_DAT_IC_TIME_NSEC) - (void)ArCWStore(fraction>>24 ); - (void)ArCWStore(fraction>>16 ); - } - (void)ArCWStore( fraction>> 8 ); - (void)ArCWStore( fraction ); - } - if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK) - goto error; - } - } - } - pArChanDesc->timeStamp = stamp; - -/*---------------------------------------------------------------------------- -* now store the status and data. The code above has already stored -* an AR_DAT_IC_VAL_STAT item code in the file. -*----------------------------------------------------------------------------*/ - (void)ArCWStore(alStat); - (void)ArCWStore(alSevr); - if (dbfType == DBF_STRING) { - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_STRING); - ptr = (char *)(struct dbf_string *)pData; - ptrEnd = ptr + count*db_strval_dim - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; - } - else if (dbfType == DBF_SHORT) { - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_SHORT); - ptr = (char *)(struct dbf_short *)pData; - ptrEnd = ptr + count * sizeof(short) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; - } - else if (dbfType == DBF_FLOAT) { - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_FLOAT); - ptr = (char *)(struct dbf_float *)pData; - ptrEnd = ptr + count * sizeof(float) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; - } - else if (dbfType == DBF_LONG) { - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_LONG); - ptr = (char *)(struct dbf_long *)pData; - ptrEnd = ptr + count * sizeof(long) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; - } - else if (dbfType == DBF_DOUBLE) { - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_DOUBLE); - ptr = (char *)(struct dbf_double *)pData; - ptrEnd = ptr + count * sizeof(double) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; - } - else if (dbfType == DBF_ENUM) { - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_ENUM); - ptr = (char *)(struct dbf_enum *)pData; - ptrEnd = ptr + count * sizeof(short) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; - } - else if (dbfType == DBF_CHAR) { - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_CHAR); - ptr = (char *)(struct dbf_char *)pData; - ptrEnd = ptr + count * sizeof(char) - 1; - while (ptr < ptrEnd) - (void)ArCWStore(*ptr++); - if (ArCWStore(*ptr++) != OK) goto error; - } - else - assertAlways(0); - -/*----------------------------------------------------------------------------- -* update bookkeeping information -* -* .lastByte -* .modified in data buffer -* .newestStamp in MI buffer -* .modified in MI buffer -*----------------------------------------------------------------------------*/ - if (pArChanDesc->pData != NULL) { - pArChanDesc->pDataBuf->bfInfo.lastByte = pArChanDesc->pData - - (char *)&pArChanDesc->pDataBuf->bfInfo; - assert(pArChanDesc->pDataBuf->bfInfo.lastByte > 0); - assert(pArChanDesc->pDataBuf->bfInfo.lastByte < 2000); - } - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pDataBuf); - ArCDChanHdr(pArChanDesc).newestSecPastEpoch = - pArChanDesc->timeStamp.secPastEpoch; - ArCDChanHdr(pArChanDesc).newestNsec = pArChanDesc->timeStamp.nsec; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - - return OK; -error: - return ERROR; -ignore: - return OK; -#undef CW_NSEC -#undef CW_SPE -} - -/*+/subr********************************************************************** -* NAME arCFChanWriteByte - write byte into a channel's stream -* -* DESCRIPTION -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o text -* -*-*/ -long -arCFChanWriteByte(pArChanDesc, value) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -int value; /* I value to write to stream */ -{ - int stat; /* status from calls */ - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - - pArChanDesc->flags &= ~AR_CDESC_SUP; /* turn off suppress */ - - if (pArChanDesc->remainCount < 1) { - if (ArCWFlushAndStore(value ) != OK) - goto error; - } - else { - if (ArCWStore( value ) != OK) - goto error; - } - if (pArChanDesc->pDataBuf->bfInfo.firstByte == 0) { - pArChanDesc->pDataBuf->bfInfo.firstByte = pArChanDesc->pData - - (char *)(&pArChanDesc->pDataBuf->bfInfo); - } - pArChanDesc->pDataBuf->bfInfo.lastByte = pArChanDesc->pData - - (char *)(&pArChanDesc->pDataBuf->bfInfo); - assert(pArChanDesc->pDataBuf->bfInfo.lastByte > 0); - assert(pArChanDesc->pDataBuf->bfInfo.lastByte < 2000); - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pDataBuf); - - return OK; -error: - return ERROR; -} - -/*+/subr********************************************************************** -* NAME arCFChanWriteGR - write a channel access DBR_GR buffer to a channel -* -* DESCRIPTION -* This routine writes DBR_GR_xxx information to the chanHdr for a -* channel. -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o text -* -* NOTES -* 1. This routine does NOT write a value to the file. -* -*-*/ -long -arCFChanWriteGR(pArChanDesc, pArg) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -struct event_handler_args *pArg;/* I pointer to monitor structure */ -{ - void *pCaBuf; /* pointer to buffer */ - int i; - long stat; - -/*---------------------------------------------------------------------------- -* get some stuff out of the structure supplied as input pArg -*---------------------------------------------------------------------------*/ - pCaBuf = pArg->dbr; - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - assert(pCaBuf != NULL); - assert(dbr_type_is_GR(pArg->type)); - - if (pArg->type == DBR_GR_STRING) { - ArCDChanHdr(pArChanDesc).chanType = DBF_STRING; - ArCDChanHdr(pArChanDesc).elCount = pArg->count; - } - else if (pArg->type == DBR_GR_SHORT) { -#define ArCWShrtGr ArCDChanHdr(pArChanDesc).graphics.shortGr -#define ArCWgr_short ((struct dbr_gr_short *)pCaBuf) - - ArCDChanHdr(pArChanDesc).chanType = DBF_SHORT; - ArCDChanHdr(pArChanDesc).elCount = pArg->count; - (void)strcpy(ArCWShrtGr.units, ArCWgr_short->units); - ArCWShrtGr.upDispLim = ArCWgr_short->upper_disp_limit; - ArCWShrtGr.lowDispLim = ArCWgr_short->lower_disp_limit; - ArCWShrtGr.upAlmLim = ArCWgr_short->upper_alarm_limit; - ArCWShrtGr.upWarnLim = ArCWgr_short->upper_warning_limit; - ArCWShrtGr.lowWarnLim = ArCWgr_short->lower_warning_limit; - ArCWShrtGr.lowAlmLim = ArCWgr_short->lower_alarm_limit; - } - else if (pArg->type == DBR_GR_FLOAT) { -#define ArCWFltGr ArCDChanHdr(pArChanDesc).graphics.floatGr -#define ArCWgr_float ((struct dbr_gr_float *)pCaBuf) - - ArCDChanHdr(pArChanDesc).chanType = DBF_FLOAT; - ArCDChanHdr(pArChanDesc).elCount = pArg->count; - ArCWFltGr.precision = ArCWgr_float->precision; - (void)strcpy(ArCWFltGr.units, ArCWgr_float->units); - ArCWFltGr.upDispLim = ArCWgr_float->upper_disp_limit; - ArCWFltGr.lowDispLim = ArCWgr_float->lower_disp_limit; - ArCWFltGr.upAlmLim = ArCWgr_float->upper_alarm_limit; - ArCWFltGr.upWarnLim = ArCWgr_float->upper_warning_limit; - ArCWFltGr.lowWarnLim = ArCWgr_float->lower_warning_limit; - ArCWFltGr.lowAlmLim = ArCWgr_float->lower_alarm_limit; - } - else if (pArg->type == DBR_GR_LONG) { -#define ArCWLngGr ArCDChanHdr(pArChanDesc).graphics.longGr -#define ArCWgr_long ((struct dbr_gr_long *)pCaBuf) - - ArCDChanHdr(pArChanDesc).chanType = DBF_LONG; - ArCDChanHdr(pArChanDesc).elCount = pArg->count; - (void)strcpy(ArCWLngGr.units, ArCWgr_long->units); - ArCWLngGr.upDispLim = ArCWgr_long->upper_disp_limit; - ArCWLngGr.lowDispLim = ArCWgr_long->lower_disp_limit; - ArCWLngGr.upAlmLim = ArCWgr_long->upper_alarm_limit; - ArCWLngGr.upWarnLim = ArCWgr_long->upper_warning_limit; - ArCWLngGr.lowWarnLim = ArCWgr_long->lower_warning_limit; - ArCWLngGr.lowAlmLim = ArCWgr_long->lower_alarm_limit; - } - else if (pArg->type == DBR_GR_DOUBLE) { -#define ArCWDblGr ArCDChanHdr(pArChanDesc).graphics.doubleGr -#define ArCWgr_double ((struct dbr_gr_double *)pCaBuf) - - ArCDChanHdr(pArChanDesc).chanType = DBF_DOUBLE; - ArCDChanHdr(pArChanDesc).elCount = pArg->count; - ArCWDblGr.precision = ArCWgr_double->precision; - (void)strcpy(ArCWDblGr.units, ArCWgr_double->units); - ArCWDblGr.upDispLim = ArCWgr_double->upper_disp_limit; - ArCWDblGr.lowDispLim = ArCWgr_double->lower_disp_limit; - ArCWDblGr.upAlmLim = ArCWgr_double->upper_alarm_limit; - ArCWDblGr.upWarnLim = ArCWgr_double->upper_warning_limit; - ArCWDblGr.lowWarnLim = ArCWgr_double->lower_warning_limit; - ArCWDblGr.lowAlmLim = ArCWgr_double->lower_alarm_limit; - } - else if (pArg->type == DBR_GR_ENUM) { -/*---------------------------------------------------------------------------- -* Store the graphics info into the graphics buffer, set the modified -* bit for the buffer, and also set lastByte for the disk block. -*---------------------------------------------------------------------------*/ -#define ArCWEnmGr ArCDChanHdr(pArChanDesc).graphics.enumGr.pGRBuf -#define ArCWgr_enum ((struct dbr_gr_enum *)pCaBuf) - - if (ArCDChanHdr(pArChanDesc).chanType == DBF_ENUM) { - assert(ArCWEnmGr != NULL); /* better have a buffer */ - assert(ArCWEnmGr->blkNum != 0); /* it must contain a block */ - } - else { - ArCDChanHdr(pArChanDesc).chanType = DBF_ENUM; - if ((stat = arCF_GRGetBlock(pArChanDesc)) != OK) - assertAlways(0); - } - - ArCDChanHdr(pArChanDesc).elCount = pArg->count; - ArCWEnmGr->numStrings = ArCWgr_enum->no_str; - for (i=0; inumStrings; i++) - (void)strcpy(ArCWEnmGr->states[i], ArCWgr_enum->strs[i]); - ArCWEnmGr->bfInfo.lastByte = BF_BLOCK_DATA + 2 + - ArCWEnmGr->numStrings * db_state_text_dim - 1; - stat = bfWrite(pArChanDesc->pArCfDesc->pBfDesc, - &ArCWEnmGr->bfInfo, ArCWEnmGr->blkNum); - if (stat != OK) { - (void)fprintf(stderr, "arCFWriteGR: error writing GR block\n"); - assertAlways(0); - } - } - else if (pArg->type == DBR_GR_CHAR) { -#define ArCWChrGr ArCDChanHdr(pArChanDesc).graphics.charGr -#define ArCWgr_char ((struct dbr_gr_char *)pCaBuf) - - ArCDChanHdr(pArChanDesc).chanType = DBF_CHAR; - ArCDChanHdr(pArChanDesc).elCount = pArg->count; - (void)strcpy(ArCWChrGr.units, ArCWgr_char->units); - ArCWChrGr.upDispLim = ArCWgr_char->upper_disp_limit; - ArCWChrGr.lowDispLim = ArCWgr_char->lower_disp_limit; - ArCWChrGr.upAlmLim = ArCWgr_char->upper_alarm_limit; - ArCWChrGr.upWarnLim = ArCWgr_char->upper_warning_limit; - ArCWChrGr.lowWarnLim = ArCWgr_char->lower_warning_limit; - ArCWChrGr.lowAlmLim = ArCWgr_char->lower_alarm_limit; - } - else { - assertAlways(0); - } - - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - - return OK; -} - -/*+/subr********************************************************************** -* NAME arCFClose - close an AR channel data file -* -* DESCRIPTION -* Closes an AR channel data file. If the file was open in O_RDWR -* mode, then buffers are flushed and the lock file is deleted. -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o text -* -* SEE ALSO -* arCFOpen(), arCFCreate() -* -* EXAMPLE -* -*-*/ -long -arCFClose(ppArCfDesc) -AR_CF_DESC **ppArCfDesc; /* IO ptr to ptr to channel file descriptor */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status */ - AR_CF_DESC *pCfDesc; /* pointer to channel file descriptor */ - AR_CHAN_DESC *pChanDesc; /* pointer to channel descriptor */ - - assert(ppArCfDesc != NULL); - assert(*ppArCfDesc != NULL); - - pCfDesc = *ppArCfDesc; - - if (pCfDesc->pChanDescHead != NULL) { - assert(pCfDesc->pBfDesc != NULL); - assert(pCfDesc->pChanDescTail != NULL); - - /* close all the channel descriptors */ - while ((pChanDesc = pCfDesc->pChanDescHead) != NULL) { - stat = arCFChanClose(&pChanDesc); - } - - } - - assert(pCfDesc->pChanDescHead == NULL); /* should be closed */ - assert(pCfDesc->pChanDescTail == NULL); - - if (pCfDesc->pMIHead != NULL) { - assert(pCfDesc->pBfDesc != NULL); - assert(pCfDesc->pMITail != NULL); - -/*---------------------------------------------------------------------------- -* check all MI blocks for "MODIFIED" bit, and write those with it set; -* ALL MI blocks will be free()'d. When the entire MI block list has -* been traversed, both MIHead and MITail in the channel file descriptor -* will be null. -* -* As part of the traversal, check each chanHdr for DBF_ENUM channels. -* The GR block may need to be written, and the buffer will need to -* be free()'d. -*---------------------------------------------------------------------------*/ - while (pCfDesc->pMIHead != NULL) { - AR_MI_BUF *pMIBuf; /* pointer to MI block */ - AR_GR_BUF *pGRBuf; /* pointer to GR block */ - int i; - - pMIBuf = pCfDesc->pMIHead; - for (i=0; ichanHdr[i].name[0] == '\0') - ; /* no action */ - else if (pMIBuf->chanHdr[i].chanType == DBF_ENUM && - (pGRBuf=pMIBuf->chanHdr[i].graphics.enumGr.pGRBuf) != NULL) { - if (ArCFModifyTestAndReset(pCfDesc, pGRBuf)) { - stat = bfWrite(pCfDesc->pBfDesc, - &pGRBuf->bfInfo, pGRBuf->blkNum); - if (stat != OK) { - (void)fprintf(stderr, - "arCFClose: error writing GR block\n"); - retStat = ERROR; - } - } - arCF_freeGR_BUF(pGRBuf); - pMIBuf->chanHdr[i].graphics.enumGr.pGRBuf = NULL; - } - } - pCfDesc->pMIHead = pMIBuf->pNextMI; - if ((stat = arCF_MIFlush(pCfDesc, pMIBuf)) != OK) { - (void)fprintf(stderr, "arCFClose: error writing MI block\n"); - retStat = ERROR; - } - arCF_freeMI_BUF(pMIBuf); - } - pCfDesc->pMITail = NULL; - } - - assert(pCfDesc->pMIHead == NULL); - assert(pCfDesc->pMITail == NULL); - - if (pCfDesc->pBfDesc != NULL) { - stat = bfClose(&(*ppArCfDesc)->pBfDesc); - if (stat != OK) { - (void)fprintf(stderr, "arCFClose: error closing block file\n"); - retStat = ERROR; - } - } - - arCF_freeCF_DESC(*ppArCfDesc); - *ppArCfDesc = NULL; - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCFCreate - create an AR channel data file -* -* DESCRIPTION -* Creates an empty 'block file' of type BF_TYPE_CHAN_DATA. The -* maximum size for the file will be set at the number of blocks -* which will fit with the caller specified number of bytes. The -* initial size for the file is 1 block. -* -* If the create is successful, then the file is open in O_RDWR mode -* when control returns to the caller. The channel file descriptor -* and other structures have been set up as would be done by arCFOpen(). -* In addition, a lock file has been created to prevent multiple -* writers. -* -* The block size is forced to be AR_CF_BLKSIZE bytes. -* -* RETURNS -* pointer to channel file descriptor, or -* NULL if the file already exists or if an error occurs on create -* -* BUGS -* o no exit handler is established (see arCFOpen() ) -* -* SEE ALSO -* arCFOpen(), arCFClose(), arCFChanOpen() -* -*-*/ -AR_CF_DESC * -arCFCreate(name, maxBytes) -char *name; /* I file name */ -int maxBytes; /* I maximum number of bytes for file */ -{ - int stat=OK; /* status from calls */ - - BF_BLKNUM maxBlocks; /* size limit */ - BF_DESC *pDesc; /* pointer to block file descriptor */ - AR_CF_DESC *pArCfDesc=NULL;/* pointer to channel file descriptor */ - - assert(strlen(name) < GEN_FNAME_DIM); - assert(strlen(name) > 0); - - -/*---------------------------------------------------------------------------- -* allocate memory for an AR channel file descriptor and initialize the -* descriptor. Then create the block file and put into the channel file -* descriptor a pointer to the block file descriptor. This hides from -* most users the fact that there are actually two descriptors--they -* just use the channel file descriptor. -*---------------------------------------------------------------------------*/ - if ((pArCfDesc = arCF_mallocCF_DESC()) == NULL) { - (void)fprintf(stderr, "arCFCreate: can't malloc for arCfDesc\n"); - stat = ERROR; - } - else { - pArCfDesc->pBfDesc = NULL; - pArCfDesc->pMIHead = NULL; /* no MI buffers yet */ - pArCfDesc->pMITail = NULL; - pArCfDesc->pMIFree = NULL; - pArCfDesc->MIFree_hdrNum = 0; - pArCfDesc->pChanDescHead = NULL; /* no channel desc exist yet */ - pArCfDesc->pChanDescTail = NULL; - pArCfDesc->pWriteHead = NULL; - pArCfDesc->pWriteTail = NULL; - pArCfDesc->b0Modified = 0; - } - - if (maxBytes < AR_CF_BLKSIZE) { - (void)printf("nBytes must be at least %d\n", AR_CF_BLKSIZE); - stat = ERROR; - } - if (stat == OK) { - maxBlocks = maxBytes / AR_CF_BLKSIZE; - - pDesc = bfCreate(name, BF_TYPE_CHAN_DATA, - 1, AR_CF_BLKSIZE, BF_FLAG_GROW, maxBlocks); - if (pDesc == NULL) - stat = ERROR; - else - pArCfDesc->pBfDesc = pDesc; - } - if (stat == OK) { -/*---------------------------------------------------------------------------- -* create has succeeded; initialize userInfo in block0 -*---------------------------------------------------------------------------*/ - ArB0MIHead(pArCfDesc) = 0; - ArB0MITail(pArCfDesc) = 0; - ArB0MINblk(pArCfDesc) = 0; - ArB0MIFree_blkNum(pArCfDesc) = 0; - ArB0MIFree_hdrNum(pArCfDesc) = 0; - ArB0FormatRev(pArCfDesc) = AR_CF_FORMAT_REV; - if ((stat = bfWrite(pDesc, pDesc->pBlock0, 0)) != OK) - (void)printf("arCFCreate: error writing block0\n"); - } - if (stat != OK) { - if (pArCfDesc != NULL) { -/*---------------------------------------------------------------------------- -* ERROR has occurred; clean up whatever structure has been built and close -* the file. -*---------------------------------------------------------------------------*/ - (void)arCFClose(&pArCfDesc); - assert(pArCfDesc == NULL); - } - } - - return pArCfDesc; -} - -/*+/subr********************************************************************** -* NAME arCFOpen - open an AR channel data file -* -* DESCRIPTION -* Opens an existing AR channel data file (a 'block file' of type -* BF_TYPE_CHAN_DATA) in the specified mode, O_RDONLY or O_RDWR. If -* the mode is O_RDWR, then a lock file is created to prevent multiple -* writers of the file. -* -* Upon a successful open, the master index blocks have been read into -* memory (and the channel file descriptor has the appropriate pointers). -* -* The block size in the file must be AR_CF_BLKSIZE. The file -* `format revision number' must match the `format revision number' -* the code was compiled with. -* -* RETURNS -* pointer to channel file descriptor, or -* NULL -* -* BUGS -* o lock file handling is somewhat `ratty', especially under VxWorks; -* there is a slim chance that multiple writers could occur. -* o no exit handler is established, which means that AR_CFClose() -* isn't automatically called. This means that buffers aren't flushed -* and the lock file isn't deleted if the program aborts. -* -* SEE ALSO -* arCFCreate(), arCFClose(), arCFChanOpen() -* -* EXAMPLE -* -*-*/ -AR_CF_DESC * -arCFOpen(name, mode) -char *name; /* I file name */ -int mode; /* I mode to use for open--O_RDONLY or O_RDWR */ -{ - int stat=OK; /* status from calls */ - BF_DESC *pDesc=NULL; /* pointer to block file descriptor */ - AR_CF_DESC *pArCfDesc=NULL;/* pointer to channel file descriptor */ - - assert(strlen(name) < GEN_FNAME_DIM); - assert(strlen(name) > 0); - assert(mode == O_RDONLY || mode == O_RDWR); - (void)arCSCheck(); /* check control system 'compatibility' */ - (void)arCFAsserts(); /* check control system 'compatibility' */ - -/*---------------------------------------------------------------------------- -* allocate memory for an AR channel file descriptor and initialize the -* descriptor. Then open the block file and put into the channel file -* descriptor a pointer to the block file descriptor. This hides from -* most users the fact that there are actually two descriptors--they -* just use the channel file descriptor. -*---------------------------------------------------------------------------*/ - if ((pArCfDesc = arCF_mallocCF_DESC()) == NULL) { - (void)fprintf(stderr, "arCFOpen: can't malloc for arCfDesc\n"); - stat = ERROR; - } - else { - pArCfDesc->pBfDesc = NULL; - pArCfDesc->pMIHead = NULL; /* no MI buffers yet */ - pArCfDesc->pMITail = NULL; - pArCfDesc->pMIFree = NULL; - pArCfDesc->MIFree_hdrNum = 0; - pArCfDesc->pChanDescHead = NULL; /* no channel desc exist yet */ - pArCfDesc->pChanDescTail = NULL; - pArCfDesc->pWriteHead = NULL; - pArCfDesc->pWriteTail = NULL; - pArCfDesc->b0Modified = 0; - } - if (stat == OK) { - if ((pDesc = bfOpen(name, mode, BF_TYPE_CHAN_DATA, 0)) == NULL) - stat = ERROR; - else - pArCfDesc->pBfDesc = pDesc; - } - if (stat == OK) { - if (BfB0BlockSize(pDesc) != AR_CF_BLKSIZE) { - (void)fprintf(stderr, "arCfOpen: block size mismatch\n"); - stat = ERROR; - } - } - if (stat == OK) { - if (ArB0FormatRev(pArCfDesc)/100 != AR_CF_FORMAT_REV/100) { - (void)fprintf(stderr, - "arCfOpen: file format mismatch--file %d, code %d\n", - ArB0FormatRev(pArCfDesc), AR_CF_FORMAT_REV); - stat = ERROR; - } - } - if (stat == OK) { -/*---------------------------------------------------------------------------- -* so far, the open is going OK. Do any additional processing needed. -*---------------------------------------------------------------------------*/ - stat = arCFReadMIBuffers(pArCfDesc); - } - - if (stat != OK) { - if (pArCfDesc != NULL) { -/*---------------------------------------------------------------------------- -* ERROR has occurred; clean up whatever structure has been built and close -* the file. -*---------------------------------------------------------------------------*/ - (void)arCFClose(&pArCfDesc); - assert(pArCfDesc == NULL); - } - } - - return pArCfDesc; -} - -/*+/subr********************************************************************** -* NAME arCFReadMIBuffers - read (or re-read) the MI blocks -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o doesn't have any protection against changes in linked lists while -* this routine is running -* o doesn't handle deleting channels or purging data (i.e., deleting -* .datInfo items or entire index blocks) -* o comments are out of date--they don't describe re-read of MI blocks -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCFReadMIBuffers(pArCfDesc) -AR_CF_DESC *pArCfDesc; /* I ptr to channel file descriptor */ -{ - int retStat=OK; /* return status to caller */ - int stat; /* status return from calls */ - BF_BLKNUM blockNum; /* block number */ - AR_MI_BUF *pMIBuf; /* ptr to buffer for block */ - int i; - AR_MI_BUF MIBuf; /* temporary buffer for re-read of MI block */ - - if (ArB0MIHead(pArCfDesc) == 0) - return OK; -/*---------------------------------------------------------------------------- -* the file has some Master Index blocks; read ALL OF THEM into memory. -* -* For each MI block, get a buffer, link the buffer into the MI buffer -* list, put the block number into the buffer, reset the buffer's flags, -* and, finally, read the block into the buffer. Once the block is in -* the buffer, do some initialization for each chanHdr. This -* initialization includes reading the blocks for DBF_ENUM channels. -* -* If block0 points to an MIFree, then check each MI block to see if it -* is the one pointed to; when a match is found, initialize the MIFree -* information in the channel file descriptor. -*---------------------------------------------------------------------------*/ - - blockNum = ArB0MIHead(pArCfDesc); - while (blockNum > 0) { - pMIBuf = pArCfDesc->pMIHead; - while (pMIBuf != NULL) { - if (pMIBuf->blkNum == blockNum) - break; - pMIBuf = pMIBuf->pNextMI; - } - if (pMIBuf == NULL) { - if ((pMIBuf = arCF_mallocMI_BUF()) == NULL) { - (void)fprintf(stderr, "arCFOpen: can't malloc for MI block\n"); - stat = ERROR; - goto readMIError; - } - if (pArCfDesc->pMIHead == NULL) /* first block? */ - pArCfDesc->pMIHead = pMIBuf; /* yes; link to head */ - else - pArCfDesc->pMITail->pNextMI = pMIBuf; /* no; link from prev */ - pArCfDesc->pMITail = pMIBuf; /* this is now tail */ - pMIBuf->blkNum = blockNum; - pMIBuf->pNextMI = NULL; - ArCFModifyInit(pMIBuf); - pMIBuf->pBlock = &pMIBuf->bfInfo; - - stat = bfRead(pArCfDesc->pBfDesc, &pMIBuf->bfInfo, blockNum); - if (stat != OK) { - (void)fprintf(stderr, "arCFOpen: error reading MI block\n"); - stat = ERROR; - goto readMIError; - } - - for (i=0; ichanHdr[i].count = 0; - pMIBuf->chanHdr[i].flags = 0; - if (pMIBuf->chanHdr[i].name[0] != '\0' && - pMIBuf->chanHdr[i].chanType == DBF_ENUM) { - pMIBuf->chanHdr[i].graphics.enumGr.pGRBuf = NULL; - stat = arCF_GRReadBlock(pArCfDesc, &pMIBuf->chanHdr[i]); - if (stat != OK) { - (void)fprintf(stderr, - "arCFOpen: error reading GR block for ENUM\n"); - stat = ERROR; - goto readMIError; - } - } - } - } - else { - stat = bfRead(pArCfDesc->pBfDesc, &MIBuf.bfInfo, blockNum); - if (stat != OK) { - (void)fprintf(stderr, "arCFOpen: error reading MI block\n"); - stat = ERROR; - goto readMIError; - } - pMIBuf->bfInfo.flink = MIBuf.bfInfo.flink; - for (i=0; ichanHdr[i].name, - MIBuf.chanHdr[i].name) == 0); - pMIBuf->chanHdr[i].indexTail = MIBuf.chanHdr[i].indexTail; - pMIBuf->chanHdr[i].newestSecPastEpoch = - MIBuf.chanHdr[i].newestSecPastEpoch; - pMIBuf->chanHdr[i].newestNsec = - MIBuf.chanHdr[i].newestNsec; - } - else { - pMIBuf->chanHdr[i].graphics.nextMIFree = - MIBuf.chanHdr[i].graphics.nextMIFree; - } - } - - } - if (ArB0MIFree_blkNum(pArCfDesc) == blockNum) { - pArCfDesc->pMIFree = pMIBuf; - pArCfDesc->MIFree_hdrNum = ArB0MIFree_hdrNum(pArCfDesc); - } - blockNum = pMIBuf->bfInfo.flink; /* next MI block */ - } - return OK; -readMIError: - return ERROR; -} - -/*+/subr********************************************************************** -* NAME arCFSyncRead - synchronize read buffers in memory with disk -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCFSyncRead(pArCfDesc) -AR_CF_DESC *pArCfDesc; /* I ptr to channel file descriptor */ -{ - int retStat=OK; /* return status to caller */ - int stat; /* status return from calls */ - int readOnly; /* channel file is opened read-only */ - AR_CHAN_DESC *pChanDesc; - BF_DESC *pBfDesc; - - assert(pArCfDesc != NULL); - assert(pArCfDesc->pBfDesc != NULL); - pBfDesc = pArCfDesc->pBfDesc; - - readOnly = ((pBfDesc->flags & BF_DESC_WRITE) == 0); - if (readOnly) { - stat = bfRead(pBfDesc, pBfDesc->pBlock0, 0); - assertAlways(stat == OK); - stat = arCFReadMIBuffers(pArCfDesc); - assertAlways(stat == OK); - } - pChanDesc = pArCfDesc->pChanDescHead; - while (pChanDesc != NULL) { - if ((pChanDesc->flags & AR_CDESC_WRITE) == 0) { - if (pChanDesc->pIndexBuf != NULL && - pChanDesc->pIndexBuf->bfInfo.flink == 0) { - stat = bfRead(pBfDesc, &pChanDesc->pIndexBuf->bfInfo, - pChanDesc->pIndexBuf->blkNum); - assertAlways(stat == OK); - } - if (pChanDesc->pDataBuf != NULL && - pChanDesc->pDataBuf->bfInfo.flink == 0) { - stat = bfRead(pBfDesc, &pChanDesc->pDataBuf->bfInfo, - pChanDesc->pDataBuf->blkNum); - assertAlways(stat == OK); - pChanDesc->remainCount = - pChanDesc->pData-(char *)&pChanDesc->pDataBuf->bfInfo - - pChanDesc->pDataBuf->bfInfo.firstByte; - } - } - pChanDesc = pChanDesc->pNextDesc; - } - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCFSyncWrite - synchronize disk with write buffers in memory -* -* DESCRIPTION -* -* RETURNS -* OK -* -* BUGS -* o doesn't lock for list and write operations -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCFSyncWrite(pArCfDesc) -AR_CF_DESC *pArCfDesc; /* I ptr to channel file descriptor */ -{ - int retStat=OK; /* return status to caller */ - int stat; /* status return from calls */ - AR_MI_BUF *pBuf; /* preamble is same for all types of buffer */ - int modified=0; - - assert(pArCfDesc != NULL); - - while ((pBuf = pArCfDesc->pWriteHead) != NULL) { - modified++; - if (ArCFModifyTestAndReset(pArCfDesc, pBuf)) { - stat = bfWrite(pArCfDesc->pBfDesc, &pBuf->bfInfo, pBuf->blkNum); - assertAlways(stat == OK); - } - } - - if (modified) { - pArCfDesc->b0Modified = 0; - stat = bfWrite(pArCfDesc->pBfDesc, pArCfDesc->pBfDesc->pBlock0, 0); - if (stat != OK) - retStat = ERROR; - } - - return retStat; -} diff --git a/src/libCom/arCSCheck.c b/src/libCom/arCSCheck.c deleted file mode 100644 index 3f122c255..000000000 --- a/src/libCom/arCSCheck.c +++ /dev/null @@ -1,133 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 04-01-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 04-01-90 rac initial version - * .02 07-31-91 rac installed in SCCS - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE arCSCheck.c - check assumptions about definitions in arCS.h -* -* DESCRIPTION -* -*-***************************************************************************/ - -#include -#include -#include -#ifndef INCLcadefh -# include -#endif - -#ifndef INCLdb_accessh -# include -#endif - - - -/*+/subr********************************************************************** -* NAME arCSCheck - check assumptions used by AR about the control system -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o doesn't actually check against GTACS #define's -* -* SEE ALSO -* arCS.h -* -* EXAMPLE -* -*-*/ -int -arCSCheck() -{ -#ifdef NDEBUG -# define NDEBUG /* force checks even if compiled NDEBUG */ -#endif - -/*---------------------------------------------------------------------------- -* dimensions for text strings must be multiples of 4 for proper alignment -* of structures. In addition, specific dimensions are checked for string -* types which are stored in files--changing these dimensions requires -* reformatting existing files. -* -* Just for documentation purposes, alarm severity and status are checked. -* Again, these are important because of file layout. -*---------------------------------------------------------------------------*/ - assert(AR_NAME_DIM % 4 == 0); - assert(AR_NAME_DIM == 36); - assert(AR_NAME_DIM == db_name_dim); - assert(AR_STRVAL_DIM == 40); - assert(AR_STRVAL_DIM == db_strval_dim); - assert(AR_DESC_DIM % 4 == 0); - assert(AR_DESC_DIM == 24); - assert(AR_DESC_DIM == db_desc_dim); - assert(AR_UNITS_DIM % 4 == 0); - assert(AR_UNITS_DIM == 8); - assert(AR_UNITS_DIM == db_units_dim); - assert(AR_STATE_DIM == 16); - assert(AR_STATE_DIM == db_state_dim); - assert(AR_STATE_TEXT_DIM == 26); - assert(AR_STATE_TEXT_DIM == db_state_text_dim); - assert(sizeof(AR_ALM_SEV) == 1); - assert(sizeof(AR_ALM_STAT) == 1); - -/*---------------------------------------------------------------------------- -* check for incompatibilities between the assumptions used by AR and -* the actual sizes in the control system. -*---------------------------------------------------------------------------*/ - assert(AR_STRVAL_DIM == dbr_size[DBR_STRING]); -#ifndef AR_CS_NEW_DBR - assert(2 == dbr_size[DBR_INT]); -#else - assert(2 == dbr_size[DBR_SHORT]); -#endif - assert(4 == dbr_size[DBR_FLOAT]); - -/*---------------------------------------------------------------------------- -* miscellaneous -*---------------------------------------------------------------------------*/ - assert(4 == sizeof(long)); /* block numbers require 32 bit integer; - also important for file layout */ - assert(2 == sizeof(short)); /* important for file layout */ - assert(4 == sizeof(float)); /* important for file layout */ - assert(1 == sizeof(char)); /* important for file layout */ - assert(2 == sizeof(USHORT));/* important for file layout */ - assert(4 == sizeof(ULONG)); /* important for file layout */ - assert(TS_EPOCH_YEAR == 1990);/* existing file time stamps are - invalidated if epoch year changes*/ - - return OK; -} diff --git a/src/libCom/arChanIO.c b/src/libCom/arChanIO.c deleted file mode 100644 index 704649279..000000000 --- a/src/libCom/arChanIO.c +++ /dev/null @@ -1,1638 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 03-09-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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 03-09-90 rac initial version - * .02 07-31-91 rac installed in SCCS - * .03 09-19-91 rac add a new assert check; fix bug in writing - * index blocks - * .04 09-14-92 rac remove use of special malloc and free routines - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code - */ -/*+/mod*********************************************************************** -* TITLE arChanIO.c - AR channel data file routines -* -* DESCRIPTION -* `Private' routines for the implementation of AR channel data files. -* These routines are intended for use only by arAccessLib.c routines. -* -* SEE ALSO -* arAccessLib.h and arAccessLib.c for some code which needs to be -* directly accessible to users of the AR access -* library. -*-***************************************************************************/ - -#define ARACC_TEXT_GLBLSOURCE -#include -#ifndef INC_arCS_h -# include -#endif -#ifndef INC_genDefs_h -# include -#endif -#ifndef INC_tsDefs_h -# include -#endif -#ifndef INCLcadefh -# include -#endif - -#ifdef vxWorks -# include -# include /* for O_RDWR and O_RDONLY definitions */ -# include -#else -# include -# include /* for O_RDWR and O_RDONLY definitions */ -#endif - - -/*---------------------------------------------------------------------------- -* AR channel file routines -* -* long arCFAsserts( ) -* long arCF_DFillRbufAndGetc( pArChanDesc ) -* long arCF_DFlushAndFree( pArChanDesc ) -* long arCF_DFlushWbufAndPutc( c, pArChanDesc ) -* long arCF_DNextBlock( pArChanDesc ) -* long arCF_DRead( pArChanDesc, pDBuf, blockNum ) -* -* long arCF_GRGetBlock( pArChanDesc ) -* long arCF_GRReadBlock( pArCfDesc, pArChanHdr ) -* -* long arCF_IFlushAndFree( pArChanDesc ) -* long arCF_INextDatInfo( pArChanDesc ) -* long arCF_IRead( pArChanDesc, pIBuf, blockNum ) -* -* long arCF_MIAddBlock( pArCfDesc ) -* long arCF_MIAddChan( pArCfDesc, name, >ppMIBuf, >pIndex ) -* long arCF_MIDelChan( pArCfDesc, pMIBuf, index ) -* long arCF_MIFindChan( pArCfDesc, name, >ppMIBuf, >pIndex ) -*---------------------------------------------------------------------------*/ - -/*+/subhead------------------------------------------------------------------- -* NAME arCF_malloc/arCF_free -* -* malloc and free routines for arCF routines to use for the various kinds -* of data structures. Should the need arise, these routines will -* be enhanced to maintain lists of free data structures of the various -* kinds, to eliminate malloc()/free() overhead and memory fragmentation. -* -* The following macros are used for calling malloc() and free() for -* some common data structures in arChanIO. They have two versions, -* depending on whether DEBUG is defined. Both versions perform the -* described function. The DEBUG version provides the capability for -* `bounds checking' on allocated buffers, and also for filling buffers -* with a known pattern for use in `un-initialized buffer' bug detection. -* -* AR_MI_BUF *arCF_mallocMI_BUF() void arCF_freeMI_BUF(pMIBuf -* AR_INDEX_BUF *arCF_mallocINDEX_BUF() void arCF_freeINDEX_BUF(pIndexBuf) -* AR_DATA_BUF *arCF_mallocDATA_BUF() void arCF_freeDATA_BUF(pDataBuf) -* AR_GR_BUF *arCF_mallocGR_BUF() void arCF_freeGR_BUF(pDataBuf) -* -*---------------------------------------------------------------------------*/ -static int glArMallocDebug=0; /* 1 says print info */ -static unsigned long glArNMalloc=0; /* # of successful malloc's */ -static unsigned long glArNMallocFailed=0; /* # of failed mallocs */ -static unsigned long glArNbytesMalloc=0; /* # of bytes ever malloc'ed */ -static unsigned long glArNetNbytesMalloc=0; /* # bytes malloc, not free */ -static unsigned long glArNFree=0; /* # of free's */ -static unsigned long glArNbytesFree=0; /* # of bytes ever free'ed */ - -void -arFree(pMem, size, text) -void *pMem; -int size; -char *text; -{ - free((char *)pMem); - glArNFree++; - glArNbytesFree += size; - glArNetNbytesMalloc -= size; - if (glArMallocDebug) { - (void)printf("free %s=0x%x sz=%d\n", text, pMem, size); - arMallocStats(); - } -} - -void * -arMalloc(size, text) -int size; -char *text; -{ - void *pMem; - pMem = (void *)malloc(size); - if (pMem != NULL) { - glArNMalloc++; - glArNbytesMalloc += size; - glArNetNbytesMalloc += size; - } - else - glArNMallocFailed++; - - if (glArMallocDebug) { - (void)printf("malloc %s=0x%x sz=%d\n", text, pMem, size); - arMallocStats(); - } - return pMem; -} -void -arMallocDebug(n) -int n; -{ - glArMallocDebug = n; -} -void -arMallocStats() -{ - (void)printf("Nmal,Nfree,net= %d %d %d\n", - glArNMalloc, glArNFree, glArNetNbytesMalloc); -} - -AR_MI_BUF * -arCF_mallocMI_BUF() -{ -#ifdef DEBUG - return (AR_MI_BUF *)arMalloc(sizeof(AR_MI_BUF), "AR_MI_BUF"); -#else - return (AR_MI_BUF *)malloc(sizeof(AR_MI_BUF)); -#endif -} -void -arCF_freeMI_BUF(ptr) -AR_MI_BUF *ptr; -{ -#ifdef DEBUG - arFree(ptr, sizeof(AR_MI_BUF), "AR_MI_BUF"); -#else - free(ptr); -#endif -} - -AR_INDEX_BUF * -arCF_mallocINDEX_BUF() -{ -#ifdef DEBUG - return (AR_INDEX_BUF *)arMalloc(sizeof(AR_INDEX_BUF), "AR_INDEX_BUF"); -#else - return (AR_INDEX_BUF *)malloc(sizeof(AR_INDEX_BUF)); -#endif -} -void -arCF_freeINDEX_BUF(ptr) -AR_INDEX_BUF *ptr; -{ -#ifdef DEBUG - arFree(ptr, sizeof(AR_INDEX_BUF), "AR_INDEX_BUF"); -#else - free(ptr); -#endif -} - -AR_DATA_BUF * -arCF_mallocDATA_BUF() -{ -#ifdef DEBUG - return (AR_DATA_BUF *)arMalloc(sizeof(AR_DATA_BUF), "AR_DATA_BUF"); -#else - return (AR_DATA_BUF *)malloc(sizeof(AR_DATA_BUF)); -#endif -} -void -arCF_freeDATA_BUF(ptr) -AR_DATA_BUF *ptr; -{ -#ifdef DEBUG - arFree(ptr, sizeof(AR_DATA_BUF), "AR_DATA_BUF"); -#else - free(ptr); -#endif -} - -AR_GR_BUF * -arCF_mallocGR_BUF() -{ -#ifdef DEBUG - return (AR_GR_BUF *)arMalloc(sizeof(AR_GR_BUF), "AR_GR_BUF"); -#else - return (AR_GR_BUF *)malloc(sizeof(AR_GR_BUF)); -#endif -} -void -arCF_freeGR_BUF(ptr) -AR_GR_BUF *ptr; -{ -#ifdef DEBUG - arFree(ptr, sizeof(AR_GR_BUF), "AR_GR_BUF"); -#else - free(ptr); -#endif -} - -/*+/subr********************************************************************** -* NAME arCFAsserts - check some assumptions used in arChanIO routines -* -* DESCRIPTION -* This routine checks a number of hardware and software items -* which influence the proper operation of the arChanIO routines and -* compatibility between various execution platforms. Aside from -* the simple motivation of being able to run, these checks are -* important in avoiding the clobbering of a file full of data. -* -* RETURNS -* OK -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCFAsserts() -{ - static ULONG in[]={0,0,0}, out[]={0,0,0}, i; - char between[4]; - TS_STAMP time_s; - - assertAlways(4 == sizeof(time_s.secPastEpoch)); - /* important for file layout; also - needed to make structures properly - aligned */ - assertAlways(4 == sizeof(time_s.nsec));/* important for file layout; also - needed to make structures properly - aligned */ - assertAlways(1 == sizeof(char)); - assertAlways(2 == sizeof(short)); - assertAlways(4 == sizeof(long)); - assertAlways(4 == sizeof(float)); - assertAlways(8 == sizeof(double)); - assertAlways(AR_UNITS_DIM == 8); /* important for file layout */ - assertAlways(AR_UNITS_DIM % 8 == 0);/* important for file layout; also - needed to make structures properly - aligned */ - assertAlways(db_state_dim == 16); /* important for file layout; also - needed to make structures properly - aligned */ - assertAlways(db_state_text_dim == 26);/* important for file layout; also - needed to make structures properly - aligned */ - assertAlways(dbr_size[DBF_ENUM] == 2);/* important for file layout; also - needed for proper functioning of - code which copies DBF_ENUM values */ - assertAlways(AR_UNITS_DIM % 8 == 0);/* important for file layout; also - needed to make structures properly - aligned */ - assertAlways(AR_GR_BUF_PAD >= 1); /* block has to hold state strings */ - assertAlways(ERROR < 0); /* must not be a valid block number */ - -/*---------------------------------------------------------------------------- -* make sure that changing long to character stream and back actually works -*---------------------------------------------------------------------------*/ - in[1] = 0x87654321L; - for (i=0; i<4; i++) { - between[i] = *(((char *)&in[1])+i); - } - for (i=0; i<4; i++) { - *(((char *)&out[1])+i) = between[i]; - } - assertAlways(in[1] == out[1]); - - return OK; -} - -/*+/subr********************************************************************** -* NAME arCF_DFillRbufAndGetc - get next data buffer and get a character -* -* DESCRIPTION -* Gets the next data buffer for reading, puts the time stamp -* information from datInfo into the chanDesc, and returns the first -* character for reading. -* -* The time stamp information in the chanDesc is initialized from -* the datInfo structure in the index block, if the datInfo -* actually contains a time stamp. (Remember that blocks which -* don't have the beginning of an item have zero time stamp in -* their datInfo.) -* -* RETURNS -* character, or -* ERROR -* -*-*/ -long -arCF_DFillRbufAndGetc(pArChanDesc) -AR_CHAN_DESC *pArChanDesc; /* pointer to channel descriptor */ -{ - if (arCF_DNextBlock(pArChanDesc) != OK) - return ERROR; - if (--pArChanDesc->remainCount >= 0) { - if (ArCDDatInfo(pArChanDesc).stamp.secPastEpoch != 0) - pArChanDesc->timeStamp = ArCDDatInfo(pArChanDesc).stamp; - return ((int)(*(++pArChanDesc->pData))) & 0xff; - } - else - assertAlways(0); -/* NOTREACHED */ -} - -/*+/subr********************************************************************** -* NAME arCF_DFlushAndFree - flush data block and free buffer -* -* DESCRIPTION -* If the data block has been modified, the `.lastByte' item in the -* block is updated and the block is written. -* -* The block is free'd and the buffer pointer in the chanDesc is -* set to NULL. -* -* RETURNS -* OK, or -* ERROR -* -* NOTES -* 1. This routine depends on the channel descriptor having .remainCount -* and .pData be relevant to the buffer being flushed. -* -* BUGS -* o doesn't provide a mechanism for multiple buffering -* -*-*/ -long -arCF_DFlushAndFree(pArChanDesc) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status to caller */ - - if (ArCFModifyTestAndReset(pArChanDesc->pArCfDesc, pArChanDesc->pDataBuf)){ - assert((pArChanDesc->flags & AR_CDESC_WRITE) != 0); - if (pArChanDesc->pData != NULL) { - pArChanDesc->pDataBuf->bfInfo.lastByte = pArChanDesc->pData - - (char *)&pArChanDesc->pDataBuf->bfInfo; - assert(pArChanDesc->pDataBuf->bfInfo.lastByte > 0); - assert(pArChanDesc->pDataBuf->bfInfo.lastByte < 2000); - } - stat = bfWrite(pArChanDesc->pArCfDesc->pBfDesc, - &pArChanDesc->pDataBuf->bfInfo, - pArChanDesc->pDataBuf->blkNum); - if (stat != OK) { - (void)fprintf(stderr, - "arCF_DFlushAndFree: can't write data block\n"); - retStat = ERROR; - } - } - arCF_freeDATA_BUF(pArChanDesc->pDataBuf); - pArChanDesc->pDataBuf = NULL; - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCF_DFlushWbufAndPutc - flush data buffer and write a character -* -* DESCRIPTION -* Write the current data block to the file, get a new data block for -* writing, and put the character into the new block. Manipulations -* for index and master index blocks are performed as needed. -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o text -* -* EXAMPLE -* for (i=0; iremainCount >= 0) -* *(char *)(++(pArChanDesc->pData)) = data[i]; -* else -* stat = arCF_DFlushWbufAndPutc(data[i], pArChanDesc); -* } -* -*-*/ -long -arCF_DFlushWbufAndPutc(c, pArChanDesc) -char c; /* I character to write */ -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -{ - - assert(pArChanDesc != NULL); - - if (arCF_DNextBlock(pArChanDesc) != OK) - return ERROR; - if (--pArChanDesc->remainCount >= 0) - *(++pArChanDesc->pData) = c; - else - assertAlways(0); - - return OK; -} - -/*+/subr********************************************************************** -* NAME arCF_DNextBlock - get next data block -* -* DESCRIPTION -* Gets the next data block, as dictated by the next datInfo in the -* index block. If the mode is O_RDWR, a new datInfo is created and -* a new data block is acquired. If the mode is O_RDONLY, then ERROR -* is returned if there are no more datInfo's, with AR_CDESC_EOF set -* in chanDesc.flags . -* -* RETURNS -* OK, or -* ERROR -* -*-*/ -long -arCF_DNextBlock(pArChanDesc) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -{ - int stat; /* status from calls */ - - AR_DATA_BUF *pDataBufNew; /* pointer to new data buffer */ - BF_BLKNUM blockNum; /* block number of new data block */ - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - - if ((pArChanDesc->flags & AR_CDESC_WRITE) != 0) { -/*---------------------------------------------------------------------------- -* O_RDWR -- write mode processing -* -* first, get a buffer to hold the next data block; -* then, get the next datInfo item. -*---------------------------------------------------------------------------*/ - if ((pDataBufNew = arCF_mallocDATA_BUF()) == NULL) { - if ((pArChanDesc->flags & AR_CDESC_SUP) == 0) { - (void)fprintf(stderr, - "arCF_DNextBlock: can't malloc new data buf\n"); - } - pArChanDesc->flags |= AR_CDESC_SUP; /* suppress msg */ - return ERROR; - } - - if (arCF_INextDatInfo(pArChanDesc) != OK) { - if ((pArChanDesc->flags & AR_CDESC_SUP) == 0) { - (void)fprintf(stderr, - "arCF_DNextBlock: error getting new datInfo\n"); - } - pArChanDesc->flags |= AR_CDESC_SUP; /* suppress msg */ - arCF_freeDATA_BUF(pDataBufNew); - return ERROR; - } - - blockNum = ArCDDatInfo(pArChanDesc).dataBlock; - - if (pArChanDesc->pDataBuf == NULL) { -/*---------------------------------------------------------------------------- -* Case 1: -* this is the first call for the channel following the open. Read the -* last used data block for the channel. If there wasn't a "last used -* data block", acquire a new data block. -*---------------------------------------------------------------------------*/ - if (blockNum > 0) { - stat = bfRead(pArChanDesc->pArCfDesc->pBfDesc, - &pDataBufNew->bfInfo, blockNum); - if (stat != OK) { - (void)fprintf(stderr, - "arCF_DNextBlock: error reading old data block\n"); - arCF_freeDATA_BUF(pDataBufNew); - return ERROR; - } - pDataBufNew->blkNum = blockNum; - ArCFModifyInit(pDataBufNew); - pDataBufNew->pBlock = &pDataBufNew->bfInfo; - } - else { - blockNum = bfAcquire(pArChanDesc->pArCfDesc->pBfDesc, - &pDataBufNew->bfInfo); - if (blockNum == ERROR) { - if ((pArChanDesc->flags & AR_CDESC_SUP) == 0) { - (void)fprintf(stderr, - "arCF_DNextBlock: error acquiring new data block\n"); - } - pArChanDesc->flags |= AR_CDESC_SUP; /* suppress msg */ - arCF_freeDATA_BUF(pDataBufNew); - return ERROR; - } - pDataBufNew->blkNum = blockNum; - ArCFModifyInit(pDataBufNew); - pDataBufNew->pBlock = &pDataBufNew->bfInfo; - ArCFModifySet(pArChanDesc->pArCfDesc, pDataBufNew); - ArCDDatInfo(pArChanDesc).dataBlock = pDataBufNew->blkNum; - } - } - else { -/*---------------------------------------------------------------------------- -* Case 2: -* this isn't the first call--instead, the caller wants the current -* buffer flushed and a new one started. Acquire a new block, link the -* old one to it, write the old block, and free its buffer. -*---------------------------------------------------------------------------*/ - blockNum = bfAcquire(pArChanDesc->pArCfDesc->pBfDesc, - &pDataBufNew->bfInfo); - if (blockNum == ERROR) { - if ((pArChanDesc->flags & AR_CDESC_SUP) == 0) { - (void)fprintf(stderr, - "arCF_DNextBlock: error acquiring new data block\n"); - } - pArChanDesc->flags |= AR_CDESC_SUP; /* suppress msg */ - arCF_freeDATA_BUF(pDataBufNew); - return ERROR; - } - pDataBufNew->blkNum = blockNum; - ArCFModifyInit(pDataBufNew); - pDataBufNew->pBlock = &pDataBufNew->bfInfo; - ArCFModifySet(pArChanDesc->pArCfDesc, pDataBufNew); - ArCDDatInfo(pArChanDesc).dataBlock = pDataBufNew->blkNum; - - pArChanDesc->pDataBuf->bfInfo.flink = blockNum; - if (pArChanDesc->pData != NULL) { - pArChanDesc->pDataBuf->bfInfo.lastByte = pArChanDesc->pData - - (char *)&pArChanDesc->pDataBuf->bfInfo; - assert(pArChanDesc->pDataBuf->bfInfo.lastByte > 0); - assert(pArChanDesc->pDataBuf->bfInfo.lastByte < 2000); - } - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pDataBuf); - if (arCF_DFlushAndFree(pArChanDesc) != OK) { - (void)fprintf(stderr, - "arCF_DNextBlock: error writing old block\n"); - return ERROR; - } - } -/*---------------------------------------------------------------------------- -* wrapup -* -* set up the channel descriptor for writing to the new block -*---------------------------------------------------------------------------*/ - pArChanDesc->pDataBuf = pDataBufNew; - pArChanDesc->remainCount = - AR_CF_BLKSIZE - pDataBufNew->bfInfo.lastByte - 1; - pArChanDesc->pData = - (char *)&pDataBufNew->bfInfo + pDataBufNew->bfInfo.lastByte; - return OK; - } - else { -/*---------------------------------------------------------------------------- -* O_RDONLY -* -* Case 1: -* this is the first call for the channel following the open. A buffer -* must be obtained, then the first available data block for the -* channel must be read. -* -* Case 2: -* this isn't the first call following open. Simply read the next -* available data block into the same buffer. -* -* NOTES: -* 1. pDataBufNew is used here as the buffer pointer--except for the first -* read for the channel, the `New' is inappropriate; peruse accordingly. -*---------------------------------------------------------------------------*/ - if ((pDataBufNew = pArChanDesc->pDataBuf) == NULL) { - if ((pDataBufNew = arCF_mallocDATA_BUF()) == NULL) { - if ((pArChanDesc->flags & AR_CDESC_SUP) == 0) { - (void)fprintf(stderr, - "arCF_DNextBlock: can't malloc new data buf\n"); - } - pArChanDesc->flags |= AR_CDESC_SUP; /* suppress msg */ - return ERROR; - } - } - - if (arCF_INextDatInfo(pArChanDesc) != OK) - return ERROR; - - blockNum = ArCDDatInfo(pArChanDesc).dataBlock; - - if (blockNum > 0) { - stat = arCF_DRead(pArChanDesc, pDataBufNew, blockNum); - if (stat != OK) { - (void)fprintf(stderr, - "arCF_DNextBlock: error reading next data block\n"); - return ERROR; - } - } - else { - pArChanDesc->flags |= AR_CDESC_EOF; - return ERROR; /* no data to read */ - } - pArChanDesc->pDataBuf = pDataBufNew; - return OK; - } -} - -/*+/subr********************************************************************** -* NAME arCF_DRead - read a data block into a data buffer -* -* DESCRIPTION -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCF_DRead(pArChanDesc, pDataBuf, blockNum) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -AR_DATA_BUF *pDataBuf; /* IO pointer to data buffer */ -BF_BLKNUM blockNum; /* I block number to read */ -{ - if (bfRead(pArChanDesc->pArCfDesc->pBfDesc, &pDataBuf->bfInfo, blockNum) - != OK) - return ERROR; - pDataBuf->blkNum = blockNum; - ArCFModifyInit(pDataBuf); - pDataBuf->pBlock = &pDataBuf->bfInfo; -/*---------------------------------------------------------------------------- -* wrapup -* -* set up the channel descriptor for reading from the new block -* case 1: no bytes in block; set remainCount = 0, return ERROR, EOF; -* case 2: first read after open; use firstByte; this ignores overflow -* bytes in the first block. -* case 3: use BF_BLOCK_DATA, so as to read bytes which overflow from -* one block to the next. -*---------------------------------------------------------------------------*/ - if (pDataBuf->bfInfo.lastByte < BF_BLOCK_DATA) { - pArChanDesc->remainCount = 0; - pArChanDesc->pData = (char *)&pDataBuf->bfInfo; - pArChanDesc->flags |= AR_CDESC_EOF; - return ERROR; - } - else { - int i; - if (pArChanDesc->remainCount < -9) { /* 1st read after open */ - if ((i = pDataBuf->bfInfo.firstByte) < BF_BLOCK_DATA) - assertAlways(0); /* 1st block can't just have overflow */ - } - else - i = BF_BLOCK_DATA; - - pArChanDesc->remainCount = pDataBuf->bfInfo.lastByte -i +1; - pArChanDesc->pData = (char *)(&pDataBuf->bfInfo) +i -1; - } - - return OK; -} - -/*+/subr********************************************************************** -* NAME arCF_GRGetBlock - get a block to hold ENUM graphics info -* -* DESCRIPTION -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o -* -*-*/ -long -arCF_GRGetBlock(pArChanDesc) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -{ - int retStat=OK; /* return status to caller */ - BF_BLKNUM block; /* number of acquired block */ - AR_GR_BUF *pGRBuf; /* pointer to buffer for block */ - - assert(pArChanDesc != NULL); - assert(ArCDChanHdr(pArChanDesc).chanType == DBF_ENUM); - -/*---------------------------------------------------------------------------- -* allocate a buffer to hold new block and acquire a new block -*---------------------------------------------------------------------------*/ - if ((pGRBuf = arCF_mallocGR_BUF()) == NULL) { - (void)fprintf(stderr, - "arCF_GRAddBlock: can't malloc for new GR block\n"); - retStat = ERROR; - } - if (retStat == OK) { - block = bfAcquire(pArChanDesc->pArCfDesc->pBfDesc, &pGRBuf->bfInfo); - if (block == ERROR) { - (void)fprintf(stderr, - "arCF_GRAddBlock: can't acquire block for grInfo\n"); - retStat = ERROR; - arCF_freeGR_BUF(pGRBuf); - } - } - if (retStat == OK) { - pGRBuf->blkNum = block; - ArCFModifyInit(pGRBuf); - pGRBuf->pBlock = &pGRBuf->bfInfo; -/*---------------------------------------------------------------------------- -* initialize the block file information for the block -*---------------------------------------------------------------------------*/ - pGRBuf->bfInfo.flink = 0; - pGRBuf->bfInfo.firstByte = BF_BLOCK_DATA; - pGRBuf->bfInfo.lastByte = BF_BLOCK_DATA - 1; - ArCFModifySet(pArChanDesc->pArCfDesc, pGRBuf); -/*----------------------------------------------------------------------------- -* link the block and buffer into the chanHdr and set the modified -* bit for the MI block -*----------------------------------------------------------------------------*/ - ArCDChanHdr(pArChanDesc).graphics.enumGr.block = block; - ArCDChanHdr(pArChanDesc).graphics.enumGr.pGRBuf = pGRBuf; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - pArChanDesc->pArCfDesc->b0Modified = 1; - } - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCF_GRReadBlock - get a buffer and read ENUM graphics info -* -* DESCRIPTION -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o -* -*-*/ -long -arCF_GRReadBlock(pArCfDesc, pArChanHdr) -AR_CF_DESC *pArCfDesc; /* I pointer to channel file descriptor */ -AR_CHAN_HDR *pArChanHdr; /* IO pointer to chanHdr */ -{ - int retStat=OK; /* return status to caller */ - BF_BLKNUM block; /* number of acquired block */ - AR_GR_BUF *pGRBuf; /* pointer to buffer for block */ - - assert(pArCfDesc != NULL); - assert(pArChanHdr != NULL); - assert(pArChanHdr->chanType == DBF_ENUM); - -/*---------------------------------------------------------------------------- -* allocate a buffer to hold the block and read the block -*---------------------------------------------------------------------------*/ - if ((pGRBuf = arCF_mallocGR_BUF()) == NULL) { - (void)fprintf(stderr, "arCF_GRReadBlock: can't malloc for GR block\n"); - retStat = ERROR; - } - if (retStat == OK) { - block = bfRead(pArCfDesc->pBfDesc, &pGRBuf->bfInfo, - pArChanHdr->graphics.enumGr.block); - if (block == ERROR) { - (void)fprintf(stderr, - "arCF_GRReadBlock: can't read block for grInfo\n"); - retStat = ERROR; - arCF_freeGR_BUF(pGRBuf); - } - } - if (retStat == OK) { -/*----------------------------------------------------------------------------- -* link the block into the chanHdr. (No need to set modified bit for -* MI block, since this is only a run-time change, not for disk.) -*----------------------------------------------------------------------------*/ - pArChanHdr->graphics.enumGr.pGRBuf = pGRBuf; - pGRBuf->blkNum = block; - ArCFModifyInit(pGRBuf); - pGRBuf->pBlock = &pGRBuf->bfInfo; - } - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCF_IFlushAndFree - flush index block and free buffer -* -* DESCRIPTION -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCF_IFlushAndFree(pArChanDesc) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status to caller */ - - if (ArCFModifyTestAndReset(pArChanDesc->pArCfDesc, pArChanDesc->pIndexBuf)){ - assert((pArChanDesc->flags & AR_CDESC_WRITE) != 0); - stat = bfWrite(pArChanDesc->pArCfDesc->pBfDesc, - &pArChanDesc->pIndexBuf->bfInfo, - pArChanDesc->pIndexBuf->blkNum); - if (stat != OK) { - (void)fprintf(stderr, - "arCF_IFlushAndFree: can't write index block\n"); - retStat = ERROR; - } - } - arCF_freeINDEX_BUF(pArChanDesc->pIndexBuf); - pArChanDesc->pIndexBuf = NULL; - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCF_INextDatInfo - get next datInfo item in a channel's index -* -* DESCRIPTION -* Obtains the next datInfo element for a channel; the chanDescr will -* have the element's subscript. 'next' has several possible meanings, -* depending on the present state of the channel descriptor. -* -* If the channel descriptor is open O_RDWR, then the 'next' datInfo is -* either the last used datInfo (if this is the first call following -* opening the descriptor) or else a new datInfo at the tail end of the -* channel's index. When necessary, a new index block is obtained and, -* if necessary, the previous index buffer is written and the buffer -* is free()'d. -* -* In O_RDONLY mode, the 'next' datInfo is either the first available -* datInfo (if this is the first call following opening the descriptor) -* or else the next datInfo in the index. Initially, an index buffer is -* obtained; the same buffer is used for successive index blocks. When -* no more datInfo are available for reading, ERROR is returned, with -* AR_CDESC_EOF set in chanDesc.flags . -* -* On a successful return, the following fields in the chanDesc have -* been set up: -* o .pIndexBuf points to the (possibly new) index buffer -* o .datInfNum is the number of the datInf structure -* -* The chanHdr is updated, if necessary. -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o a highly likely race exists between reading and writing: the chanHdr -* has up-to-date information about 'full' write buffers, and the reader -* has access to this information. In an asynchronous situation, it -* is unpredictable whether those write buffers will be available from -* disk or from memory or (depending on the race) from neither. -* -* NOTES -* 1. This routine is written so that it can be repeatedly called when -* an error condition exists and it won't break. This can be exploited -* by having read or write not check status until after the last byte -* has been transferred, which makes the transfer more efficient. This -* feature is implemented using the AR_CDESC_SUP flag in chanDesc . -* 2. The ArCDDatInfo() macro is used here. Use of this macro must FOLLOW -* storing a 'good' value for datInfNum in the channel descriptor. -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCF_INextDatInfo(pArChanDesc) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -{ - int stat; /* status from calls */ - - AR_INDEX_BUF *pIndexBuf; /* pointer to index buffer */ - BF_BLKNUM blockNum; /* block number of new index block */ - short datInfNum; /* number of datInfo structure element */ - - assert(pArChanDesc != NULL); - assert(pArChanDesc->pMIBuf != NULL); - assert(pArChanDesc->pArCfDesc != NULL); - assert(pArChanDesc->pArCfDesc->pBfDesc != NULL); - - pIndexBuf = pArChanDesc->pIndexBuf; - - if ((pArChanDesc->flags & AR_CDESC_WRITE) != 0) { -/*---------------------------------------------------------------------------- -* O_RDWR -- write mode processing. There are 4 cases to handle. -* -* increment datInfNum to point to next datInfo to be used. -* -* if the new datInfNum is < 0 or is >= AR_CF_NDATINFO, then a new index -* block (and thus index buffer) is needed. The buffer is obtained here -* and 'filled in' later by bfRead() or bfAcquire(). -*---------------------------------------------------------------------------*/ - datInfNum = ++pArChanDesc->datInfNum; - if (datInfNum < 0 || datInfNum >= AR_CF_NDATINFO) { - if ((pIndexBuf = arCF_mallocINDEX_BUF()) == NULL) { - if ((pArChanDesc->flags & AR_CDESC_SUP) == 0) { - (void)fprintf(stderr, - "arCF_INextDatInfo: can't malloc index buffer\n"); - } - pArChanDesc->flags |= AR_CDESC_SUP; /* suppress msg */ - --pArChanDesc->datInfNum; - return ERROR; - } - } - if (datInfNum >= 0 && datInfNum < AR_CF_NDATINFO) - goto rdwrCase1; - else if (datInfNum >= AR_CF_NDATINFO) - goto rdwrCase2; - else { - blockNum = ArCDChanHdr(pArChanDesc).indexTail; - if (blockNum > 0) - goto rdwrCase3; - else - goto rdwrCase4; - } -rdwrCase1: -/*---------------------------------------------------------------------------- -* Case 1: the next datInfo in the index block is available for use. -* -* o adjust lastByte in the index block -* o set up chanDesc for the datInfo -* o set up new datInfo[datInfNum] -*---------------------------------------------------------------------------*/ - /* datInfNum in descriptor set up by ++ above */ - pIndexBuf->bfInfo.lastByte += sizeof(AR_DAT_INFO); - assert(pIndexBuf->bfInfo.lastByte > 0); - assert(pIndexBuf->bfInfo.lastByte < 2000); - - ArCDDatInfo(pArChanDesc).dataBlock = (BF_BLKNUM)0; - ArCDDatInfo(pArChanDesc).stamp.secPastEpoch = 0; - ArCDDatInfo(pArChanDesc).stamp.nsec = 0; - - ArCFModifySet(pArChanDesc->pArCfDesc, pIndexBuf); - - goto rdwrEnd; -rdwrCase3: -/*---------------------------------------------------------------------------- -* Case 3: this is the first call after the channel has been opened, and -* the file already contains data for the channel. The chanHdr points -* to an existing index block (indexTail), and that index block already -* has a datInfo structure set up pointing to a data block. -* -* o read the indexTail block into the index buffer -* o set up chanDesc for the indexBuf and datInfo -* o set up chanDesc for secPastEpoch from chanHdr "newest" values -*---------------------------------------------------------------------------*/ - stat = arCF_IRead(pArChanDesc, pIndexBuf, blockNum); - if (stat != OK) { - (void)fprintf(stderr, - "arCF_INextDatInfo: error reading index block\n"); - arCF_freeINDEX_BUF(pIndexBuf); - --pArChanDesc->datInfNum; - return ERROR; - } - datInfNum = (pIndexBuf->bfInfo.lastByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - /* firstByte and lastByte are OK */ - - pArChanDesc->pIndexBuf = pIndexBuf; - pArChanDesc->datInfNum = datInfNum; - pArChanDesc->timeStamp.secPastEpoch = - ArCDChanHdr(pArChanDesc).newestSecPastEpoch; - pArChanDesc->timeStamp.nsec = ArCDChanHdr(pArChanDesc).newestNsec; - - /* the information in chanHdr is OK */ - /* the information in datInfo is OK */ - - goto rdwrEnd; -rdwrCase2: -rdwrCase4: -/*---------------------------------------------------------------------------- -* Case 2: the current datInfo uses the last slot in the index block. -* -* Case 4: this is the first call after the channel has been opened, but -* the file doesn't yet contain data for the channel. -* -* A new index block is needed, with datInfo[0] to be the 'next' datInfo. -* Much of the code is common for these two cases; for each action item, -* the case(s) which use the item are indicated. -* -* 2,4 acquire a new index block and install it in the index buffer, -* marking the buffer as MODIFIED. -* 2,4 set up firstByte and lastByte in the index block -* 2 set the flink in the current index block to point to the new one -* and write the current index block, free()ing its buffer -* 4 set chanHdr.indexHead to point to the new index block -* 2,4 install the new block in the chanHdr (in the MI block); mark the -* MI buffer as MODIFIED. -* 2,4 set up chanDesc for the indexBuf and datInfo -* 4 set up chanDesc for secPastEpoch as "none" -* 2,4 set up datInfo[0] -*---------------------------------------------------------------------------*/ - blockNum = bfAcquire(pArChanDesc->pArCfDesc->pBfDesc, - &pIndexBuf->bfInfo); - if (blockNum == ERROR) { - if ((pArChanDesc->flags & AR_CDESC_SUP) == 0) { - (void)fprintf(stderr, - "arCF_INextDatInfo: can't acquire index block \n"); - } - pArChanDesc->flags |= AR_CDESC_SUP; /* suppress msg */ - arCF_freeINDEX_BUF(pIndexBuf); - --pArChanDesc->datInfNum; - return ERROR; - } - datInfNum = 0; - pIndexBuf->blkNum = blockNum; - ArCFModifyInit(pIndexBuf); - pIndexBuf->pBlock = &pIndexBuf->bfInfo; - pIndexBuf->bfInfo.firstByte = BF_BLOCK_DATA; - pIndexBuf->bfInfo.lastByte = BF_BLOCK_DATA + sizeof(AR_DAT_INFO) - 1; - ArCFModifySet(pArChanDesc->pArCfDesc, pIndexBuf); - - if (ArCDChanHdr(pArChanDesc).indexHead == 0) { /* case 4 */ - ArCDChanHdr(pArChanDesc).indexHead = blockNum; - pArChanDesc->timeStamp.secPastEpoch = 0; - pArChanDesc->timeStamp.nsec = 0; - } - else { /* case 2 */ - assert(pArChanDesc->pIndexBuf->blkNum == - ArCDChanHdr(pArChanDesc).indexTail); - assert(pArChanDesc->pIndexBuf->bfInfo.flink == (BF_BLKNUM)0); - pArChanDesc->pIndexBuf->bfInfo.flink = (BF_BLKNUM)blockNum; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pIndexBuf); - if (arCF_IFlushAndFree(pArChanDesc) != OK) { - (void)fprintf(stderr, - "arCF_INextDatInfo: error writing previous index block\n"); - /* ignore this error */ - } - } - ArCDChanHdr(pArChanDesc).indexTail = blockNum; - ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf); - pArChanDesc->pArCfDesc->b0Modified = 1; - - pArChanDesc->pIndexBuf = pIndexBuf; - pArChanDesc->datInfNum = datInfNum; - - ArCDDatInfo(pArChanDesc).dataBlock = (BF_BLKNUM)0; - ArCDDatInfo(pArChanDesc).stamp.secPastEpoch = 0; - ArCDDatInfo(pArChanDesc).stamp.nsec = 0; - -rdwrEnd: - ; - } - else { - int datInfLast; /* # of last datInfo in block */ -/*---------------------------------------------------------------------------- -* O_RDONLY -- read mode processing. There are 3 cases to handle. -* -* increment datInfNum to point to next datInfo to be used. If there is -* no index buffer, then datInfNum will have been initialized elsewhere -* to -10 . -*---------------------------------------------------------------------------*/ - datInfNum = ++pArChanDesc->datInfNum; - if (pArChanDesc->pIndexBuf == NULL) - datInfLast = -1; - else { - datInfLast = (pArChanDesc->pIndexBuf->bfInfo.lastByte - - pArChanDesc->pIndexBuf->bfInfo.firstByte) / sizeof(AR_DAT_INFO); - } - if (datInfNum >= 0 && datInfNum <= datInfLast) { -/*---------------------------------------------------------------------------- -* Case 1: the next datInfo in the index block is available for reading. -* -* o set up chanDesc for the indexBuf and datInfNum -* o set up chanDesc for time stamp from datInfo -*---------------------------------------------------------------------------*/ - assert(pArChanDesc->pIndexBuf != NULL); - - /* datInfNum in chanDesc set up by ++ above */ - if (ArCDDatInfo(pArChanDesc).stamp.secPastEpoch != 0) - pArChanDesc->timeStamp = ArCDDatInfo(pArChanDesc).stamp; - } - else { -/*---------------------------------------------------------------------------- -* Case 2: the current datInfo was in the last one in the index block. -* Case 3: this is the first call after the channel was opened. -* -* o if there is no index buffer, allocate one -* o get the blockNum of the next index block, either from 'flink' -* (for case 2) or from indexHead (for case 3) -* o read the next index block -* o set up chanDesc for the indexBuf and datInfNum -* o set up chanDesc for time stamp from datInfo -*---------------------------------------------------------------------------*/ - if (pArChanDesc->pIndexBuf == NULL) { - if ((pArChanDesc->pIndexBuf = arCF_mallocINDEX_BUF()) == - NULL) { - if ((pArChanDesc->flags & AR_CDESC_SUP) == 0) { - (void)fprintf(stderr, - "arCF_INextDatInfo: can't malloc index buffer\n"); - } - pArChanDesc->flags |= AR_CDESC_SUP; /* suppress msg */ - --pArChanDesc->datInfNum; - return ERROR; - } - } - if (datInfNum < 0) - blockNum = ArCDChanHdr(pArChanDesc).indexHead; - else - blockNum = pArChanDesc->pIndexBuf->bfInfo.flink; - if (blockNum == 0) { - pArChanDesc->flags |= AR_CDESC_EOF; - --pArChanDesc->datInfNum; - return ERROR; - } - stat = arCF_IRead(pArChanDesc, pArChanDesc->pIndexBuf, blockNum); - if (stat != OK) { - (void)fprintf(stderr, - "arCF_INextDatInfo: error reading index block\n"); - --pArChanDesc->datInfNum; - return ERROR; - } - if (pArChanDesc->pIndexBuf->bfInfo.firstByte < BF_BLOCK_DATA) { - pArChanDesc->flags |= AR_CDESC_EOF; - --pArChanDesc->datInfNum; - return ERROR; - } - pArChanDesc->datInfNum = - (pArChanDesc->pIndexBuf->bfInfo.firstByte - BF_BLOCK_DATA) / - sizeof(AR_DAT_INFO); - assert(pArChanDesc->datInfNum >= 0); - assert(pArChanDesc->datInfNum < AR_CF_NDATINFO); - - if (ArCDDatInfo(pArChanDesc).stamp.secPastEpoch != 0) - pArChanDesc->timeStamp= ArCDDatInfo(pArChanDesc).stamp; - } - } - - return OK; -} - -/*+/subr********************************************************************** -* NAME arCF_IRead - read an index block into an index buffer -* -* DESCRIPTION -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -arCF_IRead(pArChanDesc, pIndexBuf, blockNum) -AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */ -AR_INDEX_BUF *pIndexBuf; /* IO pointer to index buffer */ -BF_BLKNUM blockNum; /* I block number to read */ -{ - if (bfRead(pArChanDesc->pArCfDesc->pBfDesc, &pIndexBuf->bfInfo, blockNum) - != OK) - return ERROR; - pIndexBuf->blkNum = blockNum; - ArCFModifyInit(pIndexBuf); - pIndexBuf->pBlock = &pIndexBuf->bfInfo; - - return OK; -} - -/*+/subr********************************************************************** -* NAME arCF_MIAddBlock - add a new block to the master index -* -* DESCRIPTION -* Acquire a block (either from free block list or by expanding the -* file) and add it to the master index. The new block is formatted -* with 'free channel headers', which are linked into the free chanHdr -* list, at its head. -* -* The MODIFIED flag is set for the new MI block. If there was a 'tail' -* MI block which has been linked to this one, its MODIFIED flag is -* also set. -* -* RETURNS -* OK, or -* ERROR -* -*-*/ -long -arCF_MIAddBlock(pArCfDesc) -AR_CF_DESC *pArCfDesc; /* IO pointer to channel file descriptor */ -{ - int retStat=OK; /* return status to caller */ - - BF_BLKNUM block; /* number of acquired block */ - AR_MI_BUF *pMIBuf; /* pointer to buffer for block */ - int i; /* temp for loops */ - - assert(pArCfDesc != NULL); - assert(pArCfDesc->pBfDesc != NULL); - -/*---------------------------------------------------------------------------- -* allocate a buffer to hold new block and acquire a new block -*---------------------------------------------------------------------------*/ - pMIBuf = arCF_mallocMI_BUF(); - if (pMIBuf == NULL) { - (void)fprintf(stderr, - "arCF_MIaddBlock: can't malloc for new MI block\n"); - retStat = ERROR; - } - if (retStat == OK) { - block = bfAcquire(pArCfDesc->pBfDesc, &pMIBuf->bfInfo); - if (block == ERROR) { - (void)fprintf(stderr, - "arCF_MIaddBlock: can't acquire block for file\n"); - retStat = ERROR; - } - } - if (retStat == OK) { -/*---------------------------------------------------------------------------- -* set up miscellaneous fields in new block -* -* install this block as MIHead, if it's the first MI block -* if there was an old MITail, link it to this new block and mark it as -* modified -* install this block as MITail and mark it as modified -* increment count of MI blocks (block0 only) -* -* please pardon the confusion here, but there are two linked lists to -* maintain--the list of blocks on disk and the list of buffers in memory. -* The disk list is rooted in block0; the memory list is rooted in the -* channel file descriptor. -*---------------------------------------------------------------------------*/ - pMIBuf->blkNum = block; - ArCFModifyInit(pMIBuf); - pMIBuf->pBlock = &pMIBuf->bfInfo; - ArCFModifySet(pArCfDesc, pMIBuf); - pArCfDesc->b0Modified = 1; - pMIBuf->pNextMI = NULL; - if (pArCfDesc->pMIHead == NULL) { - assert(ArB0MIHead(pArCfDesc) == 0); - assert(pArCfDesc->pMITail == NULL); - assert(ArB0MITail(pArCfDesc) == 0); - pArCfDesc->pMIHead = pMIBuf; - ArB0MIHead(pArCfDesc) = block; - } - else { - assert(pArCfDesc->pMITail != NULL); - assert(ArB0MITail(pArCfDesc) != 0); - pArCfDesc->pMITail->pNextMI = pMIBuf; - pArCfDesc->pMITail->bfInfo.flink = block; - ArCFModifySet(pArCfDesc, pArCfDesc->pMITail); - pArCfDesc->b0Modified = 1; - } - pArCfDesc->pMITail = pMIBuf; - ArB0MITail(pArCfDesc) = block; - ArB0MINblk(pArCfDesc) += 1; -/*---------------------------------------------------------------------------- -* 'format' the new block into individual free channel headers and link -* these into the memory (CfDesc) and disk (block0) structures. (This -* block is put at the head of the list of free chanHdr's.) The name in -* each free channel header has its first character set to '\0' . -*---------------------------------------------------------------------------*/ - for (i=0; ichanHdr[i].name[0] = '\0'; - pMIBuf->chanHdr[i].graphics.nextMIFree.blkNum = - ichanHdr[i].graphics.nextMIFree.hdrNum = - ipMIFree = pMIBuf; - pArCfDesc->MIFree_hdrNum = 0; -/*---------------------------------------------------------------------------- -* initialize the block file information for the block; the file -* flink in the previous block (if there was a previous block) was set above -*---------------------------------------------------------------------------*/ - pMIBuf->bfInfo.flink = 0; - pMIBuf->bfInfo.firstByte = BF_BLOCK_DATA; - pMIBuf->bfInfo.lastByte = BF_BLOCK_DATA - 1 + - AR_CF_NHDR * sizeof(AR_CHAN_HDR); - - } - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCF_MIAddChan - add a channel to the master index -* -* DESCRIPTION -* Gets the next free channel header from the free chanHdr list and -* performs some initialization for the new chanHdr. A new MI block -* is acquired if there were no entries on the free chanHdr list. -* -* The MODIFIED flag is set for the MI block. -* -* This routine isn't intended as the primary user routine for adding -* a channel to a channel file--use arCFChanOpen() instead. -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o if the forward link (to the next free chanHdr) in the acquired -* chanHdr points to another block, then a search of the entire MI -* list may be necessary to find the MI buffer pointer to store in -* the channel file descriptor for pMIFree. -* o doesn't add the channel to the hash table (which doesn't -* presently exist) -* -* SEE ALSO -* arCFChanOpen(), arCF_MIDelChan -* -*-*/ -long -arCF_MIAddChan(pArCfDesc, name, ppMIBuf, pIndex) -AR_CF_DESC *pArCfDesc; /* IO pointer to channel file descriptor */ -char *name; /* I channel name */ -AR_MI_BUF **ppMIBuf; /* O ptr to ptr to MI block containing channel */ -int *pIndex; /* O pointer to location to store index within - MI block of chanHdr of added channel */ -{ - int retStat=OK; /* return status to caller */ - AR_MI_BUF *pMIBuf; /* ptr to MI block for new chanHdr */ - short indx; /* chanHdr index in MI block */ - AR_CHAN_HDR *pChanHdr; /* pointer to actual chanHdr */ - - assert(pArCfDesc != NULL); - assert(pArCfDesc->pBfDesc != NULL); - assert(name != NULL); - assert(ppMIBuf != NULL); - assert(pIndex != NULL); - assert(strlen(name) > 0); - assert(strlen(name) < AR_NAME_DIM); - -/*---------------------------------------------------------------------------- -* if there aren't any entries on the free chanHdr list (pMIFree), then -* add a new MI block to the file, putting its chanHdr's on the free list -*---------------------------------------------------------------------------*/ - if (pArCfDesc->pMIFree == NULL) { - if (arCF_MIAddBlock(pArCfDesc) != OK) - retStat = ERROR; - } -/*---------------------------------------------------------------------------- -* get a chanHdr, removing it from the free chanHdr list. Then -* initialize the chanHdr with some default information, including the -* name provided by the caller. -*---------------------------------------------------------------------------*/ - if (retStat == OK) { - BF_BLKNUM blkNum; /* block # for next empty chanHdr */ - int hdrNum; /* index in block for next empty chanHdr */ - -/*---------------------------------------------------------------------------- -* grab the first entry from the free chanHdr list, getting its block -* address and subscript, and also getting the actual address of the -* chanHdr -*---------------------------------------------------------------------------*/ - pMIBuf = pArCfDesc->pMIFree; /* 'address' of this */ - indx = pArCfDesc->MIFree_hdrNum; /* chanHdr */ - pChanHdr = &pMIBuf->chanHdr[indx]; - assert(pChanHdr->name[0] == '\0'); /* make sure it's empty */ - -/*---------------------------------------------------------------------------- -* set the head of the free chanHdr list to point to the next free -* chanHdr. Several special cases exist: no 'next'; 'next' is in the -* same MI block as the chanHdr we just got; 'next' is in the next -* MI block. If none of the special cases are true, then the whole -* MI chain is searched for the MI buffer with the specified block -* number (remember, we don't have a direct way to translate between -* 'disk block' number and 'address of buffer in memory'). -* -* the 'free chanHdr list' has two parts to be set: the block number and -* index in block0; and the buffer address and index in the channel file -* descriptor. -*---------------------------------------------------------------------------*/ - blkNum = pChanHdr->graphics.nextMIFree.blkNum; - hdrNum = pChanHdr->graphics.nextMIFree.hdrNum; - if (blkNum == 0) { /* no 'next' empty chanHdr */ - pArCfDesc->pMIFree = NULL; - pArCfDesc->MIFree_hdrNum = 0; - } - else if (blkNum == pMIBuf->blkNum) { /* in this block? */ - pArCfDesc->pMIFree = pMIBuf; - pArCfDesc->MIFree_hdrNum = hdrNum; - } - else { /* search for buffer with next empty chanHdr */ - AR_MI_BUF *pMIFree; /* temp during search */ - - if (pMIBuf->pNextMI != NULL) { /* in next block? */ - if (blkNum == pMIBuf->pNextMI->blkNum) { - pMIFree = pMIBuf->pNextMI; - goto searchDone; - } - } - pMIFree = pArCfDesc->pMIHead; - while (pMIFree != NULL) { - if (pMIFree->blkNum == blkNum) - goto searchDone; - pMIFree = pMIFree->pNextMI; - } -searchDone: - assert(pMIFree != NULL); /* MUST find a match! */ - assert(pMIFree->chanHdr[hdrNum].name[0] == '\0'); - pArCfDesc->pMIFree = pMIFree; - pArCfDesc->MIFree_hdrNum = hdrNum; - } - ArB0MIFree_blkNum(pArCfDesc) = blkNum; - ArB0MIFree_hdrNum(pArCfDesc) = hdrNum; - -/*---------------------------------------------------------------------------- -* initialize the new chanHdr -* -* mark the MI block as having been altered -*---------------------------------------------------------------------------*/ - (void)strcpy(pChanHdr->name, name); - pChanHdr->chanType = TYPENOTCONN; - pChanHdr->elCount = 0; - pChanHdr->indexHead = 0; - pChanHdr->indexTail = 0; - pChanHdr->oldestSecPastEpoch = 0; - pChanHdr->newestSecPastEpoch = 0; - pChanHdr->newestNsec = 0; - pChanHdr->flags = 0; - pChanHdr->count = 0; - - ArCFModifySet(pArCfDesc, pMIBuf); - pArCfDesc->b0Modified = 1; - - *ppMIBuf = pMIBuf; - *pIndex = indx; - } - - return retStat; -} - -/*+/subr********************************************************************** -* NAME arCF_MIDelChan - delete a chanHdr from master index -* -* DESCRIPTION -* Deletes a chanHdr from the master index, making it into a -* 'free chanHdr' and placing it at the head of the free chanHdr list. -* -* The MODIFIED bit is set the the MI block. -* -* RETURNS -* OK -* -* BUGS -* o doesn't remove the channel from the hash table (which doesn't -* presently exist) -* o doesn't check for index blocks and data blocks--if either exists, -* memory buffers and disk blocks are essentially 'lost'. -* -* SEE ALSO -* arCF_MIAddChan() -* -*-*/ -long -arCF_MIDelChan(pArCfDesc, pMIBuf, indx) -AR_CF_DESC *pArCfDesc; /* IO pointer to channel file descriptor */ -AR_MI_BUF *pMIBuf; /* IO pointer to MI block containing channel */ -int indx; /* I index within MI block of chanHdr for channel */ -{ - assert(pArCfDesc != NULL); - assert(pArCfDesc->pBfDesc != NULL); - assert(indx >= 0); - assert(indx < BfB0BlockSize(pArCfDesc->pBfDesc) / sizeof(AR_CHAN_HDR)); - -/*---------------------------------------------------------------------------- -* update disk information in disk block and block0 -*---------------------------------------------------------------------------*/ - pMIBuf->chanHdr[indx].graphics.nextMIFree.blkNum = - ArB0MIFree_blkNum(pArCfDesc); - pMIBuf->chanHdr[indx].graphics.nextMIFree.hdrNum = - ArB0MIFree_hdrNum(pArCfDesc); - ArB0MIFree_blkNum(pArCfDesc) = pMIBuf->blkNum; - ArB0MIFree_hdrNum(pArCfDesc) = indx; -/*---------------------------------------------------------------------------- -* update pointer and index in channel file descriptor -*---------------------------------------------------------------------------*/ - pArCfDesc->pMIFree = pMIBuf; - pArCfDesc->MIFree_hdrNum = indx; - -/*---------------------------------------------------------------------------- -* mark this chanHdr as 'free', and set the MODIFIED bit for the MI block -*---------------------------------------------------------------------------*/ - pMIBuf->chanHdr[indx].name[0] = '\0'; - ArCFModifySet(pArCfDesc, pMIBuf); - pArCfDesc->b0Modified = 1; - - return OK; -} - -/*+/subr********************************************************************** -* NAME arCF_MIFindChan - search master index for a specified channel -* -* DESCRIPTION -* Search for the specified channel name in the Master Index blocks -* in memory. -* -* RETURNS -* OK, or -* ERROR if channel name not found -* -* BUGS -* o uses a linear search through all MI blocks -* o all MI blocks must be in memory -* -* EXAMPLE -* -*-*/ -long -arCF_MIFindChan(pArCfDesc, name, ppMIBuf, pIndex) -AR_CF_DESC *pArCfDesc; /* I pointer to channel file descriptor */ -char *name; /* I channel name */ -AR_MI_BUF **ppMIBuf; /* O ptr to ptr to MI block containing channel; - if NULL, no MI block pointer will be - returned */ -int *pIndex; /* O pointer to location to store index within - MI block of chanHdr for channel; if NULL, no - index will be returned */ -{ - AR_MI_BUF *pMIBuf; /* pointer to MI block for search */ - int i; - - assert(pArCfDesc != NULL); - assert(pArCfDesc->pBfDesc != NULL); - assert(name != NULL); - assert(strlen(name) > 0); - assert(strlen(name) < AR_NAME_DIM); - - pMIBuf = pArCfDesc->pMIHead; /* head of MI list in memory */ - - while (pMIBuf != NULL) { - for (i=0; ichanHdr[i].name[0] != '\0') { - if (strcmp(pMIBuf->chanHdr[i].name, name) == 0) - goto done; - } - } - pMIBuf = pMIBuf->pNextMI; /* next MI block in memory */ - } - -done: - if (ppMIBuf != NULL) - *ppMIBuf = pMIBuf; - if (pIndex != NULL) - *pIndex = i; - - return(pMIBuf==NULL ? ERROR : OK); -} - -long -arCF_MIFlush(pCfDesc, pMIBuf) -AR_CF_DESC *pCfDesc; /* I pointer to channel file descriptor */ -AR_MI_BUF *pMIBuf; /* I pointer to MI block */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status */ - - if (ArCFModifyTestAndReset(pCfDesc, pMIBuf)) { - stat = bfWrite(pCfDesc->pBfDesc, &pMIBuf->bfInfo, pMIBuf->blkNum); - if (stat != OK) - retStat = ERROR; - } - if (pCfDesc->b0Modified) { - pCfDesc->b0Modified = 0; - stat = bfWrite(pCfDesc->pBfDesc, pCfDesc->pBfDesc->pBlock0, 0); - if (stat != OK) - retStat = ERROR; - } - return retStat; -} diff --git a/src/libCom/bdt.c b/src/libCom/bdt.c deleted file mode 100644 index 5db3b9cb7..000000000 --- a/src/libCom/bdt.c +++ /dev/null @@ -1,613 +0,0 @@ -#include -#include -#include -#include -#ifdef linux -#include -#endif -#include -#include - -#ifdef vxWorks -#include -#include -#include -#include -#else -#include -#include -#include -#endif - -#include -#include - -#include "bdt.h" - -/* ---------------------------------------------------------------------- */ -/* server mode functions */ - -#ifndef vxWorks /* server mode functions */ -static char* filename=(char*)NULL; - -/* ----------------------------- */ -/* signal catcher for the server */ -/* ----------------------------- */ -static void catch_sig(int sig) -{ - fprintf(stderr,"\nbdt server exiting\n"); - unlink(filename); - exit(0); -} - -/* -------------------------------- */ -/* child reaper for the server mode */ -/* -------------------------------- */ -static void get_child(int sig) -{ - while(wait3((int *)NULL,WNOHANG,(struct rusage *)NULL)>0); -#ifdef linux - signal(SIGCHLD,get_child); /* for reaping children */ -#endif -} - -/* ------------------------------- */ -/* Clear the signals for a process */ -/* ------------------------------- */ -int BdtServerClearSignals() -{ - signal(SIGCHLD,SIG_DFL); - signal(SIGHUP,SIG_DFL); - signal(SIGINT,SIG_DFL); - signal(SIGTERM,SIG_DFL); - signal(SIGQUIT,SIG_DFL); - return 0; -} - -/* ----------------------------------------------------- */ -/* Make a unix process into a generic background process */ -/* ----------------------------------------------------- */ -int BdtMakeServer(char** argv) -{ - FILE* fd; - - if(filename) return -1; - - /* set up signal handling for the server */ - signal(SIGCHLD,get_child); /* for reaping children */ - signal(SIGHUP,catch_sig); - signal(SIGINT,catch_sig); - signal(SIGTERM,catch_sig); - signal(SIGQUIT,catch_sig); - - /* disconnect from parent */ - switch(fork()) - { - case -1: /* error */ - perror("Cannot fork"); - return -1; - case 0: /* child */ -#ifdef linux - setpgrp(); -#else - setpgrp(0,0); -#endif - setsid(); - break; - default: /* parent goes away */ - exit(0); - } - - /* save process ID */ - filename=(char*)malloc(strlen(argv[0])+10); - sprintf(filename,"%s.%d",argv[0],getpid()); - fd=fopen(filename,"w"); - fprintf(fd,"%d",getpid()); - fprintf(stderr,"\npv server pid: %d\n",getpid()); - fclose(fd); - - return 0; -} -#endif /* server mode functions */ - -/* ------------------------------------------ */ -/* unimplemented channel access open function */ -/* ------------------------------------------ */ -BDT* BdtPvOpen(char* name) -{ - return (BDT*)NULL; -} - -/* --------------------------------------------------------------- */ -/* open a bulk data socket to a server given the server IP address */ -/* --------------------------------------------------------------- */ -BDT* BdtIpOpen(char* address, int Port) -{ - struct sockaddr_in tsin; - unsigned long addr; - int osoc; - BDT* bdt; - - /* request the process variables (bulk data?) */ - addr=inet_addr(address); - - tsin.sin_port=0; - tsin.sin_family=AF_INET; - tsin.sin_addr.s_addr=htonl(INADDR_ANY); - - if((osoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0) - { - perror("BdtIpOpen: create socket failed"); - return (BDT*)NULL; - } - - if((bind(osoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0) - { - perror("BdtIpOpen: local address bind failed"); - return (BDT*)NULL; - } - - tsin.sin_port=htons(Port); - memcpy((char*)&tsin.sin_addr,(char*)&addr,sizeof(addr)); - - if(connect(osoc,(struct sockaddr*)&tsin,sizeof(tsin))<0) - { - perror("BdtIpOpen: connect failed"); - close(osoc); - return (BDT*)NULL; - } - - bdt=(BDT*)malloc(sizeof(BDT)); - bdt->soc=osoc; - bdt->pending_delta=0; - bdt->remaining_send=0; - bdt->remaining_recv=0; - bdt->state=BdtUnbound; - - /* now connected to the bulk data socket on the IOC */ - return bdt; -} - -/* -------------------------------------- */ -/* write size bytes from buffer to socket */ -/* -------------------------------------- */ -int BdtWrite(int soc,void* buffer,int size) -{ - int rc,total; - unsigned char* data; - - data=(unsigned char*)buffer; - total=size; - - do - { - /* send block of data */ - if((rc=send(soc,&data[size-total],total,0))<0) - { - if(errno==EINTR) - rc=0; - else - { perror("BdtWrite: Send to remote failed"); } - } - else - total-=rc; - } - while(rc>0 && total>0); - - return (rc<=0)?-1:0; -} - -/* --------------------------------------- */ -/* send a message header down a BDT socket */ -/* --------------------------------------- */ -int BdtSendHeader(BDT* bdt,unsigned short verb,int size) -{ - BdtMsgHead buf; - - if(bdt->state!=BdtIdle) - { - fprintf(stderr,"BdtSendHeader: Interface not idle\n"); - bdt->state=BdtBad; - return -1; - } - - buf.verb=htons(verb); - buf.size=htonl((unsigned long)size); - - if(BdtWrite(bdt->soc,&buf.verb, sizeof(buf.verb))<0) - { - fprintf(stderr,"BdtSendHeader: write to remote failed"); - return -1; - } - if(BdtWrite(bdt->soc,&buf.size, sizeof(buf.size))<0) - { - fprintf(stderr,"BdtSendHeader: write to remote failed"); - return -1; - } - - /* don't wait for response if data must go out */ - if(size) - { - bdt->remaining_send=size; - bdt->state=BdtSData; - } - - return 0; -} - -/* ------------------------------------------- */ -/* send a message data chunk down a BDT socket */ -/* ------------------------------------------- */ -int BdtSendData(BDT* bdt,void* buffer,int size) -{ - int len,remaining,rc; - - if(bdt->state!=BdtSData) - { - fprintf(stderr,"BdtSendData: Interface not in send data mode\n"); - bdt->state=BdtBad; - return -1; - } - - remaining=bdt->remaining_send-size; - - if(remaining<0) - { - fprintf(stderr,"BdtSendData: To much data to send\n"); - len=bdt->remaining_send; - } - else - len=size; - - /* this function should loop until size bytes is sent */ - - /* send out the chunk */ - if((rc=send(bdt->soc,(char*)buffer,len,0))<0) - { - perror("BdtSendData: Send data chunk to remote failed"); - return -1; - } - - bdt->remaining_send-=rc; - - if(bdt->remaining_send<0) - { - fprintf(stderr,"BdtSendData: To much data Sent\n"); - bdt->remaining_send=0; - } - - if(bdt->remaining_send==0) - bdt->state=BdtIdle; - - return rc; -} - -/* ------------------------------------------------------------------------ - report if data is pending from remote - clear the pending data condition - ------------------------------------------------------------------------ */ -int BdtPvDeltaPending(BDT* bdt) -{ - int rc = bdt->pending_delta; - bdt->pending_delta=0; - return rc; -} - -/* ------------------------------------- */ -/* Read exactly size bytes from remote */ -/* ------------------------------------- */ -int BdtRead(int soc,void* buffer,int size) -{ - int rc,total; - unsigned char* data; - - data=(unsigned char*)buffer; - total=size; - - do - { - /* wait for data chunk */ - if((rc=recv(soc,&data[size-total],total,0))<0) - { - if(errno==EINTR) - rc=0; - else - { perror("BdtRead: Receive data chunk failed"); } - } - else - total-=rc; - } - while(rc>0 && total>0); - - return (rc<=0)?-1:0; -} - -/* ------------------------------------- */ -/* wait for a message header from remote */ -/* ------------------------------------- */ -int BdtReceiveHeader(BDT* bdt,int* verb,int* size) -{ - BdtMsgHead buf; - - /* can only receive header when in the idle state */ - if (bdt->state == BdtEof) - return -1; - - if(bdt->state != BdtIdle) - { - fprintf(stderr,"BdtReceiveHeader: Interface not idle\n"); - bdt->state=BdtBad; - return -1; - } - - if(BdtRead(bdt->soc,&buf.verb,sizeof(buf.verb))<0) - { - fprintf(stderr,"BdtReceiveHeader: Read failed\n"); - return -1; - } - if(BdtRead(bdt->soc,&buf.size,sizeof(buf.size))<0) - { - fprintf(stderr,"BdtReceiveHeader: Read failed\n"); - return -1; - } - - /* copy message data to user */ - *verb=ntohs(buf.verb); - *size=ntohl(buf.size); - - if(*size) - bdt->state=BdtRData; - - bdt->remaining_recv=*size; - - return 0; -} - -/* ------------------------------------------------------------------------ - Wait for a chunk of data from remote. - User can continually call this with a maximum size until it return 0. - ------------------------------------------------------------------------ */ -int BdtReceiveData(BDT* bdt,void* buffer,int size) -{ - int rc; - - /* can only receive data when in the receive data state */ - switch(bdt->state) - { - case BdtRData: break; - case BdtIdle: return 0; - default: - fprintf(stderr,"BdtReceiveData: bad receive state\n"); - bdt->state=BdtBad; - break; - } - - if(BdtRead(bdt->soc,buffer,size)<0) - { - fprintf(stderr,"BdtReceiveData: Read failed\n"); - bdt->state = BdtEof; - return -1; - } - - bdt->remaining_recv-=size; - - if(bdt->remaining_recv<0) - { - fprintf(stderr,"BdtReceiveData: To much data received\n"); - bdt->remaining_recv=0; - } - - if(bdt->remaining_recv==0) - bdt->state=BdtIdle; - - return size; -} - -/* ------------------------------------------------------ */ -/* connect to a process variable, useful if raw open used */ -/* ------------------------------------------------------ */ -int BdtServiceConnect(BDT* bdt, char* service_name) -{ - int len,rc,size,verb; - - if(bdt->state!=BdtUnbound) - { - fprintf(stderr,"BdtServiceConnect: can only bind to one service\n"); - return -1; - } - - bdt->state=BdtIdle; - len=strlen(service_name)+1; - - /* send out connect message */ - if(BdtSendHeader(bdt,BDT_Connect,len)<0) - { - fprintf(stderr,"BdtServiceConnect: send of connect header failed\n"); - bdt->state=BdtUnbound; - return -1; - } - - /* send out the process variable to connect to */ - if(BdtSendData(bdt,service_name,len)<0) - { - fprintf(stderr,"BdtServiceConnect: send of connect body failed\n"); - bdt->state=BdtUnbound; - return -1; - } - - rc=0; - - /* wait for response from connect to process variable */ - if(BdtReceiveHeader(bdt,&verb,&size)<0) - { - fprintf(stderr,"BdtServiceConnect: receive reponse failed\n"); - bdt->state=BdtUnbound; - return -1; - } - - /* check response */ - switch(verb) - { - case BDT_Ok: - rc=0; - break; - case BDT_Error: - fprintf(stderr,"BdtServiceConnect: connection rejected\n"); - bdt->state=BdtUnbound; - rc=-1; - break; - default: - fprintf(stderr,"BdtServiceConnect: unknown response from remote\n"); - bdt->state=BdtUnbound; - rc=-1; - break; - } - - return rc; -} - -/* -------------------- */ -/* close the connection */ -/* -------------------- */ -int BdtClose(BDT* bdt) -{ - int verb,size,done; - - /* send a close message out */ - if(BdtSendHeader(bdt,BDT_Close,0)<0) - { - fprintf(stderr,"BdtClose: Cannot send close message\n"); - return -1; - } - - done=0; - - do - { - /* check response */ - if(BdtReceiveHeader(bdt,&verb,&size)<0) - { - fprintf(stderr,"BdtClose: Close message response error\n"); - return -1; - } - - switch(verb) - { - case BDT_Ok: - done=1; - break; - case BDT_Error: - fprintf(stderr,"BdtClose: Close rejected\n"); - return -1; - break; - default: break; - } - } - while(done==0); - - bdt->state=BdtUnbound; - free(bdt); - return 0; -} - -/* --------------------------------------- */ -/* make a listener socket for UDP - simple */ -/* --------------------------------------- */ -int BdtOpenListenerUDP(int Port) -{ - int nsoc; - struct sockaddr_in tsin; - - tsin.sin_port=htons(Port); - tsin.sin_family=AF_INET; - tsin.sin_addr.s_addr=htonl(INADDR_ANY); - - if((nsoc=socket(AF_INET,SOCK_DGRAM,BDT_UDP))<0) - { - perror("BdtOpenListenerUDP: open socket failed"); - return -1; - } - - if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0) - { - perror("BdtOpenListenerUDP: local bind failed"); - close(nsoc); - return -1; - } - - return nsoc; -} - -/* --------------------------------------- */ -/* make a listener socket for TCP - simple */ -/* --------------------------------------- */ -int BdtOpenListenerTCP(int Port) -{ - int nsoc; - struct sockaddr_in tsin; - - memset (&tsin, 0, sizeof(struct sockaddr_in)); - tsin.sin_port=htons(Port); - tsin.sin_family=htons(AF_INET); - tsin.sin_addr.s_addr=htonl(INADDR_ANY); - - if((nsoc=socket(AF_INET,SOCK_STREAM,BDT_TCP))<0) - { - perror("BdtOpenListenerTCP: open socket failed"); - return -1; - } - - if((bind(nsoc,(struct sockaddr*)&tsin,sizeof(tsin)))<0) - { - perror("BdtOpenListenerTCP: local bind failed"); - close(nsoc); - return -1; - } - - listen(nsoc,5); - return nsoc; -} - -/* ------------------------------- */ -/* make BDT from a socket - simple */ -/* ------------------------------- */ -BDT* BdtMakeBDT(int soc) -{ - BDT* bdt; - bdt=(BDT*)malloc(sizeof(BDT)); - bdt->soc=soc; - bdt->pending_delta=0; - bdt->remaining_send=0; - bdt->remaining_recv=0; - bdt->state=BdtIdle; - return bdt; -} - -/* --------------------------- */ -/* free a BDT and close socket */ -/* --------------------------- */ -int BdtFreeBDT(BDT* bdt) -{ - close(bdt->soc); - free(bdt); - return 0; -} - -/* ------------------------------------------------- */ -/* connect to a generic service on the remote server */ -/* ------------------------------------------------- */ -int BdtPvConnect(BDT* bdt, char* pv_name) -{ - char* data; - int len,rc; - - len=strlen(pv_name)+strlen(BDT_PV_SERVICE)+2; - data=(char*)malloc(len); - sprintf(data,"%s %s",BDT_PV_SERVICE,pv_name); - - rc=BdtServiceConnect(bdt,data); - - free(data); - return rc; -} - diff --git a/src/libCom/bfSubr.c b/src/libCom/bfSubr.c deleted file mode 100644 index c86109bb8..000000000 --- a/src/libCom/bfSubr.c +++ /dev/null @@ -1,1584 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 03-05-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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 03-05-90 rac initial version - * .02 07-30-91 rac installed in SCCS - * .03 09-14-92 rac discontinue using special malloc routines - * .04 10-29-92 rac under Unix, cope with write getting EINTR status - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code - */ -/*+/mod*********************************************************************** -* TITLE bfSubr.c - 'block file' subroutines -* -* DESCRIPTION -* These subroutines implement a fixed block size file system based on -* the usual byte-oriented file system available to C. The operations -* used by these routines are: -* o open() with O_RDONLY, O_RDWR, and O_CREAT as options. The O_EXCL -* option found in some operating systems isn't used. Instead, these -* routines create a "fileName.lock" file to enforce a single writer. -* o lseek() with L_SET as the option used. -* o read(), write(), and close() -* -* On disk, the file system is a file containing fixed size blocks. These -* routines maintain a singly-threaded list of 'free' blocks which are -* available for use. User routines built on top of these routines -* must maintain singly-threaded lists of 'in use' blocks. -* -* These routines maintain some information in a file descriptor in memory. -* This information isn't written to the disk until the file is closed. -* Users of these routines must take particular care to ensure that -* bfClose() is called for all open files. -* -* Since information about the file is kept in the file descriptor, these -* routines aren't reentrant with respect to a single file. Several file -* descriptors can be used simultaneously, one per thread, without -* interference. -* -* Although these routines do a reasonable amount of error checking, the -* user must bear a significant amount of responsibility in abiding by -* the rules. Some cautions for the user include: -* o don't use pointers to file descriptors after bfClose() is called -* o don't exceed the block size for the file. BF_MAX_BLOCK_SIZE is the -* largest a block will ever be, but BfBlockSize(pDesc) returns the -* actual block size for a particular file. -* -* Users are strongly encouraged to use the BfXxx() macros when dealing -* with block0 or the file descriptor. -* -* INCLUDE FILES -* In general, use of the block file routines requires using several -* include files. The set used differs between SunOS and VxWorks: -* -* SunOs VxWorks -* -* -* -* -* -* -* BUGS -* o routines aren't reentrant with respect to a single file -* o some operations require an operating system file I/O call when, with -* appropriate enhancements, such I/O could be avoided, or at least -* deferred -* o a list of open block files should be kept for a task, and an exit -* handler should be established for a task, so that cleanup is assured -* o the issue of blocking signals during critical operations should be -* addressed -* o error handling is rudimentary: there are no individualized error -* codes; most error messages don't include file name; error messages -* are sent to stdout; etc. -* o these routines use blocking I/O. Under SunOS, non-blocking I/O -* might be better. -* -*-***************************************************************************/ - - -/*---------------------------------------------------------------------------- -* synopsis summaries -* < indicates input arg to function -* > indicates output arg from function -* <> indicates arg both input to and output from function -* -* except as noted, 'int' functions return OK or ERROR -* blockNum must be 'BF_BLKNUM' -* -* char *bfRingFgets(>pBuf, pBfDesc ) -* returns pBuf or NULL -* int bfRingFputs(pBfDesc ) -* returns last character or EOF -* int BfRingGetc(<>pDesc ) -* returns character or EOF -* int BfRingPutc( pBfDesc ) -* returns character or EOF -* -*BF_BLKNUM bfAcquire( <>pBfDesc, <>pBfBlock ) -* returns blockNum or ERROR -* int bfClose( <>ppBfDesc ) -* BF_DESC *bfCreate( pBfBlock, pBfDesc, <>pBfBlock, pBfBlock, -#include -#include - -#ifdef vxWorks -# include -# include -# include - typedef long off_t; /* for lseek() */ -#else -# include -# include -# include -# include -#endif - -#ifdef LINT - char *glBfTypeKw[]; - - main() - { - char *pBuf; - BF_DESC *pDesc; - BF_BLOCK *pBlock; - - exit(1); - - pBuf = NULL; - pDesc = NULL; - pBlock = NULL; - - (void) bfRingFgets(pBuf, 0, pDesc); - (void) bfRingFputs(pBuf, pDesc); - (void) bfClose(&pDesc); - pDesc = bfCreate(" ", 0, (BF_BLKNUM)0, 0, (long)0, (BF_BLKNUM)0); - (void) bfInfo(" "); - (void) bfRelease(pDesc, pBlock, (BF_BLKNUM)0); - } -#endif - -BF_DESC *bfMallocDesc() -{ return (BF_DESC *)malloc(sizeof(BF_DESC)); } -void bfFreeDesc(ptr) -BF_DESC *ptr; -{ free(ptr); } - -BF_BLOCK0 *bfMallocBlock0() -{ return (BF_BLOCK0 *)malloc(sizeof(BF_BLOCK0)); } -void bfFreeBlock0(ptr) -BF_BLOCK0 *ptr; -{ free(ptr); } - - -/*+/subr********************************************************************** -* NAME bfRingFgets - get a line from a ring file -* -* DESCRIPTION -* Read the next line, including the newline, from the ring file into -* the caller's buffer. The last character placed in the caller's buffer -* is always followed by '\0'. -* -* At most bufDim-1 characters are transferred; if no newline was -* encountered, then the remaining characters will be read with the -* next call. -* -* Due to the nature of ring files, the first call to bfRingFgets() -* may encounter a partial line. If this occurs, the partial line -* is discarded and the first full line is returned. -* -* RETURNS -* pBuf, or -* NULL if an error occurs or EOF is encountered -* -*-*/ -char * -bfRingFgets(pBuf, bufDim, pDesc) -char *pBuf; /* buffer to receive up to 'bufDim-1' characters */ -int bufDim; /* dimension of buffer */ -BF_DESC *pDesc; /* block file descriptor */ -{ - int c; /* character from file */ - char *pBuf1; /* temporary buffer pointer */ - - pBuf1 = pBuf; - while (--bufDim > 0 && (c = BfRingGetc(pDesc)) != EOF) { - if ((*pBuf1++ = c) == '\n') - break; - } - *pBuf1 = '\0'; - return ((c == EOF && pBuf1 == pBuf) ? NULL : pBuf); -} - -/*+/subr********************************************************************** -* NAME bfRingFillRbufAndGetc - get next block and return a character -* -* DESCRIPTION -* Reads the next readable block from the ring file and returns the -* first readable character from the block. (If the present block, if -* any, contains unread characters, then those characters will be -* skipped.) -* -* Due to the nature of ring files, the first call to bfRingFillRbuf() -* may encounter a partial line. If this occurs, the partial line -* is discarded and the character is obtained from the first full line. -* -* The macro BfRingGetc(pDesc) is the recommended method for reading -* a ring file a character at a time. That macro calls this routine -* as necessary. -* -* The routine bfRingFgets() is available for reading a ring file a line -* at a time. -* -* RETURNS -* character, or -* EOF if an error occurs or EOF is encountered -* -*-*/ -int -bfRingFillRbufAndGetc(pDesc) -BF_DESC *pDesc; /* IO block file descriptor for ring file */ -{ - int c; /* character to return to caller */ - int stat; - -/*---------------------------------------------------------------------------- -* first, decide which block to read for more data. If this is the first -* time a read has been done, use the ringHead block; otherwise, use the -* flink from the present block (if the present block is ringTail, then -* there is no next block). -*---------------------------------------------------------------------------*/ - if (pDesc->readCount < -9) - pDesc->readBlock = BfB0RingHead(pDesc); - else { - if (pDesc->readBlock == BfB0RingTail(pDesc)) - return EOF; - else - pDesc->readBlock = pDesc->pReadBuf->flink; - } -/*---------------------------------------------------------------------------- -* if the block number to read is zero, then there is nothing to do but -* return EOF. If the block number isn't zero, read the block; otherwise, -* return EOF. Once the block has been read, check lastByte; if it indicates -* no data, return EOF. -* -* When the first read is to be done, a buffer is obtained from malloc, -* with the pointer stored in the descriptor. This buffer will be free'd -* when the bfClose() is called. -* -*---------------------------------------------------------------------------*/ - if (pDesc->readBlock > 0) { - if (pDesc->pReadBuf == NULL) { - if ((pDesc->pReadBuf = - (BF_BLOCK *)malloc((unsigned)BfB0BlockSize(pDesc))) == - NULL) { - (void)fprintf(stderr, - "bfRingFillRbufAndGetc: can't get memory\n"); - return EOF; - } - } - stat = bfRead(pDesc, pDesc->pReadBuf, pDesc->readBlock); - if (stat != OK) - c = EOF; - else { - if (pDesc->pReadBuf->lastByte < BF_BLOCK_DATA) - c = EOF; - else { -/*---------------------------------------------------------------------------- -* set the read pointer and readCount. If this is the first read for the -* file, then start reading at firstByte; succeeding blocks start reading -* at BF_BLOCK_DATA, in order to read any overflow bytes from previous -* blocks. (If the block for the first read for the file contains only -* overflow bytes, then EOF is returned.) -* -* If the file isn't organized by lines, then reading always starts at -* BF_BLOCK_DATA. -* -*---------------------------------------------------------------------------*/ - int i=0; - - if (pDesc->readCount < -9) { /* first read for file */ - i = pDesc->pReadBuf->firstByte; - if (i == 0) /* file not line-oriented */ - i = BF_BLOCK_DATA; - } - else - i = BF_BLOCK_DATA; - - if (i < BF_BLOCK_DATA) { /* only overflow bytes */ - pDesc->pRead = NULL; - pDesc->readCount = 0; - c = EOF; - } - else { - pDesc->pRead = (char *)pDesc->pReadBuf + i - 1; - pDesc->readCount = pDesc->pReadBuf->lastByte - i + 1; - - c = (int)*(char *)(++pDesc->pRead); - pDesc->readCount--; - } - } - } - } - else - c = EOF; - - return c; -} - -/*+/subr********************************************************************** -* NAME bfRingFputs - put a line into a ring file -* -* DESCRIPTION -* Write the line, including the newline, into the ring file. The -* '\0' at the end of the caller's line isn't written into the file. -* -* If this is the first line written to a block, then firstByte is -* set to point to this line. -* -* RETURNS -* last character scanned from 'line' (typically '\0'), or -* EOF, if any error occurs -* -*-*/ -int -bfRingFputs(line, pDesc) -char *line; /* I line to write */ -BF_DESC *pDesc; /* IO pointer to descriptor */ -{ - if (*line != '\0') { - if (BfRingPutc(*line, pDesc) == EOF) - return EOF; - if (pDesc->pWriteBuf->firstByte == 0) { - pDesc->pWriteBuf->firstByte = pDesc->pWrite - - (char *)pDesc->pWriteBuf; - } - } - else - return *line; - - while (*(++line) != '\0') { - if (BfRingPutc(*line, pDesc) == EOF) - return EOF; - } - return *line; -} - -/*+/subr********************************************************************** -* NAME bfRingFlushWbufAndPutc - flush write buffer and write a character -* -* DESCRIPTION -* Write a block to the ring file, get the next block for writing, and -* put the character into the block. The file descriptor must have -* a pointer to the memory buffer for the block at entry (except -* immediately after bfOpen() ); at exit, a pointer to the memory buffer -* for the new block has been placed in the file descriptor. -* -* For the first write following bfOpen(), this routine obtains a -* memory buffer for the block and places the pointer into the descriptor. -* In this case, there is no buffer to flush. Succeeding calls to this -* routine will function as described above. -* -* When this routine is called the first time following bfOpen(), it -* attempts to begin writing in the ringTail block, if there is one. -* When additional blocks are needed for writing, attempts are made to -* acquire them in the following order: -* o try to get a block from the free block list -* o try to get a block by expanding the file if it is BF_FLAG_GROW -* o follow the current block's flink, if it isn't zero -* o if the current block's flink is zero, then grab the ringHead -* block for writing and move ringHead forward to its flink -* -* The macro BfRingFputc(c, pDesc) is the recommended method for -* writing a ring file a character at a time. That macro calls this -* routine as necessary. -* -* The routine bfRingFputs() is available for writing a ring file -* a line at a time. -* -* RETURNS -* character written, or -* EOF if an error occurs -* -* BUGS -* o does a malloc/free for every call -* -* EXAMPLE -* -*-*/ -int -bfRingFlushWbufAndPutc(c, pDesc) -char c; /* I character to write */ -BF_DESC *pDesc; /* IO pointer to ring file descriptor */ -{ - int stat; /* status return from calls */ - BF_BLKNUM flink; /* link to next write block */ - BF_BLOCK *pBuf; /* next write block */ - - if ((pBuf = (BF_BLOCK *)malloc((unsigned)BfB0BlockSize(pDesc))) == NULL) { - (void)fprintf(stderr, "bfRingFlushWbufAndPutc: can't get memory\n"); - return EOF; - } - - if (pDesc->writeBlock == 0) { -/*---------------------------------------------------------------------------- -* this is the first write for the file. Get a block for writing by -* trying first the ringTail block and then, if there isn't a ringTail, -* acquiring a block. If the ringTail block is full, make it look like -* the 'old' block, so that a new block will be acquired by the normal -* mechanism. -*---------------------------------------------------------------------------*/ - if ((flink = BfB0RingTail(pDesc)) > 0) { - stat = bfRead(pDesc, pBuf, flink); - if (stat != OK) { - (void)free((char *)pBuf); - return EOF; - } - if (pBuf->lastByte >= BfB0BlockSize(pDesc)-1) { - pDesc->pWriteBuf = pBuf; /* masquerade as old */ - pDesc->writeBlock = flink; - } - } - else { - flink = bfAcquire(pDesc, pBuf); - if (flink == ERROR) { - (void)free((char *)pBuf); - return EOF; - } - } - } - if (pDesc->writeBlock != 0) { -/*---------------------------------------------------------------------------- -* the current block is full. Obtain a new block. Attempts are made -* in the following order: -* o try to get a block from bfAcquire(), which will either remove -* a block from the free block list or which will expand the file. -* If neither succeeds, then: -* o follow the block's flink, if the flink isn't zero. If the flink -* is zero, then: -* o use the block which is currently the ringHead -* In the latter two cases, the block must be made to appear empty by -* setting firstByte and lastByte appropriately. -*---------------------------------------------------------------------------*/ - int readFlag; - - if ((flink = bfAcquire(pDesc, pBuf)) > 0) - readFlag = 0; - else { - if ((flink = pDesc->pWriteBuf->flink) > 0) - readFlag = 1; - else { - if ((flink = BfB0RingHead(pDesc)) > 0) - readFlag = 1; - else { - free((char *)pBuf); - return EOF; /* no new block available */ - } - } - } - if (readFlag) { /* only have flink; get the actual block */ - stat = bfRead(pDesc, pBuf, flink); - if (stat != OK) { - free((char *)pBuf); - return EOF; - } - pBuf->firstByte = 0; - pBuf->lastByte = BF_BLOCK_DATA - 1; - } - } -/*---------------------------------------------------------------------------- -* 'flink' is the number of a new block; 'pBuf' has its memory address. Wrap -* up processing on the 'old' block and then install the new one. -* -* first, install the proper flink into the current block. If the new block -* was obtained via bfAcquire(), then it is necessary to splice the new -* block into the flink chain. -* -* then, update the lastByte in the block to correspond with the pointer -* in the descriptor. -* -* finally, write the current block. (In some cases there isn't a current -* block to write; this will usually be the case on the first call after -* a file has been opened.) After writing the current block, free the -* buffer. -*---------------------------------------------------------------------------*/ - if (pDesc->pWriteBuf != NULL) { - if (pDesc->pWriteBuf->flink == flink) - ; /* old block's flink OK */ - else if (pDesc->pWriteBuf->flink == 0) - pDesc->pWriteBuf->flink = flink; /* link old to new */ - else { - pBuf->flink = pDesc->pWriteBuf->flink; /* splice flinks */ - pDesc->pWriteBuf->flink = flink; - } - - pDesc->pWriteBuf->lastByte = pDesc->pWrite - (char *)pDesc->pWriteBuf; - - stat = bfWrite(pDesc, pDesc->pWriteBuf, pDesc->writeBlock); - if (stat != OK) { - free((char *)pBuf); - return EOF; - } - free((char *)pDesc->pWriteBuf); - } - -/*---------------------------------------------------------------------------- -* the current block has been dealt with. Install the new one into the -* descriptor. (In the descriptor is the address of the memory that was -* malloc'ed above.) -*---------------------------------------------------------------------------*/ - if (BfB0RingHead(pDesc) == 0) - BfB0RingHead(pDesc) = flink; - else if (BfB0RingHead(pDesc) == flink) - BfB0RingHead(pDesc) = pBuf->flink; - - BfB0RingTail(pDesc) = flink; - pDesc->writeBlock = flink; - pDesc->pWriteBuf = pBuf; - pDesc->writeCount = BfB0BlockSize(pDesc) - pBuf->lastByte - 1; - pDesc->pWrite = (char *)pDesc->pWriteBuf + pBuf->lastByte; - -/*---------------------------------------------------------------------------- -* FINALLY (whew!), store the character that was sent in! -*---------------------------------------------------------------------------*/ - *(++pDesc->pWrite) = c; - --pDesc->writeCount; - - return c; -} - -/*+/subr********************************************************************** -* NAME bfAcquire - acquire a block for use -* -* DESCRIPTION -* Acquires a block for use by the caller, placing the block in the -* caller's buffer. -* -* bfAcquire() will acquire the block from the free block list, if any -* free blocks are available. If no free blocks are available, then -* the file is extended, if the BF_FLAG_GROW flag is set and the maximum -* size won't be violated. Otherwise, no block is obtained. -* -* The block number returned by bfAcquire() is the value which must -* be used with bfRead(), bfWrite(), etc. -* -* 'firstByte' is set to 0 . 'lastByte' points one character before -* the first available byte location. 'flink' is set to 0 . -* -* The free block list on disk isn't updated by bfAcquire(), so it is -* extremely important that bfClose() be called before exiting. -* -* RETURNS -* block number or -* ERROR (no error message is printed if reason for not being able to -* acquire a block is either: no free block or can't grow file) -* -* BUGS -* o should maintain an 'in memory' list of free blocks and replenish -* the list as necessary. This would avoid I/O delays on bfAcquire() -* calls. -* o should be able to get a free block without needing to do disk I/O -* o multiple, simultaneous calls to this routine could result in giving -* the same block to several callers. The callers must presently -* cooperate to prevent simultaneous calls. -* -* SEE ALSO -* bfRelease() -* -* EXAMPLE -* BF_DESC *pDesc; pointer to descriptor -* BF_BLOCK *pBuf; pointer to buffer containing block -* BF_BLKNUM blockNum; block number of acquired block -* -* pDesc = bfOpen("myFile", O_RDWR, BF_TYPE_UNDEF); -* pBuf = (BF_BLOCK *)malloc(BfB0BlockSize(pDesc)); -* blockNum = bfAcquire(pDesc, pBuf); -* pBuf->firstByte = pBuf->lastByte + 1; -* for (i=0; ilastByte] = myData[i]; -* stat = bfWrite(pDesc, pBuf, blockNum, 0); -* stat = bfClose(pDesc); -* free((char *)pBuf); -* -*-*/ -BF_BLKNUM -bfAcquire(pDesc, pBuf) -BF_DESC *pDesc; /* IO pointer to descriptor */ -BF_BLOCK *pBuf; /* IO buffer ptr; buf size is BfB0BlockSize(pDesc) */ -{ - int stat; /* status from calls */ - int blockNum; /* number of acquired block */ - - assert(pDesc != NULL); - assert(pBuf != NULL); - - if (!BfWriteable(pDesc)) { - (void)fprintf(stderr, "bfAcquire: file is O_RDONLY\n"); - return ERROR; - } - - if (BfB0Flink(pDesc) == 0) { -/*---------------------------------------------------------------------------- -* NO FREE BLOCK -- try to extend the file -*---------------------------------------------------------------------------*/ - if ( BfB0CurrentSize(pDesc) >= BfB0MaxSize(pDesc) || - (BfB0Flags(pDesc) & BF_FLAG_GROW) == 0 ) { - (void)fprintf(stderr, "bfAcquire: file maxSize reached\n"); - return ERROR; - } - else - blockNum = BfB0CurrentSize(pDesc)++; - } - else { -/*---------------------------------------------------------------------------- -* USE A FREE BLOCK -*---------------------------------------------------------------------------*/ - off_t offset; /* offset into file, for lseek() */ - off_t lseek(); /* lseek function */ - - blockNum = BfB0Flink(pDesc); - offset = blockNum * BfB0BlockSize(pDesc); - stat = lseek((int)pDesc->fd, offset, L_SET); - if (stat == ERROR) { - (void)fprintf(stderr, "bfAcquire: error on lseek for free block\n"); - return ERROR; - } - stat = read((int)pDesc->fd, (char *)pBuf, (int)BfB0BlockSize(pDesc)); - if (stat != BfB0BlockSize(pDesc)) { - (void)fprintf(stderr, "bfAcquire: error reading free block\n"); - return ERROR; - } - -/*---------------------------------------------------------------------------- -* move the free block's flink into block0 and decrement the free block count -*---------------------------------------------------------------------------*/ - BfB0Flink(pDesc) = pBuf->flink; - BfB0CurrentFree(pDesc)--; - } - - pBuf->flink = 0; - pBuf->firstByte = 0; - pBuf->lastByte = BF_BLOCK_DATA - 1; - - return blockNum; -} - -/*+/subr********************************************************************** -* NAME bfClose - close a block file -* -* DESCRIPTION -* Close a file. The actions taken are: -* o if pDesc->writeBlock > 0, write the block -* o if pDesc->pReadBuf != NULL, free the buffer -* o if pDesc->pWriteBuf != NULL, free the buffer -* o write block0 -* o if the file was opened O_RDWR, delete the write lock file -* o free the descriptor and store null in the caller's pointer -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o writing the block and freeing the buffers are somewhat controversial. -* If bfClose() free's the blocks, that may interfere with the caller's -* memory management. If the caller free's the buffers in an exit -* handler, that may interfere with bfClose() writing the block. There -* is also a potential conflict between exit handlers. The caller won't -* know how large to make the buffer until after bfOpen() has been -* called, and thus may be inclined to wait until after bfOpen() to -* register the block with the caller's exit handler, which might result -* in the caller's exit handler having precedence over one possibly -* established by bfOpen(); if this scenario were acted out, the buffer -* would be free'd before bfClose() got a chance to write it. -* -* SEE ALSO -* bfOpen() -* -*-*/ -int -bfClose(ppDesc) -BF_DESC **ppDesc; /* IO pointer to pointer to descriptor */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status */ - off_t offset; /* offset into file, for lseek() */ - off_t lseek(); /* lseek function */ - BF_DESC *pDesc; /* pointer to descripter */ - - assert(*ppDesc != NULL); - - pDesc = *ppDesc; - -/*---------------------------------------------------------------------------- -* first, see if a partial block needs to be written; write if needed. If -* read and/or write buffers are registered in descriptor, release them. -*---------------------------------------------------------------------------*/ - if (pDesc->writeBlock > 0) { - pDesc->pWriteBuf->lastByte = pDesc->pWrite - - (char *)pDesc->pWriteBuf; - stat = bfWrite(pDesc, pDesc->pWriteBuf, pDesc->writeBlock); - if (stat != OK) { - (void)fprintf(stderr, "bfClose: error writing partial block\n"); - retStat = ERROR; - } - } - if (pDesc->pWriteBuf != NULL) - free((char *)pDesc->pWriteBuf); - if (pDesc->pReadBuf != NULL) - free((char *)pDesc->pReadBuf); - -/*---------------------------------------------------------------------------- -* next, position file at beginning and write block0 -*---------------------------------------------------------------------------*/ - if (BfWriteable(pDesc)) { - offset = 0; - stat = lseek((int)pDesc->fd, offset, L_SET); - if (stat >= 0) { - stat = write((int)pDesc->fd, (char *)pDesc->pBlock0, - (int)BfB0BlockSize(pDesc)); - if (stat != BfB0BlockSize(pDesc)) { - perror("bfClose: error writing block0"); - retStat = ERROR; - } - } - else { - perror("bfClose: error on lseek"); - retStat = ERROR; - } - } - -/*---------------------------------------------------------------------------- -* then close the file -*---------------------------------------------------------------------------*/ - stat = close((int)pDesc->fd); - if (stat != 0) - retStat = ERROR; - -/*---------------------------------------------------------------------------- -* if the file wasn't read only, delete the lock file -*---------------------------------------------------------------------------*/ - if (BfWriteable(pDesc)) { - char lockName[GEN_FNAME_DIM+5];/* name of lock file for write acc.*/ - - (void) sprintf(lockName, "%s.lock", pDesc->name); - if ((stat = unlink(lockName)) != 0) { - perror("bfClose: error deleting lock file"); - retStat = ERROR; - } - } - -/*---------------------------------------------------------------------------- -* and, finally, free the memory for the descriptor and put NULL in the ptr -*---------------------------------------------------------------------------*/ - if (pDesc->pBlock0 != NULL) - bfFreeBlock0(pDesc->pBlock0); - if (pDesc != NULL) - bfFreeDesc(pDesc); - *ppDesc = NULL; - - return retStat; -} - -/*+/subr********************************************************************** -* NAME bfCreate - create and initialize a block file -* -* DESCRIPTION -* Creates and initializes a block file. If the file already exists, -* nothing is done. -* -* The file is created with the specified number of blocks, with all -* except the first one on the free block list. The specified type, -* flags, block size, and maximum file size will be installed in block 0. -* -* File mode is set to -rw-rw-r--. Owner and group for the file are -* set by the operating system. -* -* RETURNS -* pointer to descriptor, or -* NULL -* -* BUGS -* o there is a potential race when creating the file. This routine -* checks to see if the file already exists and balks if it does. But -* the file could be created between the check and the create done here. -* Under UNIX, O_CREAT | O_EXCL avoids the race, but VxWorks can't -* handle O_EXCL. -* o this routine creates a file by successive writes. Some file system -* protocols require creating an empty file of the desired size before -* any writing is done. -* -* EXAMPLE -* BF_DESC *pDesc; pointer to descriptor -* -* pDesc = bfCreate("myFile", BF_TYPE_RING, 12, 1000, BF_FLAG_GROW, 100); -* BfB0RingHead(pDesc) = 0; -* BfB0RingTail(pDesc) = 0; -* stat = bfClose(pDesc) -* -*-*/ -BF_DESC * -bfCreate(name, type, nBlocks, blockSize, fileFlags, maxBlocks) -char *name; /* I name of file */ -int type; /* I file type, one of the BF_TYPE_xxx */ -BF_BLKNUM nBlocks; /* I number of blocks; must be < BF_MAX_BLOCKS */ -unsigned blockSize; /* I size of blocks; must be >= BF_MIN_BLOCK_SIZE - and <= BF_MAX_BLOCK_SIZE */ -long fileFlags; /* I flags, one of the BF_FLAG_xxx */ -BF_BLKNUM maxBlocks; /* I size limit in blocks; must be <= BF_MAX_BLOCKS */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status */ - BF_DESC *pDesc; /* block file descriptor */ - int i; /* temp for loops */ - int fd; /* temp for file descriptor */ - - assert(type >= (int)BF_TYPE_UNDEF && type < (int)BF_TYPE_PAST); - assert(nBlocks >= 1 && nBlocks <= BF_MAX_BLOCKS); - assert(blockSize >= BF_MIN_BLOCK_SIZE && blockSize <= BF_MAX_BLOCK_SIZE); - assert(maxBlocks >= BF_MIN_BLOCKS && maxBlocks <= BF_MAX_BLOCKS); - - if ((fd = open(name, O_RDWR, 0664)) >= 0) { - (void)close(fd); - (void)fprintf(stderr, "bfCreate: can't create--file already exists\n"); - retStat = ERROR; - } - - if (retStat == OK) { - pDesc = bfOpen(name, O_RDWR | O_CREAT, type, (int)blockSize); - if (pDesc == NULL) { - perror("bfCreate: error creating file"); - retStat = ERROR; - } - } - - if (retStat == OK) { -/*---------------------------------------------------------------------------- -* set up block 0; special fields are the caller's responsibility -*---------------------------------------------------------------------------*/ - if (nBlocks > 1) { - BfB0Flink(pDesc) = 1; - BfB0CurrentSize(pDesc) = nBlocks; - BfB0CurrentFree(pDesc) = nBlocks - 1; - } - BfB0Flags(pDesc) = fileFlags; - BfB0MaxSize(pDesc) = maxBlocks; - -/*---------------------------------------------------------------------------- -* write out block 0. -* -* write out the free block list. Each block except the last has a flink -* to the next; the last block has a flink of 0. -* -* If an error occurs, the write process is aborted and an error message is -* printed. -*---------------------------------------------------------------------------*/ - stat = write((int)pDesc->fd, (char *)pDesc->pBlock0, (int)blockSize); - if (stat != blockSize) { - retStat = ERROR; - perror("bfCreate: error writing block0"); - } - if (retStat == OK && nBlocks > 1) { - BF_BLOCK *pBuf; - - pBuf = (BF_BLOCK *)malloc(blockSize); - if (pBuf == NULL) { - retStat = ERROR; - (void)fprintf(stderr, - "bfCreate: can't get memory for writing free blocks\n"); - } - else { - pBuf->firstByte = 0; - pBuf->lastByte = 0; - for (i=1; i++flink = (i != nBlocks ? i : 0); - stat = write((int)pDesc->fd, (char *)pBuf, (int)blockSize); - if (stat != blockSize) { - retStat = ERROR; - perror("bfCreate: error writing free block list"); - break; - } - free((char *)pBuf); - } - } - } - } - - if (retStat == OK) - return pDesc; - else - return NULL; -} - -/*+/subr********************************************************************** -* NAME bfDumpChar - dump, as text, contents of block from block file -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -int -bfDumpChar(pBfDesc, blockNum) -BF_DESC *pBfDesc; /* I pointer to descriptor */ -BF_BLKNUM blockNum; /* I block number */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status to caller */ - char *pBuf; /* buffer pointer */ - - if ((pBuf = (char *)malloc((unsigned)BfB0BlockSize(pBfDesc))) == NULL) { - (void)printf("bfDumpHex: can't malloc buffer\n"); - retStat = ERROR; - } - if (retStat == OK) { - if ((stat = bfRead(pBfDesc, (BF_BLOCK *)pBuf, blockNum)) != OK) { - (void)printf("bfDumpHex: error reading block\n"); - retStat = ERROR; - } - } - if (retStat == OK) { - char *pBuf1; - char c; - int i,j,last; - - (void)printf("block:%d flink:%d firstByte:%d lastByte:%d\n", blockNum, - ((BF_BLOCK *)pBuf)->flink, - ((BF_BLOCK *)pBuf)->firstByte, - ((BF_BLOCK *)pBuf)->lastByte); - pBuf1 = pBuf; - last = ((BF_BLOCK *)pBuf)->lastByte; - for (i=0; i<=last; ) { - (void)printf("%04x \"", i); - for (j=0; j<64; j++) { - (void)printf("%c", - (isascii(c=pBuf1[i++])&&isprint(c))?c:'.'); - if (i>last) - break; - } - (void)printf("\"\n"); - } - } - if (pBuf != NULL) - (void)free(pBuf); - - return retStat; -} - -/*+/subr********************************************************************** -* NAME bfDumpHex - dump, in hex, contents of block from block file -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -int -bfDumpHex(pBfDesc, blockNum) -BF_DESC *pBfDesc; /* I pointer to descriptor */ -BF_BLKNUM blockNum; /* I block number */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status to caller */ - char *pBuf; /* buffer pointer */ - - if ((pBuf = (char *)malloc((unsigned)BfB0BlockSize(pBfDesc))) == NULL) { - (void)printf("bfDumpHex: can't malloc buffer\n"); - retStat = ERROR; - } - if (retStat == OK) { - if ((stat = bfRead(pBfDesc, (BF_BLOCK *)pBuf, blockNum)) != OK) { - (void)printf("bfDumpHex: error reading block\n"); - retStat = ERROR; - } - } - if (retStat == OK) { - char *pBuf1; - int i,j,last; - - (void)printf("block:%d flink:%d firstByte:%d lastByte:%d\n", blockNum, - ((BF_BLOCK *)pBuf)->flink, - ((BF_BLOCK *)pBuf)->firstByte, - ((BF_BLOCK *)pBuf)->lastByte); - pBuf1 = pBuf; - last = ((BF_BLOCK *)pBuf)->lastByte; - for (i=0; i<=last; ) { - (void)printf("%04x", i); - for (j=0; j<8; j++) { - (void)printf(" "); - (void)printf("%02x", ((int)pBuf1[i++])&0xff); - (void)printf("%02x", ((int)pBuf1[i++])&0xff); - (void)printf("%02x", ((int)pBuf1[i++])&0xff); - (void)printf("%02x", ((int)pBuf1[i++])&0xff); - if (i>last) - break; - } - (void)printf("\n"); - } - } - if (pBuf != NULL) - (void)free(pBuf); - - return retStat; -} - -/*+/subr********************************************************************** -* NAME bfInfo - print information from block0 of block file -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -int -bfInfo(name) -char *name; /* I name of file */ -{ - int stat; /* status from calls */ - int retStat=OK; /* return status */ - BF_DESC *pDesc; /* block file descriptor */ - long blockSize; /* size of blocks in this file */ - off_t offset; /* offset into file, for lseek() */ - off_t lseek(); /* lseek function */ - int fd; - - if ((pDesc = bfMallocDesc()) == NULL) { - retStat = ERROR; - (void)fprintf(stderr, "bfInfo: can't get memory for bfDesc\n"); - } - if (retStat == OK) { - if ((pDesc->pBlock0 = bfMallocBlock0()) == NULL) { - retStat = ERROR; - (void)fprintf(stderr, "bfInfo: can't get memory for block0\n"); - } - } - - if (retStat == OK) { - fd = open(name, O_RDWR, 0664); - pDesc->fd = fd; - if (pDesc->fd < 0) { - perror("bfInfo: error opening file"); - retStat = ERROR; - } - } - -/*---------------------------------------------------------------------------- -* first, read only the first few bytes of the record, mostly to find out -* how big the blocks are. -*---------------------------------------------------------------------------*/ - if (retStat == OK) { - stat = read((int)pDesc->fd, (char *)pDesc->pBlock0, BF_MIN_BLOCK_SIZE); - if (stat != BF_MIN_BLOCK_SIZE) { - (void)fprintf(stderr, "bfInfo: error reading block0 preamble\n"); - retStat = ERROR; - } - else { - blockSize = BfB0BlockSize(pDesc); - (void)printf("BLOCK 0: blockSize is %d\n", blockSize); - } - } - - if (retStat == OK) { - offset = 0; - stat = lseek((int)pDesc->fd, offset, L_SET); - if (stat == ERROR) { - perror("bfInfo: error on lseek"); - retStat = ERROR; - } - if (retStat == OK) { - stat = read((int)pDesc->fd, (char *)pDesc->pBlock0, (int)blockSize); - if (stat != blockSize) { - (void)fprintf(stderr, "bfInfo: error reading block0\n"); - retStat = ERROR; - } - else { - (void)printf("BLOCK 0: type, flink, fByte, lByte %s %d %d %d\n", - BfTypeToText(BfB0FileType(pDesc)), - BfB0Flink(pDesc), BfB0FirstByte(pDesc), - BfB0LastByte(pDesc)); - (void)printf("maxSize, currSize, currFree %d %d %d\n", - BfB0MaxSize(pDesc), BfB0CurrentSize(pDesc), - BfB0CurrentFree(pDesc)); - (void)printf("free block list: "); - while (BfB0Flink(pDesc) != 0) { - (void)printf("%d ", BfB0Flink(pDesc)); - offset = BfB0Flink(pDesc) * blockSize; - stat = lseek((int)pDesc->fd, offset, L_SET); - if (stat == ERROR) { - perror("bfInfo: error on lseek"); - retStat = ERROR; - break; - } - else { - stat = read((int)pDesc->fd, (char *)pDesc->pBlock0, - (int)blockSize); - if (stat != blockSize) { - (void)fprintf(stderr, - "bfInfo: error reading block%d\n", - offset/blockSize); - break; - } - } - } - (void)printf("\n"); - } - } - } - - - if (pDesc->fd >= 0) - (void)close((int)pDesc->fd); - if (pDesc->pBlock0 != NULL) - bfFreeBlock0(pDesc->pBlock0); - if (pDesc != NULL) - bfFreeDesc(pDesc); - - return retStat; -} - -/*+/subr********************************************************************** -* NAME bfOpen - open or create a block file -* -* DESCRIPTION -* Open a block file. The actions taken are: -* o if the file type doesn't match the caller's type, return with NULL. -* (If the caller's type is BF_TYPE_UNDEF, no type check is made.) -* o if the file is being opened O_RDWR, a lock file is created. (If -* the lock file already exists, the open isn't done.) The lock file -* has the same 'name' as the file, but with the extension of .lock -* added. -* o a block of memory is obtained to hold a file descriptor and block0 -* o block0 is read -* o the file descriptor is set up -* -* This routine can also be used to create a block file, if the open -* mode is (O_RDWR & O_CREAT). In this case, the 'blkSize' argument -* must have a meaningful value. The actions taken are: -* o a lock file is created, as described above -* o the file is created, with flags of 0664 (rw-rw-r--) -* o a block of memory is obtained to hold a file descriptor and block0 -* o an 'empty' block0 is created, with no free blocks and 0 for flags -* o the file descriptor is set up -* -* RETURNS -* pointer to descriptor, or -* NULL -* -* BUGS -* o the flags used in creating the file with O_CREAT, and the flags -* used in creating the lock file, may be system dependent -* o this routine should probably grab a few of the free blocks and -* store them into the descriptor, which should have a place to 'store' -* them. -* o there is a potential race when locking against multiple writers. -* Another instance of bfOpen() could check for the existance of the -* lock file at the same time this one does, both could find the lock -* file non-existant, and both could 'create' it. -* -* SEE ALSO -* bfClose(), bfCreate() -* -* EXAMPLE -* BF_DESC *pDesc; pointer to file descriptor -* -* pDesc = bfOpen("myFile", O_RDONLY, BF_TYPE_UNDEF, 0); -* if (pDesc == NULL) { -* printf("error opening: myFile\n"); -* exit(1); -* } -* -*-*/ -BF_DESC * -bfOpen(name, mode, type, blkSize) -char *name; /* I name of file */ -int mode; /* I mode for open; O_RDWR or O_RDONLY. O_CREAT - can be specified in conjunction with O_RDWR */ -int type; /* I desired type of file; one of BF_TYPE_xxx */ -int blkSize; /* I blockSize for new file if mode includes - O_CREAT; ignored if mode doesn't include O_CREAT */ -{ - int stat; /* status from calls */ - BF_DESC *pDesc; /* block file descriptor */ - char buffer[BF_MIN_BLOCK_SIZE]; /* 'starter' buffer */ - long blockSize; /* size of blocks in this file */ - int fd; /* temp for fd from open */ - long flags; /* flags for block file descriptor */ - off_t offset; /* offset into file, for lseek() */ - off_t lseek(); /* lseek function */ - char lockName[GEN_FNAME_DIM+5];/* name of lock file for write acc.*/ - - assert(type >= (int)BF_TYPE_UNDEF && type < (int)BF_TYPE_PAST); - -/*---------------------------------------------------------------------------- -* first, open the file in the desired mode; if O_RDWR, set the flag -*---------------------------------------------------------------------------*/ - if (strlen(name) >= GEN_FNAME_DIM) { - (void)fprintf(stderr, "bfOpen: file name too long %s\n", name); - return NULL; - } - - if ((mode & O_CREAT) != 0) - assert(blkSize >= BF_MIN_BLOCK_SIZE && blkSize <= BF_MAX_BLOCK_SIZE); - - if (mode == O_RDONLY) - flags = 0; - else if (mode == O_RDWR || mode == (O_RDWR | O_CREAT) ) { - flags = BF_DESC_WRITE; - (void) sprintf(lockName, "%s.lock", name); - if ((fd = open(lockName, O_RDONLY)) >= 0) { - (void)close(fd); - (void)fprintf(stderr, - "bfOpen: %s locked against write access\n", name); - return NULL; - } - else { - if ((fd = open(lockName, O_CREAT, 0664)) < 0) { - perror("bfOpen: error creating write lock file"); - return NULL; - } - (void)close(fd); - } - } - else { - (void)fprintf(stderr, "bfOpen: illegal mode\n", name); - return NULL; - } - if ((fd = open(name, mode, 0664)) < 0) - goto errorExit; - -/*---------------------------------------------------------------------------- -* now, find out how big blocks are so we'll know how big to make the buffer -*---------------------------------------------------------------------------*/ - if ((mode & O_CREAT) != 0) - blockSize = blkSize; - else { -/*---------------------------------------------------------------------------- -* read block0 from file -*---------------------------------------------------------------------------*/ - stat = read(fd, buffer, BF_MIN_BLOCK_SIZE); - if (stat != BF_MIN_BLOCK_SIZE) { - perror("bfOpen: error reading block0 preamble\n"); - (void)close(fd); - goto errorExit; - } - blockSize = ((BF_BLOCK0 *)buffer)->fileInfo.blockSize; - } - -/*---------------------------------------------------------------------------- -* finally, malloc for the descriptor and for block0 -* set up the descriptor -*---------------------------------------------------------------------------*/ - if ((pDesc = bfMallocDesc()) == NULL) { - (void)fprintf(stderr, "bfOpen: can't get memory for descriptor\n"); - (void)close(fd); - goto errorExit; - } - else { - if ((pDesc->pBlock0 = bfMallocBlock0()) == NULL) { - (void)fprintf(stderr, "bfOpen: can't get memory for block0\n"); - bfFreeDesc(pDesc); - (void)close(fd); - goto errorExit; - } - } - pDesc->fd = fd; - pDesc->flags = flags; - pDesc->readCount = -10; - pDesc->readBlock = 0; - pDesc->pReadBuf = NULL; - pDesc->writeCount = -10; - pDesc->writeBlock = 0; - pDesc->pWriteBuf = NULL; - (void)strcpy(pDesc->name, name); /* length already checked above */ - -/*---------------------------------------------------------------------------- -* now, get block0 into memory. If we're using O_CREAT, then one must be -* created; otherwise, read it from the file. -*---------------------------------------------------------------------------*/ - if ((mode & O_CREAT) != 0) { -/*---------------------------------------------------------------------------- -* set up block 0; special fields are the caller's responsibility -*---------------------------------------------------------------------------*/ - BfB0Flink(pDesc) = 0; - BfB0FirstByte(pDesc) = BF_BLOCK_DATA; - BfB0LastByte(pDesc) = blockSize - 1; - BfB0FileType(pDesc) = type; - BfB0BlockSize(pDesc) = blockSize; - BfB0Flags(pDesc) = 0; - BfB0MaxSize(pDesc) = 1; - BfB0CurrentSize(pDesc) = 1; - BfB0CurrentFree(pDesc) = 0; - } - else { -/*---------------------------------------------------------------------------- -* read block0 from file -*---------------------------------------------------------------------------*/ - offset = 0; - stat = lseek((int)pDesc->fd, offset, L_SET); - if (stat == ERROR) { - perror("bfOpen: error on lseek"); - goto errorExit0; - } - stat = read((int)pDesc->fd, (char *)pDesc->pBlock0, (int)blockSize); - if (stat != blockSize) { - perror("bfOpen: error reading block0\n"); - goto errorExit0; - } - } - -/*---------------------------------------------------------------------------- -* do additional checks -*---------------------------------------------------------------------------*/ - if (type != (int)BF_TYPE_UNDEF && type != BfB0FileType(pDesc)) { - (void)fprintf(stderr, "bfOpen: file type mismatch for %s\n", name); - goto errorExit0; - } - - return pDesc; - -errorExit0: - (void)close(fd); - bfFreeBlock0(pDesc->pBlock0); - bfFreeDesc(pDesc); -errorExit: - if ((flags & BF_DESC_WRITE) != 0) { - if ((stat = unlink(lockName)) != 0) - perror("bfOpen: error deleting lock file"); - } - return NULL; -} - -/*+/subr********************************************************************** -* NAME bfRead - read a block from a block file -* -* DESCRIPTION -* Reads a block from the file into the caller's buffer. (None of the -* read-related fields in the descriptor are updated; these fields -* must be set by the caller, if desired.) -* -* For files of type BF_TYPE_RING, the macro BfRingGetc(pDesc) and the -* function bfRingFgets(pBuf, bufDim, pDesc) are available as more -* friendly tools for reading the data from blocks. -* -* RETURNS -* OK, or -* ERROR -* -* EXAMPLE -* BF_DESC *pDesc; file descriptor -* BF_BLOCK *pBuf; buffer pointer -* -* pDesc = bfOpen("dataFile", O_RDONLY, BF_TYPE_UNDEF); -* pBuf = (BF_BLOCK *)malloc(BfB0BlockSize(pDesc)); -* stat = bfRead(pDesc, pBuf, 1); -* printf("contents of block 1:\n"); -* for (i=BF_BLOCK_DATA; ilastByte; i++) -* putc(((char *)pBuf)[i]); -* stat = bfClose(pDesc); -* free((char *)pBuf); -* -*-*/ -int -bfRead(pDesc, pBuf, blockNum) -BF_DESC *pDesc; /* IO pointer to descriptor */ -BF_BLOCK *pBuf; /* IO buffer pointer */ -BF_BLKNUM blockNum; /* I block number */ -{ - int stat; /* status from calls */ - off_t offset; /* offset into file, for lseek() */ - off_t lseek(); /* lseek function */ - - assert(pDesc != NULL); - assert(pBuf != NULL); - assert(blockNum >= 0 && blockNum <= BfB0CurrentSize(pDesc)); - -/*---------------------------------------------------------------------------- -* read the block -*---------------------------------------------------------------------------*/ - offset = blockNum * BfB0BlockSize(pDesc); - stat = lseek((int)pDesc->fd, offset, L_SET); - if (stat == ERROR) { - (void)fprintf(stderr, "bfRead: error on lseek\n"); - return ERROR; - } - stat = read((int)pDesc->fd, (char *)pBuf, (int)BfB0BlockSize(pDesc)); - if (stat != BfB0BlockSize(pDesc)) { - (void)fprintf(stderr, "bfRead: error reading block\n"); - return ERROR; - } - - return OK; -} - -/*+/subr********************************************************************** -* NAME bfRelease - release a block to the free block list of a block file -* -* DESCRIPTION -* Adds the caller's block to the head of the free block list. -* -* The information in the caller's buffer is destroyed. -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o should provide a mechanism whereby no disk write is involved, or -* at least provide a way to delay the write. -* o should maintain an 'in memory' list of free blocks and replenish -* the list as necessary. This would avoid I/O delays on bfAcquire() -* calls. -* o multiple, simultaneous calls to this routine could result in various -* kinds of scrambling of the free block list. Callers must presently -* cooperate to prevent simultaneous calls. -* -* SEE ALSO -* bfAcquire() -* -*-*/ -int -bfRelease(pDesc, pBuf, blockNum) -BF_DESC *pDesc; /* IO pointer to descriptor */ -BF_BLOCK *pBuf; /* IO buffer pointer */ -BF_BLKNUM blockNum; /* I number of the block */ -{ - int stat; /* status from calls */ - off_t offset; /* offset into file, for lseek() */ - off_t lseek(); /* lseek function */ - - assert(pDesc != NULL); - assert(pBuf != NULL); - assert(blockNum >= 0 && blockNum <= BfB0CurrentSize(pDesc)); - - if (!BfWriteable(pDesc)) { - (void)fprintf(stderr, "bfRelease: file is O_RDONLY\n"); - return ERROR; - } - -/*---------------------------------------------------------------------------- -* link this block into the free block list, set firstByte and lastByte -* to 0, write the released block, and free the block's memory -*---------------------------------------------------------------------------*/ - pBuf->flink = BfB0Flink(pDesc); - pBuf->firstByte = 0; - pBuf->lastByte = 0; - offset = blockNum * BfB0BlockSize(pDesc); - stat = lseek((int)pDesc->fd, offset, L_SET); - if (stat == ERROR) { - perror("bfRelease: error on lseek"); - return ERROR; - } - stat = write((int)pDesc->fd, (char *)pBuf, (int)BfB0BlockSize(pDesc)); - if (stat != BfB0BlockSize(pDesc)) { - (void)fprintf(stderr, "bfRelease: error writing released block\n"); - return ERROR; - } - -/*---------------------------------------------------------------------------- -* adjust the free block information in block0 -*---------------------------------------------------------------------------*/ - BfB0CurrentFree(pDesc)++; - BfB0Flink(pDesc) = blockNum; - - return OK; -} - -/*+/subr********************************************************************** -* NAME bfWrite - write a block to a block file -* -* DESCRIPTION -* The block is written to the file, with the flink, firstByte, and -* lastByte fields written as set by the caller. -* -* For files of type BF_TYPE_RING, the macro BfRingPutc(c, pDesc) and the -* function bfRingFputs(pBuf, pDesc) are available as more -* friendly tools for writing the data to blocks. -* -* RETURNS -* OK, or -* ERROR -* -* EXAMPLE -* For an example of using bfWrite, see bfAcquire(). -* -*-*/ -int -bfWrite(pDesc, pBuf, blockNum) -BF_DESC *pDesc; /* IO pointer to descriptor */ -BF_BLOCK *pBuf; /* IO buffer pointer */ -BF_BLKNUM blockNum; /* I number of the block */ -{ - int stat; /* status from calls */ - off_t offset; /* offset into file, for lseek() */ - off_t lseek(); /* lseek function */ - - assert(pDesc != NULL); - assert(pBuf != NULL); - assert(blockNum >= 0 && blockNum <= BfB0CurrentSize(pDesc)); - - if (!BfWriteable(pDesc)) { - (void)fprintf(stderr, "bfWrite: file is O_RDONLY\n"); - return ERROR; - } - -/*---------------------------------------------------------------------------- -* write the block and, if keepFlag isn't set, free the buffer -*---------------------------------------------------------------------------*/ - offset = blockNum * BfB0BlockSize(pDesc); - while (1) { - stat = lseek((int)pDesc->fd, offset, L_SET); - if (stat == ERROR) { - perror("bfWrite: error on lseek"); - return ERROR; - } - stat = write((int)pDesc->fd, (char *)pBuf, (int)BfB0BlockSize(pDesc)); - if (stat == BfB0BlockSize(pDesc)) - return OK; -#ifdef vxWorks - perror("bfWrite: error writing block\n"); - return ERROR; -#else - if (errno != EINTR) { - perror("bfWrite: error writing block\n"); - return ERROR; - } -#endif - } -} diff --git a/src/libCom/bucketLib/bucketLib.c b/src/libCom/bucketLib/bucketLib.c deleted file mode 100644 index f53f7a80e..000000000 --- a/src/libCom/bucketLib/bucketLib.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Author: Jeffrey O. Hill - * hill@atdiv.lanl.gov - * (505) 665 1831 - * Date: 9-93 - * - * 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 091493 joh fixed overzealous parameter check - * .02 121693 joh added bucketFree() - * - * NOTES: - * .01 Storage for identifier must persist until an item is deleted - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "freeList.h" /* bucketLib uses freeListLib inside the DLL */ - -/* - * force these to be included before bucketLib.h - * includes them - */ -#include "errMdef.h" -#include "epicsTypes.h" -#include "bucketLib.h" - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ -#ifndef LOCAL -#define LOCAL static -#endif /* LOCAL */ -#ifndef max -#define max(A,B) ((A)>(B)?(A):(B)) -#endif /* max */ - -/* - * these data type dependent routines are - * provided in the bucketLib.c - */ -typedef BUCKETID bucketHash(BUCKET *pb, const void *pId); -typedef ITEM **bucketCompare(ITEM **ppi, const void *pId); - -LOCAL bucketCompare bucketUnsignedCompare; -LOCAL bucketCompare bucketPointerCompare; -LOCAL bucketCompare bucketStringCompare; -LOCAL bucketHash bucketUnsignedHash; -LOCAL bucketHash bucketPointerHash; -LOCAL bucketHash bucketStringHash; - -typedef struct { - bucketHash *pHash; - bucketCompare *pCompare; - buckTypeOfId type; -}bucketSET; - -LOCAL bucketSET BSET[] = { - {bucketUnsignedHash, bucketUnsignedCompare, bidtUnsigned}, - {bucketPointerHash, bucketPointerCompare, bidtPointer}, - {bucketStringHash, bucketStringCompare, bidtString} -}; - -LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, - const void *pId, const void *pApp); -LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId); -LOCAL void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId); - - - -/* - * bucket id bit width - */ -#define BUCKETID_BIT_WIDTH (sizeof(BUCKETID)*CHAR_BIT) - -/* - * Maximum bucket size - */ -#define BUCKET_MAX_WIDTH 12 - -#ifdef DEBUG -main() -{ - unsigned id1; - unsigned id2; - char *pValSave1; - char *pValSave2; - int s; - BUCKET *pb; - char *pVal; - unsigned i; - clock_t start, finish; - double duration; - const int LOOPS = 500000; - - pb = bucketCreate(8); - if(!pb){ - return -1; - } - - id1 = 0x1000a432; - pValSave1 = "fred"; - s = bucketAddItemUnsignedId(pb, &id1, pValSave1); - assert (s == S_bucket_success); - - pValSave2 = "jane"; - id2 = 0x0000a432; - s = bucketAddItemUnsignedId(pb, &id2, pValSave2); - assert (s == S_bucket_success); - - start = clock(); - for(i=0; itype) { - pItemId = (unsigned *) pi->pId; - if (id == *pItemId) { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketPointerCompare() - */ -LOCAL ITEM **bucketPointerCompare (ITEM **ppi, const void *pId) -{ - void *ptr; - void **pItemId; - ITEM *pi; - - ptr = * (void **) pId; - while ( (pi = *ppi) ) { - if (bidtPointer == pi->type ) { - pItemId = (void **) pi->pId; - if (ptr == *pItemId) { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketStringCompare () - */ -LOCAL ITEM **bucketStringCompare (ITEM **ppi, const void *pId) -{ - const char *pStr = pId; - ITEM *pi; - int status; - - while ( (pi = *ppi) ) { - if (bidtString == pi->type) { - status = strcmp (pStr, (char *)pi->pId); - if (status == '\0') { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketUnsignedHash () - */ -LOCAL BUCKETID bucketUnsignedHash (BUCKET *pb, const void *pId) -{ - const unsigned *pUId = pId; - unsigned src; - BUCKETID hashid; - - src = *pUId; - hashid = src; - src = src >> pb->hashIdNBits; - while (src) { - hashid = hashid ^ src; - src = src >> pb->hashIdNBits; - } - hashid = hashid & pb->hashIdMask; - - return hashid; -} - - -/* - * bucketPointerHash () - */ -LOCAL BUCKETID bucketPointerHash (BUCKET *pb, const void *pId) -{ - void * const *ppId = (void * const *) pId; - unsigned long src; - BUCKETID hashid; - - /* - * This makes the assumption that - * a pointer will fit inside of a long - * (this assumption may not port to all - * CPU architectures) - */ - src = (unsigned long) *ppId; - hashid = src; - src = src >> pb->hashIdNBits; - while(src){ - hashid = hashid ^ src; - src = src >> pb->hashIdNBits; - } - hashid = hashid & pb->hashIdMask; - - return hashid; -} - - -/* - * bucketStringHash () - */ -LOCAL BUCKETID bucketStringHash (BUCKET *pb, const void *pId) -{ - const char *pStr = pId; - BUCKETID hashid; - unsigned i; - - hashid = 0; - i = 1; - while(*pStr){ - hashid += *pStr * i; - pStr++; - i++; - } - - hashid = hashid % (pb->hashIdMask+1); - - return hashid; -} - - - -/* - * bucketCreate() - */ -epicsShareFunc BUCKET * epicsShareAPI bucketCreate (unsigned nHashTableEntries) -{ - BUCKETID mask; - unsigned nbits; - BUCKET *pb; - - /* - * no absurd sized buckets - */ - if (nHashTableEntries<=1) { - fprintf (stderr, "Tiny bucket create failed\n"); - return NULL; - } - - /* - * count the number of bits in the bucket id - */ - for (nbits=0; nbits=BUCKETID_BIT_WIDTH) { - fprintf ( - stderr, - "%s at %d: Requested index width=%d to large. max=%ld\n", - __FILE__, - __LINE__, - nbits, - (long)(BUCKETID_BIT_WIDTH-1)); - return NULL; - } - - pb = (BUCKET *) calloc(1, sizeof(*pb)); - if (!pb) { - return pb; - } - - pb->hashIdMask = mask; - pb->hashIdNBits = nbits; - freeListInitPvt(&pb->freeListPVT, sizeof(ITEM), 1024); - - pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable)); - if (!pb->pTable) { - freeListCleanup(pb->freeListPVT); - free (pb); - return NULL; - } - return pb; -} - - -/* - * bucketFree() - */ -epicsShareFunc int epicsShareAPI bucketFree (BUCKET *prb) -{ - /* - * deleting a bucket with entries in use - * will cause memory leaks and is not allowed - */ - assert (prb->nInUse==0); - - /* - * free the free list - */ - freeListCleanup(prb->freeListPVT); - free (prb->pTable); - free (prb); - - return S_bucket_success; -} - - -/* - * bucketAddItem() - */ -epicsShareFunc int epicsShareAPI - bucketAddItemUnsignedId(BUCKET *prb, const unsigned *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtUnsigned], pId, pApp); -} -epicsShareFunc int epicsShareAPI - bucketAddItemPointerId(BUCKET *prb, void * const *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtPointer], pId, pApp); -} -epicsShareFunc int epicsShareAPI - bucketAddItemStringId(BUCKET *prb, const char *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtString], pId, pApp); -} -LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, const void *pApp) -{ - BUCKETID hashid; - ITEM **ppi; - ITEM **ppiExists; - ITEM *pi; - - /* - * try to get it off the free list first. If - * that fails then malloc() - */ - pi = (ITEM *) freeListMalloc(prb->freeListPVT); - if (!pi) { - return S_bucket_noMemory; - } - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (prb, pId); - - pi->pApp = pApp; - pi->pId = pId; - pi->type = pBSET->type; - assert ((hashid & ~prb->hashIdMask) == 0); - ppi = &prb->pTable[hashid]; - /* - * Dont reuse a resource id ! - */ - ppiExists = (*pBSET->pCompare) (ppi, pId); - if (ppiExists) { - freeListFree(prb->freeListPVT,pi); - return S_bucket_idInUse; - } - pi->pItem = *ppi; - prb->pTable[hashid] = pi; - prb->nInUse++; - - return S_bucket_success; -} - - -/* - * bucketRemoveItem() - */ -epicsShareFunc int epicsShareAPI - bucketRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId) -{ - return bucketRemoveItem(prb, &BSET[bidtUnsigned], pId); -} -epicsShareFunc int epicsShareAPI - bucketRemoveItemPointerId (BUCKET *prb, void * const *pId) -{ - return bucketRemoveItem(prb, &BSET[bidtPointer], pId); -} -epicsShareFunc int epicsShareAPI - bucketRemoveItemStringId (BUCKET *prb, const char *pId) -{ - return bucketRemoveItem(prb, &BSET[bidtString], pId); -} -LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId) -{ - BUCKETID hashid; - ITEM **ppi; - ITEM *pi; - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (prb, pId); - - assert((hashid & ~prb->hashIdMask) == 0); - ppi = &prb->pTable[hashid]; - ppi = (*pBSET->pCompare) (ppi, pId); - if(!ppi){ - return S_bucket_uknId; - } - prb->nInUse--; - pi = *ppi; - *ppi = pi->pItem; - - /* - * stuff it on the free list - */ - freeListFree(prb->freeListPVT, pi); - - return S_bucket_success; -} - - - -/* - * bucketLookupItem() - */ -epicsShareFunc void * epicsShareAPI - bucketLookupItemUnsignedId (BUCKET *prb, const unsigned *pId) -{ - return bucketLookupItem(prb, &BSET[bidtUnsigned], pId); -} -epicsShareFunc void * epicsShareAPI - bucketLookupItemPointerId (BUCKET *prb, void * const *pId) -{ - return bucketLookupItem(prb, &BSET[bidtPointer], pId); -} -epicsShareFunc void * epicsShareAPI - bucketLookupItemStringId (BUCKET *prb, const char *pId) -{ - return bucketLookupItem(prb, &BSET[bidtString], pId); -} -LOCAL void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId) -{ - BUCKETID hashid; - ITEM **ppi; - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (pb, pId); - assert((hashid & ~pb->hashIdMask) == 0); - - /* - * at the bottom level just - * linear search for it. - */ - ppi = (*pBSET->pCompare) (&pb->pTable[hashid], pId); - if(ppi){ - return (void *) (*ppi)->pApp; - } - return NULL; -} - - - -/* - * bucketShow() - */ -epicsShareFunc int epicsShareAPI bucketShow(BUCKET *pb) -{ - ITEM **ppi; - ITEM *pi; - unsigned nElem; - double X; - double XX; - double mean; - double stdDev; - unsigned count; - unsigned maxEntries; - - printf( "Bucket entries in use = %d bytes in use = %ld\n", - pb->nInUse, - (long) (sizeof(*pb)+(pb->hashIdMask+1)* - sizeof(ITEM *)+pb->nInUse*sizeof(ITEM))); - - ppi = pb->pTable; - nElem = pb->hashIdMask+1; - X = 0.0; - XX = 0.0; - maxEntries = 0; - while (ppi < &pb->pTable[nElem]) { - pi = *ppi; - count = 0; - while (pi) { - count++; - pi = pi->pItem; - } - X += count; - XX += count*count; - maxEntries = max (count, maxEntries); - ppi++; - } - - mean = X/nElem; - stdDev = sqrt(XX/nElem - mean*mean); - printf( "Bucket entries/hash id - mean = %f std dev = %f max = %d\n", - mean, - stdDev, - maxEntries); - - return S_bucket_success; -} - - diff --git a/src/libCom/bucketLib/bucketLib.h b/src/libCom/bucketLib/bucketLib.h deleted file mode 100644 index 3606cc00d..000000000 --- a/src/libCom/bucketLib/bucketLib.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * $Id$ - * - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - * Date: 9-93 - * - * 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 091493 joh added nEntries to struct bucket - * .02 121693 joh added bucketFree() - * .03 052395 joh use std EPICS status - * $Log$ - * Revision 1.6 1998/02/20 21:45:10 evans - * Made a large number of changes to epicsShareThings in libCom routines - * to get imports and exports straight on WIN32. Not everything is fixed - * at this time. - * - * Revision 1.5 1997/05/01 19:57:13 jhill - * updated dll keywords - * - * Revision 1.4 1997/04/29 06:17:18 jhill - * use free lists - * - * Revision 1.3 1997/04/10 19:45:35 jhill - * API changes and include with not <> - * - * Revision 1.2 1996/06/19 19:44:53 jhill - * C++ support - * - * - * NOTES: - * .01 Storage for identifier must persist until an item is deleted - */ - -#ifndef INCbucketLibh -#define INCbucketLibh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "errMdef.h" -#include "epicsTypes.h" -#include "shareLib.h" - -typedef unsigned BUCKETID; - -typedef enum {bidtUnsigned, bidtPointer, bidtString} buckTypeOfId; - -typedef struct item{ - struct item *pItem; - READONLY void *pId; - READONLY void *pApp; - buckTypeOfId type; -}ITEM; - -typedef struct bucket{ - ITEM **pTable; - void *freeListPVT; - unsigned hashIdMask; - unsigned hashIdNBits; - unsigned nInUse; -}BUCKET; - -epicsShareFunc BUCKET * epicsShareAPI bucketCreate (unsigned nHashTableEntries); -epicsShareFunc int epicsShareAPI bucketFree (BUCKET *prb); -epicsShareFunc int epicsShareAPI bucketShow (BUCKET *pb); - -/* - * !! Identifier must exist (and remain constant) at the specified address until - * the item is deleted from the bucket !! - */ -epicsShareFunc int epicsShareAPI bucketAddItemUnsignedId (BUCKET *prb, - READONLY unsigned *pId, READONLY void *pApp); -epicsShareFunc int epicsShareAPI bucketAddItemPointerId (BUCKET *prb, - void * READONLY *pId, READONLY void *pApp); -epicsShareFunc int epicsShareAPI bucketAddItemStringId (BUCKET *prb, - READONLY char *pId, READONLY void *pApp); - -epicsShareFunc int epicsShareAPI bucketRemoveItemUnsignedId (BUCKET *prb, READONLY unsigned *pId); -epicsShareFunc int epicsShareAPI bucketRemoveItemPointerId (BUCKET *prb, void * READONLY *pId); -epicsShareFunc int epicsShareAPI bucketRemoveItemStringId (BUCKET *prb, READONLY char *pId); - -epicsShareFunc void * epicsShareAPI bucketLookupItemUnsignedId (BUCKET *prb, READONLY unsigned *pId); -epicsShareFunc void * epicsShareAPI bucketLookupItemPointerId (BUCKET *prb, void * READONLY *pId); -epicsShareFunc void * epicsShareAPI bucketLookupItemStringId (BUCKET *prb, READONLY char *pId); - -/* - * Status returned by bucketLib functions - */ -#define BUCKET_SUCCESS S_bucket_success -#define S_bucket_success 0 -#define S_bucket_noMemory (M_bucket | 1) /*Memory allocation failed*/ -#define S_bucket_idInUse (M_bucket | 2) /*Identifier already in use*/ -#define S_bucket_uknId (M_bucket | 3) /*Unknown identifier*/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCbucketLibh*/ - diff --git a/src/libCom/calc/calcPerform.c b/src/libCom/calc/calcPerform.c deleted file mode 100644 index a9a84db14..000000000 --- a/src/libCom/calc/calcPerform.c +++ /dev/null @@ -1,545 +0,0 @@ -/* $Id$ */ -/* - * Author: Julie Sander and Bob Dalesio - * Date: 07-27-87 - * - * 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 5-18-88 lrd modified modulo and power to avoid math library - * .02 5-19-88 lrd modified absolute value to avoid math library - * defined unary math lib routines as doubles - * removed include math.h - * stopped loading dinglers math routines (ml) - * wrote a random number generator to return a - * double between 0 and 1 - * .03 12-09-88 lrd fixed modulo not to perform zero division - * .04 12-12-88 lrd lock the record while processing - * .05 12-13-88 lrd made an alarm for math error - * .06 12-15-88 lrd Process the forward scan link - * .07 12-23-88 lrd Alarm on locked MAX_LOCKED times - * .08 01-11-89 lrd Add Right and Left Shift - * .09 02-01-89 lrd Add Trig functions - * .10 03-14-89 lrd fix true on C question mark operator - * .11 03-29-89 lrd make hardware errors MAJOR - * remove hw severity spec from database - * .12 04-06-89 lrd add monitor detection - * .13 05-03-89 lrd removed process mask from arg list - * .14 06-05-89 lrd check for negative square root - * .15 08-01-89 lrd full range of exponentiation using pow(x,y) - * .16 04-04-90 lrd fix post events for read and calc alarms - * fix neg base raised to integer exponent - * .17 04-06-90 lrd change conditional to check for 0 and non-zero - * instead of 0 and 1 (more 'C' like) - * .18 09-10-90 lrd add time stamps - * .19 11-26-90 lrd add bit not and relational not - fix RNDM - * .20 11-29-90 lrd conditionally process soft channels - * .21 12-14-90 lrd fixed post events for the variables - * .22 03-15-91 mrk moved code from calcRecord to here - * .23 08-01-91 rac don't use FETCH_G ... for V2 - * .24 02-20-92 rcz fixed for vxWorks build - * .25 02-24-92 jba add EXP and fix for EXPON when *pstacktop is 0 - * .26 02-28-92 jba added CEIL and FLOOR - * .27 03-06-92 jba added MAX and MIN binary functions - * .28 03-10-92 jba added multiple conditional expressions ? - * .29 04-01-92 jba allowed floating pt constants in expression - * .30 05-01-92 jba flt pt constant string replaced with double in postfix - * .31 08-21-92 jba ANSI c changes - * .32 12-11-92 mrk Removed include for stdioLib.h - * .33 08-04-93 mgb Removed V5/V4 and EPICS_V2 conditionals - * .34 05-11-94 jba Added support for CONST_PI, CONST_D2R, and CONST_R2D - * .34 08-18-94 jba Must skip over constant when looking for COND_END,COND_ELSE - * .35 10-07-94 mda change local random() to local_random() to - * avoid colliding with math library random() - - $Log% - - */ - -/* This module contains the code for processing the arithmetic - * expressions defined in calculation records. postfix must be called - * to convert a valid infix expression to postfix. CalcPerform - * calculates the postfix expression. - * - * Subroutines - * - * Public - * - * calcPerform perform the calculation - * args - * double *pargs address of arguments (12) - * double *presult address of result - * char *rpcl address of reverse polish buffer - * returns - * 0 fetched successfully - * -1 fetch failed - * - * Private routine for calcPerform - * local_random random number generator - * returns - * double value between 0.00 and 1.00 - */ - -#ifdef vxWorks -#include -#endif - -#include -#include -#include -#include - -#include "dbDefs.h" - -#define epicsExportSharedSymbols -#include "postfix.h" -#include "postfixPvt.h" - -static double local_random(); - -#define NOT_SET 0 -#define TRUE_COND 1 -#define FALSE_COND 2 - -#ifndef PI -#define PI 3.141592654 -#endif - -epicsShareFunc long epicsShareAPI - calcPerform(double *parg, double *presult, char *post) -{ - double *pstacktop; /* stack of values */ - double stack[80]; - short temp1; - short i; - double *top; - int itop; /* integer top value */ - int inexttop; /* ineteger next to top value */ - short cond_flag; /* conditional else flag */ - short got_if; - - /* initialize flag */ - cond_flag = NOT_SET; - pstacktop = &stack[0]; - -/* DEBUG print statements -for (i=0;i<184;i++){ -printf ("%d_",post[i]); -if ( post[i] == END_STACK ) break; -if ( post[i] == 71 ) i=i+8; -} -printf ("*FINISHED*\n"); -*/ - if(*post == BAD_EXPRESSION) return(-1); - - /* set post to postfix expression in calc structure */ - top = pstacktop; - - /* polish calculator loop */ - while (*post != END_STACK){ - - switch (*post){ - case FETCH_A: - ++pstacktop; - *pstacktop = parg[0]; - break; - - case FETCH_B: - ++pstacktop; - *pstacktop = parg[1]; - break; - - case FETCH_C: - ++pstacktop; - *pstacktop = parg[2]; - break; - - case FETCH_D: - ++pstacktop; - *pstacktop = parg[3]; - break; - - case FETCH_E: - ++pstacktop; - *pstacktop = parg[4]; - break; - - case FETCH_F: - ++pstacktop; - *pstacktop = parg[5]; - break; - - case FETCH_G: - ++pstacktop; - *pstacktop = parg[6]; - break; - - case FETCH_H: - ++pstacktop; - *pstacktop = parg[7]; - break; - - case FETCH_I: - ++pstacktop; - *pstacktop = parg[8]; - break; - - case FETCH_J: - ++pstacktop; - *pstacktop = parg[9]; - break; - - case FETCH_K: - ++pstacktop; - *pstacktop = parg[10]; - break; - - case FETCH_L: - ++pstacktop; - *pstacktop = parg[11]; - break; - - case CONST_PI: - ++pstacktop; - *pstacktop = PI; - break; - - case CONST_D2R: - ++pstacktop; - *pstacktop = PI/180.; - break; - - case CONST_R2D: - ++pstacktop; - *pstacktop = 180./PI; - break; - - case ADD: - --pstacktop; - *pstacktop = *pstacktop + *(pstacktop+1); - break; - - case SUB: - --pstacktop; - *pstacktop = *pstacktop - *(pstacktop+1); - break; - - case MULT: - --pstacktop; - *pstacktop = *pstacktop * *(pstacktop+1); - break; - - case DIV: - --pstacktop; - if (*(pstacktop+1) == 0) /* can't divide by zero */ - return(-1); - *pstacktop = *pstacktop / *(pstacktop+1); - break; - - case COND_IF: - /* if false condition then skip true expression */ - if (*pstacktop == 0.0) { - /* skip to matching COND_ELSE */ - for (got_if=1; got_if>0 && *(post+1) != END_STACK; ++post) { - if (*(post+1) == CONSTANT ) post+=8; - else if (*(post+1) == COND_IF ) got_if++; - else if (*(post+1) == COND_ELSE) got_if--; - } - } - /* remove condition from stack top */ - --pstacktop; - break; - - case COND_ELSE: - /* result, true condition is on stack so skip false condition */ - /* skip to matching COND_END */ - for (got_if=1; got_if>0 && *(post+1) != END_STACK; ++post) { - if (*(post+1) == CONSTANT ) post+=8; - else if (*(post+1) == COND_IF ) got_if++; - else if (*(post+1) == COND_END) got_if--; - } - break; - - case COND_END: - break; - - case ABS_VAL: - if (*pstacktop < 0) *pstacktop = -*pstacktop; - break; - - case UNARY_NEG: - *pstacktop = -1* (*pstacktop); - break; - - case SQU_RT: - if (*pstacktop < 0) return(-1); /* undefined */ - *pstacktop = sqrt(*pstacktop); - break; - - case EXP: - *pstacktop = exp(*pstacktop); - break; - - case LOG_10: - *pstacktop = log10(*pstacktop); - break; - - case LOG_E: - *pstacktop = log(*pstacktop); - break; - - case RANDOM: - ++pstacktop; - *pstacktop = local_random(); - break; - - case EXPON: - --pstacktop; - if (*pstacktop == 0) break; - if (*pstacktop < 0){ - temp1 = (int) *(pstacktop+1); - /* is exponent an integer */ - if ((*(pstacktop+1) - (double)temp1) != 0) return (-1); - *pstacktop = exp(*(pstacktop+1) * log(-*pstacktop)); - /* is value negative */ - if ((temp1 % 2) > 0) *pstacktop = -*pstacktop; - }else{ - *pstacktop = exp(*(pstacktop+1) * log(*pstacktop)); - } - break; - - case MODULO: - --pstacktop; - itop = (int)*pstacktop; - inexttop = (int)*(pstacktop+1); - if (inexttop == 0) - return(-1); - i = itop % inexttop; - *pstacktop = i; - break; - - case REL_OR: - --pstacktop; - *pstacktop = (*pstacktop || *(pstacktop+1)); - break; - - case REL_AND: - --pstacktop; - *pstacktop = (*pstacktop && *(pstacktop+1)); - break; - - case BIT_OR: - /* force double values into integers and or them */ - itop = (int)*pstacktop; - inexttop = (int)*(pstacktop-1); - --pstacktop; - *pstacktop = (inexttop | itop); - break; - - case BIT_AND: - /* force double values into integers and and them */ - itop = (int)*pstacktop; - inexttop = (int)*(pstacktop-1); - --pstacktop; - *pstacktop = (inexttop & itop); - break; - - case BIT_EXCL_OR: - /*force double values to integers to exclusive or them*/ - itop = (int)*pstacktop; - inexttop = (int)*(pstacktop-1); - --pstacktop; - *pstacktop = (inexttop ^ itop); - break; - - case GR_OR_EQ: - --pstacktop; - *pstacktop = *pstacktop >= *(pstacktop+1); - break; - - case GR_THAN: - --pstacktop; - *pstacktop = *pstacktop > *(pstacktop+1); - break; - - case LESS_OR_EQ: - --pstacktop; - *pstacktop = *pstacktop <= *(pstacktop+1); - break; - - case LESS_THAN: - --pstacktop; - *pstacktop = *pstacktop < *(pstacktop+1); - break; - - case NOT_EQ: - --pstacktop; - *pstacktop = *pstacktop != *(pstacktop+1); - break; - - case EQUAL: - --pstacktop; - *pstacktop = (*pstacktop == *(pstacktop+1)); - break; - - case RIGHT_SHIFT: - itop = (int)*pstacktop; - inexttop = (int)*(pstacktop-1); - --pstacktop; - *pstacktop = (inexttop >> itop); - break; - - case LEFT_SHIFT: - itop = (int)*pstacktop; - inexttop = (int)*(pstacktop-1); - --pstacktop; - *pstacktop = (inexttop << itop); - break; - - case MAX: - --pstacktop; - if (*pstacktop < *(pstacktop+1)) - *pstacktop = *(pstacktop+1); - break; - - case MIN: - --pstacktop; - if (*pstacktop > *(pstacktop+1)) - *pstacktop = *(pstacktop+1); - break; - - - case ACOS: - *pstacktop = acos(*pstacktop); - break; - - case ASIN: - *pstacktop = asin(*pstacktop); - break; - - case ATAN: - *pstacktop = atan(*pstacktop); - break; - - case ATAN2: - --pstacktop; - *pstacktop = atan2(*(pstacktop+1), *pstacktop); - break; - - case COS: - *pstacktop = cos(*pstacktop); - break; - - case SIN: - *pstacktop = sin(*pstacktop); - break; - - case TAN: - *pstacktop = tan(*pstacktop); - break; - - case COSH: - *pstacktop = cosh(*pstacktop); - break; - - case SINH: - *pstacktop = sinh(*pstacktop); - break; - - case TANH: - *pstacktop = tanh(*pstacktop); - break; - - case CEIL: - *pstacktop = ceil(*pstacktop); - break; - - case FLOOR: - *pstacktop = floor(*pstacktop); - break; - - case NINT: - *pstacktop = (double)(long)((*pstacktop) >= 0 ? (*pstacktop)+0.5 : (*pstacktop)-0.5); - break; - - case REL_NOT: - *pstacktop = ((*pstacktop)?0:1); - break; - - case BIT_NOT: - itop = (int)*pstacktop; - *pstacktop = ~itop; - break; - - case CONSTANT: - ++pstacktop; - ++post; - if ( post == NULL ) { - ++post; - printf("%.7s bad constant in expression\n",post); - break; - } - memcpy((void *)pstacktop,post,8); - post+=7; - break; - default: - printf("%d bad expression element\n",*post); - break; - } - - /* move ahead in postfix expression */ - ++post; - } - - /* if everything is peachy,the stack should end at its first position */ - if (++top == pstacktop) - *presult = *pstacktop; - else - return(-1); - return(0); -} - - -/* - * RAND - * - * generates a random number between 0 and 1 using the - * seed = (multy * seed) + addy Random Number Generator by Knuth - * SemiNumerical Algorithms - * Chapter 1 - * randy = seed / 65535.0 To normalize the number between 0 - 1 - */ -static unsigned short seed = 0xa3bf; -static unsigned short multy = 191 * 8 + 5; /* 191 % 8 == 5 */ -static unsigned short addy = 0x3141; -static double local_random() -{ - double randy; - - /* random number */ - seed = (seed * multy) + addy; - randy = (float) seed / 65535.0; - - /* between 0 - 1 */ - return(randy); -} diff --git a/src/libCom/calc/postfix.c b/src/libCom/calc/postfix.c deleted file mode 100644 index 846bb41a0..000000000 --- a/src/libCom/calc/postfix.c +++ /dev/null @@ -1,576 +0,0 @@ -/* $Id$ - * Subroutines used to convert an infix expression to a postfix expression - * - * Author: Bob Dalesio - * Date: 12-12-86 - * - * 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 01-11-89 lrd added right shift and left shift operations - * .02 01-13-89 lrd modified to load into IOCs - * .03 02-01-89 lrd added trigonometric functions - * .04 04-05-89 lrd fixed the order of some operations in the - * element table and added a warning label - * .05 11-26-90 lrd fix SINH, COSH, TANH - * .06 02-20-92 rcz fixed for vxWorks build - * .07 02-24-92 jba add EXP and fixed trailing blanks in expression - * .08 03-03-92 jba added MAX and MIN and comma(like close paren) - * .09 03-06-92 jba added multiple conditional expressions ? - * .10 04-01-92 jba allowed floating pt constants in expression - * .11 05-01-92 jba flt pt constant string replaced with double in postfix - * .12 08-21-92 jba ANSI c changes - * .13 08-21-92 jba initialized *ppostfix: needed when calc expr not defined - * .14 12-11-92 mrk Removed include for stdioLib.h - * .15 11-03-93 jba Added test for extra close paren at end of expression - * .16 01-24-94 jba Changed seperator test to catch invalid commas - * .17 05-11-94 jba Added support for CONST_PI, CONST_R2D, and CONST_D2R - * and conversion of infix expression to uppercase -*/ - -/* - * Subroutines - * - * Public - * - * postfix convert an algebraic expression to symbolic postfix - * args - * pinfix the algebraic expression - * ppostfix the symbolic postfix expression - * returns - * 0 successful - * -1 not successful - * Private routines for postfix - * - * find_element finds a symbolic element in the expression element tbl - * args - * pbuffer pointer to the infox expression element - * pelement pointer to the expression element table entry - * pno_bytes pointer to the size of this element - * returns - * TRUE element found - * FALSE element not found - * get_element finds the next expression element in the infix expr - * args - * pinfix pointer into the infix expression - * pelement pointer to the expression element table - * pno_bytes size of the element in the infix expression - * plink pointer to a resolved database reference (N/A) - * returns - * FINE found an expression element - * VARIABLE found a database reference - * UNKNOWN_ELEMENT unknown element found in the infix expression - * match_element finds an alpha element in the expression table - * args - * pbuffer pointer to an alpha expression element - * pelement pointer to the expression element table - * returns - * TRUE found the element in the element table - * FLASE expression element not found - */ - -#ifdef vxWorks -#include -#endif - -#include -#include -#include -#include - -#include "dbDefs.h" - -#define epicsExportSharedSymbols -#include "postfix.h" -#include "postfixPvt.h" - - -/* declarations for postfix */ -/* element types */ -#define OPERAND 0 -#define UNARY_OPERATOR 1 -#define BINARY_OPERATOR 2 -#define EXPR_TERM 3 -#define COND 4 -#define CLOSE_PAREN 5 -#define CONDITIONAL 6 -#define ELSE 7 -#define SEPERATOR 8 -#define TRASH 9 -#define FLOAT_PT_CONST 10 -#define MINUS_OPERATOR 11 - -#define UNARY_MINUS_I_S_P 7 -#define UNARY_MINUS_I_C_P 8 -#define UNARY_MINUS_CODE UNARY_NEG -#define BINARY_MINUS_I_S_P 4 -#define BINARY_MINUS_I_C_P 4 -#define BINARY_MINUS_CODE SUB - -/* parsing return values */ -#define FINE 0 -#define UNKNOWN_ELEMENT -1 -#define END -2 - -/* - * element table - * - * structure of an element - */ -struct expression_element{ - char element[10]; /* character representation of an element */ - char in_stack_pri; /* priority in translation stack */ - char in_coming_pri; /* priority when first checking */ - char type; /* element type */ - char code; /* postfix representation */ -}; - -/* - * NOTE: DO NOT CHANGE WITHOUT READING THIS NOTICE !!!!!!!!!!!!!!!!!!!! - * Because the routine that looks for a match in this table takes the first - * match it finds, elements whose designations are contained in other elements - * MUST come first in this list. (e.g. ABS will match A if A preceeds ABS and - * then try to find BS therefore ABS must be first in this list - */ -static struct expression_element elements[] = { -/* element i_s_p i_c_p type_element internal_rep */ -{"ABS", 7, 8, UNARY_OPERATOR, ABS_VAL}, /* absolute value */ -{"NOT", 7, 8, UNARY_OPERATOR, UNARY_NEG}, /* unary negate */ -{"-", 7, 8, MINUS_OPERATOR, UNARY_NEG}, /* unary negate (or binary op) */ -{"SQRT", 7, 8, UNARY_OPERATOR, SQU_RT}, /* square root */ -{"SQR", 7, 8, UNARY_OPERATOR, SQU_RT}, /* square root */ -{"EXP", 7, 8, UNARY_OPERATOR, EXP}, /* exponential function */ -{"LOGE", 7, 8, UNARY_OPERATOR, LOG_E}, /* log E */ -{"LN", 7, 8, UNARY_OPERATOR, LOG_E}, /* log E */ -{"LOG", 7, 8, UNARY_OPERATOR, LOG_10}, /* log 10 */ -{"ACOS", 7, 8, UNARY_OPERATOR, ACOS}, /* arc cosine */ -{"ASIN", 7, 8, UNARY_OPERATOR, ASIN}, /* arc sine */ -{"ATAN2", 7, 8, UNARY_OPERATOR, ATAN2}, /* arc tangent */ -{"ATAN", 7, 8, UNARY_OPERATOR, ATAN}, /* arc tangent */ -{"MAX", 7, 8, UNARY_OPERATOR, MAX}, /* maximum of 2 args */ -{"MIN", 7, 8, UNARY_OPERATOR, MIN}, /* minimum of 2 args */ -{"CEIL", 7, 8, UNARY_OPERATOR, CEIL}, /* smallest integer >= */ -{"FLOOR", 7, 8, UNARY_OPERATOR, FLOOR}, /* largest integer <= */ -{"NINT", 7, 8, UNARY_OPERATOR, NINT}, /* nearest integer */ -{"COSH", 7, 8, UNARY_OPERATOR, COSH}, /* hyperbolic cosine */ -{"COS", 7, 8, UNARY_OPERATOR, COS}, /* cosine */ -{"SINH", 7, 8, UNARY_OPERATOR, SINH}, /* hyperbolic sine */ -{"SIN", 7, 8, UNARY_OPERATOR, SIN}, /* sine */ -{"TANH", 7, 8, UNARY_OPERATOR, TANH}, /* hyperbolic tangent*/ -{"TAN", 7, 8, UNARY_OPERATOR, TAN}, /* tangent */ -{"!", 7, 8, UNARY_OPERATOR, REL_NOT}, /* not */ -{"~", 7, 8, UNARY_OPERATOR, BIT_NOT}, /* and */ -{"RNDM", 0, 0, OPERAND, RANDOM}, /* Random Number */ -{"OR", 1, 1, BINARY_OPERATOR,BIT_OR}, /* or */ -{"AND", 2, 2, BINARY_OPERATOR,BIT_AND}, /* and */ -{"XOR", 1, 1, BINARY_OPERATOR,BIT_EXCL_OR}, /* exclusive or */ -{"PI", 0, 0, OPERAND, CONST_PI}, /* pi */ -{"D2R", 0, 0, OPERAND, CONST_D2R}, /* pi/180 */ -{"R2D", 0, 0, OPERAND, CONST_R2D}, /* 180/pi */ -{"A", 0, 0, OPERAND, FETCH_A}, /* fetch var A */ -{"B", 0, 0, OPERAND, FETCH_B}, /* fetch var B */ -{"C", 0, 0, OPERAND, FETCH_C}, /* fetch var C */ -{"D", 0, 0, OPERAND, FETCH_D}, /* fetch var D */ -{"E", 0, 0, OPERAND, FETCH_E}, /* fetch var E */ -{"F", 0, 0, OPERAND, FETCH_F}, /* fetch var F */ -{"G", 0, 0, OPERAND, FETCH_G}, /* fetch var G */ -{"H", 0, 0, OPERAND, FETCH_H}, /* fetch var H */ -{"I", 0, 0, OPERAND, FETCH_I}, /* fetch var I */ -{"J", 0, 0, OPERAND, FETCH_J}, /* fetch var J */ -{"K", 0, 0, OPERAND, FETCH_K}, /* fetch var K */ -{"L", 0, 0, OPERAND, FETCH_L}, /* fetch var L */ -{"a", 0, 0, OPERAND, FETCH_A}, /* fetch var A */ -{"b", 0, 0, OPERAND, FETCH_B}, /* fetch var B */ -{"c", 0, 0, OPERAND, FETCH_C}, /* fetch var C */ -{"d", 0, 0, OPERAND, FETCH_D}, /* fetch var D */ -{"e", 0, 0, OPERAND, FETCH_E}, /* fetch var E */ -{"f", 0, 0, OPERAND, FETCH_F}, /* fetch var F */ -{"g", 0, 0, OPERAND, FETCH_G}, /* fetch var G */ -{"h", 0, 0, OPERAND, FETCH_H}, /* fetch var H */ -{"i", 0, 0, OPERAND, FETCH_I}, /* fetch var I */ -{"j", 0, 0, OPERAND, FETCH_J}, /* fetch var J */ -{"k", 0, 0, OPERAND, FETCH_K}, /* fetch var K */ -{"l", 0, 0, OPERAND, FETCH_L}, /* fetch var L */ -{"0", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"1", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"2", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"3", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"4", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"5", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"6", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"7", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"8", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"9", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{".", 0, 0, FLOAT_PT_CONST, CONSTANT}, /* flt pt constant */ -{"?", 0, 0, CONDITIONAL, COND_IF}, /* conditional */ -{":", 0, 0, CONDITIONAL, COND_ELSE}, /* else */ -{"(", 0, 8, UNARY_OPERATOR, PAREN}, /* open paren */ -{"^", 6, 6, BINARY_OPERATOR,EXPON}, /* exponentiation */ -{"**", 6, 6, BINARY_OPERATOR,EXPON}, /* exponentiation */ -{"+", 4, 4, BINARY_OPERATOR,ADD}, /* addition */ -#if 0 -{"-", 4, 4, BINARY_OPERATOR,SUB}, /* subtraction */ -#endif -{"*", 5, 5, BINARY_OPERATOR,MULT}, /* multiplication */ -{"/", 5, 5, BINARY_OPERATOR,DIV}, /* division */ -{"%", 5, 5, BINARY_OPERATOR,MODULO}, /* modulo */ -{",", 0, 0, SEPERATOR, COMMA}, /* comma */ -{")", 0, 0, CLOSE_PAREN, PAREN}, /* close paren */ -{"||", 1, 1, BINARY_OPERATOR,REL_OR}, /* or */ -{"|", 1, 1, BINARY_OPERATOR,BIT_OR}, /* or */ -{"&&", 2, 2, BINARY_OPERATOR,REL_AND}, /* and */ -{"&", 2, 2, BINARY_OPERATOR,BIT_AND}, /* and */ -{">>", 2, 2, BINARY_OPERATOR,RIGHT_SHIFT}, /* right shift */ -{">=", 3, 3, BINARY_OPERATOR,GR_OR_EQ}, /* greater or equal*/ -{">", 3, 3, BINARY_OPERATOR,GR_THAN}, /* greater than */ -{"<<", 2, 2, BINARY_OPERATOR,LEFT_SHIFT}, /* left shift */ -{"<=", 3, 3, BINARY_OPERATOR,LESS_OR_EQ},/* less or equal to*/ -{"<", 3, 3, BINARY_OPERATOR,LESS_THAN}, /* less than */ -{"#", 3, 3, BINARY_OPERATOR,NOT_EQ}, /* not equal */ -{"=", 3, 3, BINARY_OPERATOR,EQUAL}, /* equal */ -{""} -}; - -/* - * FIND_ELEMENT - * - * find the pointer to an entry in the element table - */ -static int find_element(pbuffer,pelement,pno_bytes) - register char *pbuffer; - register struct expression_element **pelement; - register short *pno_bytes; - { - - /* compare the string to each element in the element table */ - *pelement = &elements[0]; - while ((*pelement)->element[0] != NULL){ - if (strncmp(pbuffer,(*pelement)->element, - strlen((*pelement)->element)) == 0){ - *pno_bytes += strlen((*pelement)->element); - return(TRUE); - } - *pelement += 1; - } - return(FALSE); - } - -/* - * GET_ELEMENT - * - * get an expression element - */ -static int get_element(pinfix,pelement,pno_bytes) -register char *pinfix; -register struct expression_element **pelement; -register short *pno_bytes; -{ - - /* get the next expression element from the infix expression */ - if (*pinfix == NULL) return(END); - *pno_bytes = 0; - while (*pinfix == 0x20){ - *pno_bytes += 1; - pinfix++; - } - if (*pinfix == NULL) return(END); - if (!find_element(pinfix,pelement,pno_bytes)) - return(UNKNOWN_ELEMENT); - return(FINE); - - -} - -/* - * POSTFIX - * - * convert an infix expression to a postfix expression - */ -long epicsShareAPI postfix(char *pinfix,char *ppostfix,short *perror) -{ - short no_bytes; - register short operand_needed; - register short new_expression; - struct expression_element stack[80]; - struct expression_element *pelement; - register struct expression_element *pstacktop; - double constant; - register char *pposthold, *pc; - char in_stack_pri, in_coming_pri, code; - char *ppostfixStart = ppostfix; - - /* convert infix expression to upper case */ - for (pc=pinfix; *pc; pc++) { - if (islower(*pc)) *pc = toupper(*pc); - } - - /* place the expression elements into postfix */ - operand_needed = TRUE; - new_expression = TRUE; - *ppostfix = END_STACK; - *perror = 0; - if (* pinfix == 0 ) - return(0); - pstacktop = &stack[0]; - while (get_element(pinfix,&pelement,&no_bytes) != END){ - pinfix += no_bytes; - switch (pelement->type){ - - case OPERAND: - if (!operand_needed){ - *perror = 5; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operand to the expression */ - *ppostfix++ = pelement->code; - - operand_needed = FALSE; - new_expression = FALSE; - break; - - case FLOAT_PT_CONST: - if (!operand_needed){ - *perror = 5; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add constant to the expression */ - *ppostfix++ = pelement->code; - pposthold = ppostfix; - - pinfix-=no_bytes; - while (*pinfix == ' ') *ppostfix++ = *pinfix++; - while (TRUE) { - if ( ( *pinfix >= '0' && *pinfix <= '9' ) || *pinfix == '.' ) { - *ppostfix++ = *pinfix; - pinfix++; - } else if ( *pinfix == 'E' || *pinfix == 'e' ) { - *ppostfix++ = *pinfix; - pinfix++; - if (*pinfix == '+' || *pinfix == '-' ) { - *ppostfix++ = *pinfix; - pinfix++; - } - } else break; - } - *ppostfix++ = '\0'; - - ppostfix = pposthold; - if ( sscanf(ppostfix,"%lg",&constant) != 1) { - *ppostfix = '\0'; - } else { - memcpy(ppostfix,(void *)&constant,8); - } - ppostfix+=8; - - operand_needed = FALSE; - new_expression = FALSE; - break; - - case BINARY_OPERATOR: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators of higher or equal priority to */ - /* postfix notation */ - while ((pstacktop->in_stack_pri >= pelement->in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new operator to stack */ - pstacktop++; - *pstacktop = *pelement; - - operand_needed = TRUE; - break; - - case UNARY_OPERATOR: - if (!operand_needed){ - *perror = 5; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators of higher or equal priority to */ - /* postfix notation */ - while ((pstacktop->in_stack_pri >= pelement->in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new operator to stack */ - pstacktop++; - *pstacktop = *pelement; - - new_expression = FALSE; - break; - - case MINUS_OPERATOR: - if (operand_needed){ - /* then assume minus was intended as a unary operator */ - in_coming_pri = UNARY_MINUS_I_C_P; - in_stack_pri = UNARY_MINUS_I_S_P; - code = UNARY_MINUS_CODE; - new_expression = FALSE; - } - else { - /* then assume minus was intended as a binary operator */ - in_coming_pri = BINARY_MINUS_I_C_P; - in_stack_pri = BINARY_MINUS_I_S_P; - code = BINARY_MINUS_CODE; - operand_needed = TRUE; - } - - /* add operators of higher or equal priority to */ - /* postfix notation */ - while ((pstacktop->in_stack_pri >= in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new operator to stack */ - pstacktop++; - *pstacktop = *pelement; - pstacktop->in_stack_pri = in_stack_pri; - pstacktop->code = code; - - break; - - case SEPERATOR: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators to postfix until open paren */ - while (pstacktop->element[0] != '('){ - if (pstacktop == &stack[1] || - pstacktop == &stack[0]){ - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - operand_needed = TRUE; - break; - - case CLOSE_PAREN: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators to postfix until matching paren */ - while (pstacktop->element[0] != '('){ - if (pstacktop == &stack[1] || - pstacktop == &stack[0]){ - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - pstacktop--; /* remove ( from stack */ - break; - - case CONDITIONAL: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators of higher priority to */ - /* postfix notation */ - while ((pstacktop->in_stack_pri > pelement->in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new element to the postfix expression */ - *ppostfix++ = pelement->code; - - /* add : operator with COND_END code to stack */ - if (pelement->element[0] == ':'){ - pstacktop++; - *pstacktop = *pelement; - pstacktop->code = COND_END; - } - - operand_needed = TRUE; - break; - - case EXPR_TERM: - if (operand_needed && !new_expression){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add all operators on stack to postfix */ - while (pstacktop >= &stack[1]){ - if (pstacktop->element[0] == '('){ - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new element to the postfix expression */ - *ppostfix++ = pelement->code; - - operand_needed = TRUE; - new_expression = TRUE; - break; - - - default: - *perror = 8; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - } - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add all operators on stack to postfix */ - while (pstacktop >= &stack[1]){ - if (pstacktop->element[0] == '('){ - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - *ppostfix = END_STACK; - - return(0); -} diff --git a/src/libCom/calc/postfix.h b/src/libCom/calc/postfix.h deleted file mode 100644 index 0d11b5d9f..000000000 --- a/src/libCom/calc/postfix.h +++ /dev/null @@ -1,49 +0,0 @@ -/* postfix.h - * Author: Bob Dalesio - * Date: 9-21-88 - * - * 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 01-11-89 lrd add right and left shift - * .02 02-01-89 lrd add trig functions - * .03 02-17-92 jba add exp, CEIL, and FLOOR - * .04 03-03-92 jba added MAX, MIN, and comma - * .05 03-06-92 jba added multiple conditional expressions ? - * .06 04-02-92 jba added CONSTANT for floating pt constants in expression - * .07 05-11-94 jba added CONST_PI, CONST_D2R, and CONST_R2D - */ - -#ifndef INCpostfixh -#define INCpostfixh - -#include - -epicsShareFunc long epicsShareAPI - postfix (char *pinfix, char *ppostfix, short *perror); - -epicsShareFunc long epicsShareAPI - calcPerform(double *parg, double *presult, char *post); - - -#endif /* INCpostfixh */ diff --git a/src/libCom/calc/postfixPvt.h b/src/libCom/calc/postfixPvt.h deleted file mode 100644 index c014f37c4..000000000 --- a/src/libCom/calc/postfixPvt.h +++ /dev/null @@ -1,123 +0,0 @@ -/* postfixPvt.h - * Author: Bob Dalesio - * Date: 9-21-88 - * - * 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 01-11-89 lrd add right and left shift - * .02 02-01-89 lrd add trig functions - * .03 02-17-92 jba add exp, CEIL, and FLOOR - * .04 03-03-92 jba added MAX, MIN, and comma - * .05 03-06-92 jba added multiple conditional expressions ? - * .06 04-02-92 jba added CONSTANT for floating pt constants in expression - * .07 05-11-94 jba added CONST_PI, CONST_D2R, and CONST_R2D - */ - -#ifndef INCpostfixPvth -#define INCpostfixPvth - -#include - -/* defines for element table */ -#define BAD_EXPRESSION 0 -#define FETCH_A 1 -#define FETCH_B 2 -#define FETCH_C 3 -#define FETCH_D 4 -#define FETCH_E 5 -#define FETCH_F 6 -#define FETCH_G 7 -#define FETCH_H 8 -#define FETCH_I 9 -#define FETCH_J 10 -#define FETCH_K 11 -#define FETCH_L 12 -#define ACOS 13 -#define ASIN 14 -#define ATAN 15 -#define COS 16 -#define COSH 17 -#define SIN 18 -#define STORE_A 19 -#define STORE_B 20 -#define STORE_C 21 -#define STORE_D 22 -#define STORE_E 23 -#define STORE_F 24 -#define STORE_G 25 -#define STORE_H 26 -#define STORE_I 27 -#define STORE_J 28 -#define STORE_K 29 -#define STORE_L 30 -#define RIGHT_SHIFT 31 -#define LEFT_SHIFT 32 -#define SINH 33 -#define TAN 34 -#define TANH 35 -#define LOG_2 36 -#define COND_ELSE 37 -#define ABS_VAL 38 -#define UNARY_NEG 39 -#define SQU_RT 40 -#define EXP 41 -#define CEIL 42 -#define FLOOR 43 -#define LOG_10 44 -#define LOG_E 45 -#define RANDOM 46 -#define ADD 47 -#define SUB 48 -#define MULT 49 -#define DIV 50 -#define EXPON 51 -#define MODULO 52 -#define BIT_OR 53 -#define BIT_AND 54 -#define BIT_EXCL_OR 55 -#define GR_OR_EQ 56 -#define GR_THAN 57 -#define LESS_OR_EQ 58 -#define LESS_THAN 59 -#define NOT_EQ 60 -#define EQUAL 61 -#define REL_OR 62 -#define REL_AND 63 -#define REL_NOT 64 -#define BIT_NOT 65 -#define PAREN 66 -#define MAX 67 -#define MIN 68 -#define COMMA 69 -#define COND_IF 70 -#define COND_END 71 -#define CONSTANT 72 -#define CONST_PI 73 -#define CONST_D2R 74 -#define CONST_R2D 75 -#define NINT 76 -#define ATAN2 77 -#define END_STACK 127 - -#endif /* INCpostfixPvth */ diff --git a/src/libCom/calc/sCalcPerform.c b/src/libCom/calc/sCalcPerform.c deleted file mode 100644 index a43e92110..000000000 --- a/src/libCom/calc/sCalcPerform.c +++ /dev/null @@ -1,1458 +0,0 @@ -/* $Id$ */ -/* - * Author: Julie Sander and Bob Dalesio - * Date: 07-27-87 - * - * 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: - * ----------------- - * 03-18-98 tmm Essentially rewritten to support string operators - * 5/21/98 fixed ?: operator - */ - -/* This module contains the code for processing the arithmetic - * expressions defined in calculation records. postfix must be called - * to convert a valid infix expression to postfix. sCalcPerform - * calculates the postfix expression. - * - * Subroutines - * - * Public - * - * sCalcPerform perform the calculation - * args - * double *parg address of arguments - * int numArgs number of arguments in pargs array - * double *psarg address of string arguments - * int numSArgs number of string arguments in psargs array - * double *presult address of double result - * char *psresult address of string-result buffer - * int lenSresult length of string-result buffer - * char *rpcl address of postfix buffer - * returns - * 0 fetched successfully - * -1 fetch failed - * - * Private routine for sCalcPerform - * local_random random number generator - * returns - * double value between 0.00 and 1.00 - */ - -#ifdef vxWorks -#include -#endif - -#include -#include -#include -#include - -#include "dbDefs.h" -#define epicsExportSharedSymbols -#include "cvtFast.h" -#include "sCalcPostfix.h" -#include "sCalcPostfixPvt.h" - -static double local_random(); - -static int isnan(double d) -{ - union { long l[2]; double d; } u; - u.d = d; - if ((u.l[0] & 0x7ff00000) != 0x7ff00000) return(0); - if (u.l[1] || (u.l[0] & 0x000fffff)) return(1); - return(0); -} -#define myNINT(a) ((int)((a) >= 0 ? (a)+0.5 : (a)-0.5)) -#ifndef PI -#define PI 3.141592654 -#endif -#define MAX(a,b) (a)>(b)?(a):(b) -#define MIN(a,b) (a)<(b)?(a):(b) - - -#define STACKSIZE 30 /* <-------------------------<<<<<<< */ - -struct stackElement { - double d; - char *s; -}; - -#define OVERRIDESTDCALC 0 -#define DEBUG 0 -volatile int sCalcPerformDebug = 0; -#if DEBUG -int sCalcStackHW = 0; -int sCalcStackLW = 0; -#define INC(ps) {if ((int)(++(ps)-top) > sCalcStackHW) sCalcStackHW = (int)((ps)-top);} -#define DEC(ps) {if ((int)(--(ps)-top) < sCalcStackLW) sCalcStackLW = (int)((ps)-top);} -#else -#define INC(ps) ++ps -#define DEC(ps) ps-- -#endif - - -#define isDouble(ps) ((ps)->s==NULL) -#define isString(ps) ((ps)->s) - -#define cleanStringElement(ps) {free((ps)->s); (ps)->s=NULL;} - -static void cleanStackElement(struct stackElement *ps) -{ - if (isString(ps)) { - free(ps->s); - ps->s = NULL; - } -} - -static void cleanup(struct stackElement *ps, struct stackElement *pe) -{ - for (; ps <= pe; ps++) { - if (isString(ps)) { - free(ps->s); - ps->s = NULL; - } - } -} - -#define toDouble(ps) {if (isString(ps)) to_double(ps);} - -/* convert stack element to double */ -static void to_double(struct stackElement *ps) -{ - ps->d = atof(ps->s); - free(ps->s); - ps->s = NULL; -} - -#define toString(ps) {if (isDouble(ps)) to_string(ps);} - -/* convert stack element to string */ -static void to_string(struct stackElement *ps) -{ - ps->s = calloc(20, 1); - /* any precision greater than 8 results in (slow) sprintf call */ - if (isnan(ps->d)) - strcpy(ps->s,"NaN"); - else - (void)cvtDoubleToString(ps->d, ps->s, 8); -} - -static char *findConversionIndicator(char *s) -{ - char *cc=NULL, *s1, *retval; - - while (s && *s) { - if ((s1 = strstr(s, "%%")) != NULL) { - /* not a conversion/assignment indicator; skip over */ - s = s1+2; continue; - } - if ((s = strchr(s, (int)'%')) == NULL) { - return(NULL); - } - if ((cc = strpbrk(s, "pwn$c[deEfgGiousxX")) == NULL) { - return(NULL); - } - /* - * (*cc) is a conversion character; look for suppressed assignment - * ('*' occurring after '%' and before conversion character) - */ - s1 = strchr(s, (int)'*'); - if (s1 && (s1 < cc)) { - /* suppressed assignment; skip past conversion character */ - s = cc+1; - if (*cc == '[') { - /* skip character set ([..], []..], or [^]..]) */ - if (cc[1] == ']') { - s = &(cc[2]); - } else if ((cc[1] == '^') && (cc[2] == ']')) { - s = &(cc[3]); - } - s = strchr(s, (int)']'); - if (s == NULL) { - /* bad character-set syntax */ - return(NULL); - } - s++; /* skip past ']' */ - } - /* keep looking for conversion/assignment character */ - - continue; - } else { - /* (*cc) is a conversion/assignment character */ - break; - } - } - if (cc == NULL) return(NULL); - retval = cc; - /* - * (*cc) is a conversion/assignment indicator. Make sure there - * aren't any more in the format string. - */ - s = cc+1; - while (s && *s) { - if ((s1 = strstr(s, "%%")) != NULL) { - /* not a conversion/assignment indicator; skip over */ - s = s1+2; continue; - } - if ((s = strchr(s, (int)'%')) == NULL) return(retval); - if ((cc = strpbrk(s, "pwn$c[deEfgGiousxX")) == NULL) return(retval); - /* - * (*cc) is a conversion character; look for suppressed assignment - * ('*' occurring after '%' and before conversion character) - */ - s1 = strchr(s, (int)'*'); - if (s1 && (s1 < cc)) { - /* suppressed assignment; skip past conversion character */ - s = cc+1; - if (*cc == '[') { - /* skip character set ([..], []..], or [^]..]) */ - if (cc[1] == ']') { - s = &(cc[2]); - } else if ((cc[1] == '^') && (cc[2] == ']')) { - s = &(cc[3]); - } - s = strchr(s, (int)']'); - if (s == NULL) return(NULL); /* bad character-set syntax */ - s++; /* skip past ']' */ - } - continue; - } else { - /* (*cc) assignment is not suppressed */ - return(NULL); - } - } - return(retval); -} - -#if OVERRIDESTDCALC -/* Override standard EPICS expression evaluator (if we're loaded after it) */ -epicsShareFunc long epicsShareAPI - calcPerform(double *parg, double *presult, char *post) -{ - return(sCalcPerform(parg, 12, NULL, 0, presult, NULL, 0, post)); -} -#endif - -epicsShareFunc long epicsShareAPI - sCalcPerform(double *parg, int numArgs, char **psarg, int numSArgs, double *presult, char *psresult, int lenSresult, char *post) -{ - struct stackElement stack[STACKSIZE], *top; - register struct stackElement *ps, *ps1, *ps2; - char *s2, tmpstr[1000]; - register char *s, *s1; - register int i, j, k; - long l; - unsigned short ui; - unsigned long ul; - float f; - double d; - register double *topd, *pd; - short h, got_if; - -#if DEBUG - if (sCalcPerformDebug>=10) { - int more; - printf("sCalcPerform: postfix:"); - for (s=post, more=1; more;) { - printf("%2d ", *s); - switch (*s) { - case END_STACK: - more = 0; - break; - case LITERAL: - printf("(0x"); - for (i=0, s++; i<8; i++, s++) printf("%2x ", (unsigned int)(unsigned char)*s); - printf(") "); - break; - case SLITERAL: - s++; /* point past code */ - printf("'"); - while (*s) printf("%c", *s++); - printf("' "); - s++; - break; - case FETCH: - s++; /* point past code */ - printf("@%d ", *s++); - break; - case SFETCH: - s++; /* point past code */ - printf("$%d ", *s++); - break; - default: - if (*s == BAD_EXPRESSION) more=0; - s++; - break; - } - } - printf("\n"); - } -#endif - - /* Make sure postfix expression exists and is nontrivial */ - /* if ((*post == END_STACK) || (*post == BAD_EXPRESSION)) return(-1);*/ - if (*post == BAD_EXPRESSION) return(-1); - - - if (*post++ != USES_STRING) { - - topd = pd = (double *)&stack[10]; - pd--; - - /* No string expressions */ - while (*post != END_STACK) { - - switch (*post){ - - case FETCH: - ++pd; - ++post; - *pd = (*post < numArgs) ? parg[*post] : 0; - break; - - case STORE: - /* not implemented */ - return(-1); - - case CONST_PI: - ++pd; - *pd = PI; - break; - - case CONST_D2R: - ++pd; - *pd = PI/180.; - break; - - case CONST_R2D: - ++pd; - *pd = 180./PI; - break; - - case CONST_S2R: - ++pd; - *pd = PI/(180.*3600); - break; - - case CONST_R2S: - ++pd; - *pd = (180.*3600)/PI; - break; - - case ADD: - --pd; - *pd = *pd + pd[1]; - break; - - case SUB: - --pd; - *pd = *pd - pd[1]; - break; - - case MULT: - --pd; - *pd = *pd * pd[1]; - break; - - case DIV: - --pd; - if (pd[1] == 0) /* can't divide by zero */ - return(-1); - *pd = *pd / pd[1]; - break; - - case COND_IF: - /* if false condition then skip true expression */ - if (*pd == 0.0) { - /* skip to matching COND_ELSE */ - for (got_if=1; got_if>0 && *(post+1) != END_STACK; ++post) { - switch(post[1]) { - case LITERAL: post+=8; break; - case COND_IF: got_if++; break; - case COND_ELSE: got_if--; break; - case FETCH: case SFETCH: post++; break; - } - } - } - /* remove condition from stack top */ - --pd; - break; - - case COND_ELSE: - /* result, true condition is on stack so skip false condition */ - /* skip to matching COND_END */ - for (got_if=1; got_if>0 && *(post+1) != END_STACK; ++post) { - switch(post[1]) { - case LITERAL: post+=8; break; - case COND_IF: got_if++; break; - case COND_END: got_if--; break; - case FETCH: post++; break; - } - } - break; - - case COND_END: - break; - - case ABS_VAL: - if (*pd < 0 ) *pd *= -1; - break; - - case UNARY_NEG: - *pd *= -1; - break; - - case SQU_RT: - /* check for neg number */ - if (*pd < 0) return(-1); - *pd = sqrt(*pd); - break; - - case EXP: - *pd = exp(*pd); - break; - - case LOG_10: - /* check for neg number */ - if (*pd < 0) return(-1); - *pd = log10(*pd); - break; - - case LOG_E: - /* check for neg number */ - if (*pd < 0) return(-1); - *pd = log(*pd); - break; - - case RANDOM: - ++pd; - *pd = local_random(); - break; - - case EXPON: - --pd; - if (*pd == 0) break; - if (*pd < 0) { - i = (int) pd[1]; - /* is exponent an integer? */ - if ((pd[1] - (double)i) != 0) return (-1); - *pd = exp(pd[1] * log(-(*pd))); - /* is value negative */ - if ((i % 2) > 0) *pd = -(*pd); - } else { - *pd = exp(pd[1] * log(*pd)); - } - break; - - case MODULO: - --pd; - if ((int)(pd[1]) == 0) - return(-1); - *pd = (double)((int)(*pd) % (int)(pd[1])); - break; - - case REL_OR: - --pd; - *pd = *pd || pd[1]; - break; - - case REL_AND: - --pd; - *pd = *pd && pd[1]; - break; - - case BIT_OR: - /* force double values into integers and or them */ - --pd; - *pd = (int)(pd[1]) | (int)(*pd); - break; - - case BIT_AND: - /* force double values into integers and and them */ - --pd; - *pd = (int)(pd[1]) & (int)(*pd); - break; - - case BIT_EXCL_OR: - /* force double values to integers to exclusive or them */ - --pd; - *pd = (int)(pd[1]) ^ (int)(*pd); - break; - - case GR_OR_EQ: - --pd; - *pd = *pd >= pd[1]; - break; - - case GR_THAN: - --pd; - *pd = *pd > pd[1]; - break; - - case LESS_OR_EQ: - --pd; - *pd = *pd <= pd[1]; - break; - - case LESS_THAN: - --pd; - *pd = *pd < pd[1]; - break; - - case NOT_EQ: - --pd; - *pd = *pd != pd[1]; - break; - - case EQUAL: - --pd; - *pd = *pd == pd[1]; - break; - - case RIGHT_SHIFT: - --pd; - *pd = (int)(*pd) >> (int)(pd[1]); - break; - - case LEFT_SHIFT: - --pd; - *pd = (int)(*pd) << (int)(pd[1]); - break; - - case MAX_VAL: - --pd; - if (*pd < pd[1]) *pd = pd[1]; - break; - - case MIN_VAL: - --pd; - if (*pd > pd[1]) *pd = pd[1]; - break; - - case ACOS: - *pd = acos(*pd); - break; - - case ASIN: - *pd = asin(*pd); - break; - - case ATAN: - *pd = atan(*pd); - break; - - case ATAN2: - --pd; - *pd = atan2(pd[1], *pd); - break; - - case COS: - *pd = cos(*pd); - break; - - case SIN: - *pd = sin(*pd); - break; - - case TAN: - *pd = tan(*pd); - break; - - case COSH: - *pd = cosh(*pd); - break; - - case SINH: - *pd = sinh(*pd); - break; - - case TANH: - *pd = tanh(*pd); - break; - - case CEIL: - *pd = ceil(*pd); - break; - - case FLOOR: - *pd = floor(*pd); - break; - - case NINT: - d = *pd; - *pd = (double)(long)(d >= 0 ? d+0.5 : d-0.5); - break; - - case REL_NOT: - *pd = (*pd ? 0 : 1); - break; - - case BIT_NOT: - *pd = ~(int)(*pd); - break; - - case LITERAL: - ++pd; - ++post; - if (post == NULL) { - ++post; - printf("%.7s bad constant in expression\n",post); - *pd = 0.; - break; - } - memcpy((void *)&(*pd),post,8); - post += 7; - break; - - default: - break; - } - - /* move ahead in postfix expression */ - ++post; - } - - /* if everything is peachy,the stack should end at its first position */ - if (pd != topd) return(-1); -#if DEBUG > 1 -/* check out floating rep of numbers like NaN, Inf */ -{ -union { unsigned char s[8]; double d; } u; -u.d = *pd; -printf("sCalcPerform: result: %g = (0x", *pd); -for (i=0; i<8; i++) printf("%2x ", u.s[i]); -printf(") \n"); -} -#endif - *presult = *pd; - if (psresult && (lenSresult > 15)) { - if (isnan(*pd)) - strcpy(psresult,"NaN"); - else - (void)cvtDoubleToString(*pd, psresult, 8); - } - } else { - - /*** expression requires string operations ***/ - - top = ps = &stack[10]; - ps--; /* Expression handler assumes ps is pointing to a filled element */ - - /* string expressions and values handled */ - while (*post != END_STACK) { - - switch (*post){ - - case FETCH: - INC(ps); - ++post; - ps->s = NULL; - ps->d = (*post < numArgs) ? parg[*post] : 0; - break; - - case SFETCH: - INC(ps); - ++post; - if (*post < numSArgs) { - /* fetch from string variable */ - ps->s = calloc(strlen(psarg[*post])+1, 1); - strcpy(ps->s, psarg[*post]); - } else { - /* fetch from variable that caller did not supply */ - ps->s = calloc(1, 1); - *(ps->s) = 0; - } - break; - - case STORE: - /* not implemented */ - cleanup(top, ps); - return(-1); - - case CONST_PI: - INC(ps); - ps->s = NULL; - ps->d = PI; - break; - - case CONST_D2R: - INC(ps); - ps->s = NULL; - ps->d = PI/180.; - break; - - case CONST_R2D: - INC(ps); - ps->s = NULL; - ps->d = 180./PI; - break; - - case CONST_S2R: - INC(ps); - ps->s = NULL; - ps->d = PI/(180.*3600); - break; - - case CONST_R2S: - INC(ps); - ps->s = NULL; - ps->d = (180.*3600)/PI; - break; - - case ADD: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - ps->d = ps->d + ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - ps->d = ps->d + ps1->d; - } else { - /* concatenate two strings */ - s = ps->s; - ps->s = calloc(strlen(ps->s) + strlen(ps1->s) + 1, 1); - strcpy(ps->s, s); - strcat(ps->s, ps1->s); - free(s); - cleanStringElement(ps1); - } - break; - - case SUB: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - ps->d = ps->d - ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - ps->d = ps->d - ps1->d; - } else { - /* subtract ps1->s from ps->s */ - s = strstr(ps->s, ps1->s); - s1 = ps->s; - s2 = ps1->s; - if (s && (strlen(s2) <= (strlen(s1) - (s - s1)))) { - for (s1=s+strlen(s2); *s1; s++, s1++) *s = *s1; - *s = '\0'; - } - cleanStringElement(ps1); - } - break; - - case MULT: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = ps->d * ps1->d; - break; - - case DIV: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - if (ps1->d == 0) /* can't divide by zero */ - return(-1); - ps->d = ps->d / ps1->d; - break; - - case COND_IF: - /* if false condition then skip true expression */ - toDouble(ps); - if (ps->d == 0.0) { - /* skip to matching COND_ELSE */ - for (got_if=1; got_if>0 && *(post+1) != END_STACK; ++post) { - switch(post[1]) { - case LITERAL: post+=8; break; - case SLITERAL: post++; while (post[1]) post++; break; - case COND_IF: got_if++; break; - case COND_ELSE: got_if--; break; - case FETCH: case SFETCH: post++; break; - } - } - } - /* remove condition from stack top */ - DEC(ps); - break; - - case COND_ELSE: - /* result, true condition is on stack so skip false condition */ - /* skip to matching COND_END */ - for (got_if=1; got_if>0 && *(post+1) != END_STACK; ++post) { - switch(post[1]) { - case LITERAL: post+=8; break; - case SLITERAL: post++; while (post[1]) post++; break; - case COND_IF: got_if++; break; - case COND_END: got_if--; break; - case FETCH: case SFETCH: post++; break; - } - } - break; - - case COND_END: - break; - - case ABS_VAL: - toDouble(ps); - if (ps->d < 0 ) ps->d *= -1; - break; - - case UNARY_NEG: - toDouble(ps); - ps->d *= -1; - break; - - case SQU_RT: - toDouble(ps); - /* check for neg number */ - if (ps->d < 0) {cleanup(top, ps); return(-1);} - ps->d = sqrt(ps->d); - break; - - case EXP: - toDouble(ps); - ps->d = exp(ps->d); - break; - - case LOG_10: - toDouble(ps); - /* check for neg number */ - if (ps->d < 0) {cleanup(top, ps); return(-1);} - ps->d = log10(ps->d); - break; - - case LOG_E: - toDouble(ps); - /* check for neg number */ - if (ps->d < 0) {cleanup(top, ps); return(-1);} - ps->d = log(ps->d); - break; - - case RANDOM: - INC(ps); - ps->d = local_random(); - ps->s = NULL; - break; - - case EXPON: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - if (ps->d == 0) break; - if (ps->d < 0) { - i = (int) ps1->d; - /* is exponent an integer? */ - if ((ps1->d - (double)i) != 0) return (-1); - ps->d = exp(ps1->d * log(-(ps->d))); - /* is value negative */ - if ((i % 2) > 0) ps->d = -ps->d; - } else { - ps->d = exp(ps1->d * log(ps->d)); - } - break; - - case MODULO: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - if ((int)ps1->d == 0) - return(-1); - ps->d = (double)((int)ps->d % (int)ps1->d); - break; - - case REL_OR: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = ps->d || ps1->d; - break; - - case REL_AND: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = ps->d && ps1->d; - break; - - case BIT_OR: - /* force double values into integers and or them */ - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = (int)(ps1->d) | (int)(ps->d); - break; - - case BIT_AND: - /* force double values into integers and and them */ - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = (int)(ps1->d) & (int)(ps->d); - break; - - case BIT_EXCL_OR: - /* force double values to integers to exclusive or them */ - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = (int)(ps1->d) ^ (int)(ps->d); - break; - - case GR_OR_EQ: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - ps->d = ps->d >= ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - ps->d = ps->d >= ps1->d; - } else { - /* compare ps->s to ps1->s */ - ps->d = (double)(strcmp(ps->s, ps1->s) >= 0); - free(ps->s); - ps->s = NULL; - cleanStringElement(ps1); - } - break; - - case GR_THAN: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - ps->d = ps->d > ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - ps->d = ps->d > ps1->d; - } else { - /* compare ps->s to ps1->s */ - ps->d = (double)(strcmp(ps->s, ps1->s) > 0); - free(ps->s); - ps->s = NULL; - cleanStringElement(ps1); - } - break; - - case LESS_OR_EQ: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - ps->d = ps->d <= ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - ps->d = ps->d <= ps1->d; - } else { - /* compare ps->s to ps1->s */ - ps->d = (double)(strcmp(ps->s, ps1->s) <= 0); - free(ps->s); - ps->s = NULL; - cleanStringElement(ps1); - } - break; - - case LESS_THAN: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - ps->d = ps->d < ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - ps->d = ps->d < ps1->d; - } else { - /* compare ps->s to ps1->s */ - ps->d = (double)(strcmp(ps->s, ps1->s) < 0); - free(ps->s); - ps->s = NULL; - cleanStringElement(ps1); - } - break; - - case NOT_EQ: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - ps->d = ps->d != ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - ps->d = ps->d != ps1->d; - } else { - /* compare ps->s to ps1->s */ - ps->d = (double)(strcmp(ps->s, ps1->s) != 0); - free(ps->s); - ps->s = NULL; - cleanStringElement(ps1); - } - break; - - case EQUAL: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - ps->d = ps->d == ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - ps->d = ps->d == ps1->d; - } else if ((isString(ps)) && (isString(ps1))) { - /* compare ps->s to ps1->s */ - ps->d = (double)(strcmp(ps->s, ps1->s) == 0); - free(ps->s); - ps->s = NULL; - cleanStringElement(ps1); - } - break; - - case RIGHT_SHIFT: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = (int)(ps->d) >> (int)(ps1->d); - break; - - case LEFT_SHIFT: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = (int)(ps->d) << (int)(ps1->d); - break; - - case MAX_VAL: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - if (ps->d < ps1->d) ps->d = ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - if (ps->d < ps1->d) ps->d = ps1->d; - } else { - /* compare ps->s to ps1->s */ - if (strcmp(ps->s, ps1->s) < 0) { - s = ps->s; - ps->s = ps1->s; - ps1->s = s; - } - cleanStringElement(ps1); - } - break; - - case MIN_VAL: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) { - toDouble(ps1); - if (ps->d > ps1->d) ps->d = ps1->d; - } else if (isDouble(ps1)) { - to_double(ps); - if (ps->d > ps1->d) ps->d = ps1->d; - } else { - /* compare ps->s to ps1->s */ - if (strcmp(ps->s, ps1->s) > 0) { - s = ps->s; - ps->s = ps1->s; - ps1->s = s; - } - cleanStringElement(ps1); - } - break; - - case ACOS: - toDouble(ps); - ps->d = acos(ps->d); - break; - - case ASIN: - toDouble(ps); - ps->d = asin(ps->d); - break; - - case ATAN: - toDouble(ps); - ps->d = atan(ps->d); - break; - - case ATAN2: - ps1 = ps; - DEC(ps); - toDouble(ps1); - toDouble(ps); - ps->d = atan2(ps1->d, ps->d); - break; - - case COS: - toDouble(ps); - ps->d = cos(ps->d); - break; - - case SIN: - toDouble(ps); - ps->d = sin(ps->d); - break; - - case TAN: - toDouble(ps); - ps->d = tan(ps->d); - break; - - case COSH: - toDouble(ps); - ps->d = cosh(ps->d); - break; - - case SINH: - toDouble(ps); - ps->d = sinh(ps->d); - break; - - case TANH: - toDouble(ps); - ps->d = tanh(ps->d); - break; - - case CEIL: - toDouble(ps); - ps->d = ceil(ps->d); - break; - - case FLOOR: - toDouble(ps); - ps->d = floor(ps->d); - break; - - case NINT: - if (isDouble(ps)) { - d = ps->d; - ps->d = (double)(long)(d >= 0 ? d+0.5 : d-0.5); - } else { - /* hunt down integer and convert */ - s = strpbrk(ps->s,"0123456789"); - if ((s > ps->s) && (s[-1] == '.')) s--; - if ((s > ps->s) && (s[-1] == '-')) s--; - d = s ? atof(s) : 0.0; - free(ps->s); ps->s = NULL; - ps->d = (double)(long)(d >= 0 ? d+0.5 : d-0.5); - } - break; - - case REL_NOT: - toDouble(ps); - ps->d = (ps->d ? 0 : 1); - break; - - case BIT_NOT: - toDouble(ps); - ps->d = ~(int)(ps->d); - break; - - case LITERAL: - INC(ps); - ++post; - if (post == NULL) { - ++post; - printf("%.7s bad constant in expression\n",post); - ps->s = NULL; - ps->d = 0.; - break; - } - memcpy((void *)&(ps->d),post,8); - ps->s = NULL; - post += 7; - break; - - case SLITERAL: - INC(ps); - ++post; - if (post == NULL) { - ++post; - printf("%.7s bad constant in expression\n",post); - ps->s = NULL; - ps->d = 0.; - break; - } - ps->s = calloc(strlen(post)+1, 1); - strcpy(ps->s, post); - /* skip to end of string */ - while (*post) post++; - break; - - case TO_DOUBLE: - if (isString(ps)) { - /* hunt down number and convert */ - s = strpbrk(ps->s,"0123456789"); - if ((s > ps->s) && (s[-1] == '.')) s--; - if ((s > ps->s) && (s[-1] == '-')) s--; - ps->d = s ? atof(s) : 0.0; - free(ps->s); ps->s = NULL; - } - break; - - case TO_STRING: - toString(ps); - break; - - case PRINTF: - ps1 = ps; - DEC(ps); - if (isDouble(ps)) - {cleanup(top, ps1); return(-1);} - s = ps->s; - while ((s1 = strstr(s, "%%"))) {s = s1+2;} - if (((s = strpbrk(s, "%")) == NULL) || - ((s = strpbrk(s+1, "*cdeEfgGiousxX")) == NULL)) { - /* no printf arguments needed */ - sprintf(tmpstr, ps->s); - } else { - switch (*s) { - default: case '*': - cleanup(top, ps1); - return(-1); - case 'c': case 'd': case 'i': case 'o': - case 'u': case 'x': case 'X': - toDouble(ps1); - l = myNINT(ps1->d); - sprintf(tmpstr, ps->s, l); - break; - case 'e': case 'E': case 'f': case 'g': case 'G': - toDouble(ps1); - sprintf(tmpstr, ps->s, ps1->d); - break; - case 's': - toString(ps1); - sprintf(tmpstr, ps->s, ps1->s); - break; - } - } - if (strlen(ps->s) < strlen(tmpstr)) { - free(ps->s); - ps->s = calloc(strlen(tmpstr)+1, 1); - } - strcpy(ps->s, tmpstr); - cleanStackElement(ps1); - break; - - case SSCANF: - ps1 = ps; - DEC(ps); - if (isDouble(ps) || isDouble(ps1)) - {cleanup(top, ps1); return(-1);} - s = findConversionIndicator(ps1->s); - if (s == NULL) {cleanup(top, ps1); return(-1);} - switch (*s) { - default: case 'p': case 'w': case 'n': case '$': - cleanup(top, ps1); - return(-1); - case 'd': case 'i': - if (s[-1] == 'h') { - sscanf(ps->s, ps1->s, &h); - ps->d = (double)h; - } else { - sscanf(ps->s, ps1->s, &l); - ps->d = (double)l; - } - cleanStringElement(ps); - ps->s = NULL; - break; - case 'o': case 'u': case 'x': case 'X': - if (s[-1] == 'h') { - sscanf(ps->s, ps1->s, &ui); - ps->d = (double)ui; - } else { - sscanf(ps->s, ps1->s, &ul); - ps->d = (double)ul; - } - cleanStringElement(ps); - ps->s = NULL; - break; - case 'e': case 'E': case 'f': case 'g': case 'G': - if (s[-1] == 'l') { - sscanf(ps->s, ps1->s, &(ps->d)); - } else { - sscanf(ps->s, ps1->s, &f); - ps->d = (double)f; - } - cleanStringElement(ps); - ps->s = NULL; - break; - case 'c': case '[': case 's': - sscanf(ps->s, ps1->s, tmpstr); - if (strlen(ps->s) < strlen(tmpstr)) { - free(ps->s); - ps->s = calloc(strlen(tmpstr)+1, 1); - } - strcpy(ps->s, tmpstr); - break; - } - cleanStringElement(ps1); - break; - - case SUBRANGE: - ps2 = ps; - DEC(ps); - ps1 = ps; - DEC(ps); - toString(ps); - k = strlen(ps->s); - if (isDouble(ps1)) { - i = (int)ps1->d; - if (i < 0) i += k; - } else { - s = strstr(ps->s, ps1->s); - i = s ? (s - ps->s) + strlen(ps1->s) : 0; - } - if (isDouble(ps2)) { - j = (int)ps2->d; - if (j < 0) j += k; - } else { - if (*(ps2->s)) { - s = strstr(ps->s, ps2->s); - j = s ? (s - ps->s) - 1 : k; - } else { - j = k; - } - } - i = MAX(MIN(i,k),0); - j = MIN(j,k); - for (s=ps->s, s1=s+i, s2=s+j ; *s1 && s1 <= s2; ) - {*s++ = *s1++;} - *s = 0; - break; - - case REPLACE: - ps2 = ps; - DEC(ps); - ps1 = ps; - DEC(ps); - toString(ps); - toString(ps1); - toString(ps2); - i = strlen(ps->s); - j = strlen(ps1->s); - k = strlen(ps2->s); - s1 = strstr(ps->s, ps1->s); - s2 = ps2->s; - if (s1 >= ps->s) { - char *s_old, *s_dest; - s_old = s = ps->s; - if (k > j) ps->s = malloc(i - j + k + 1); - s_dest = ps->s; - while (s < s1) *s_dest++ = *s++; - s += j; - while (*s2) *s_dest++ = *s2++; - while (*s) *s_dest++ = *s++; - *s_dest = '\0'; - if (k > j) free(s_old); - } - cleanStringElement(ps1); - cleanStringElement(ps2); - break; - - default: - break; - } - - /* move ahead in postfix expression */ - ++post; - } - - /* if everything is peachy,the stack should end at its first position */ - if (ps != top) - return(-1); - - if (isDouble(ps)) { - if (presult) *presult = ps->d; - if (psresult) { - toString(ps); - for (i=0, s=ps->s, s1=psresult; *s && is, lenSresult); */ - psresult[lenSresult-1] = 0; - cleanStringElement(ps); - } - } else { - if (psresult) { - for (i=0, s=ps->s, s1=psresult; *s && id; - } else { - cleanStringElement(ps); - } - } - - } /* if (*post++ != USES_STRING) {} else */ - - return(0); -} - - -/* - * RAND - * - * generates a random number between 0 and 1 using the - * seed = (multy * seed) + addy Random Number Generator by Knuth - * SemiNumerical Algorithms - * Chapter 1 - * randy = seed / 65535.0 To normalize the number between 0 - 1 - */ -static unsigned short seed = 0xa3bf; -static unsigned short multy = 191 * 8 + 5; /* 191 % 8 == 5 */ -static unsigned short addy = 0x3141; -static double local_random() -{ - double randy; - - /* random number */ - seed = (seed * multy) + addy; - randy = (float) seed / 65535.0; - - /* between 0 - 1 */ - return(randy); -} diff --git a/src/libCom/calc/sCalcPostfix.c b/src/libCom/calc/sCalcPostfix.c deleted file mode 100644 index c8b71bbc8..000000000 --- a/src/libCom/calc/sCalcPostfix.c +++ /dev/null @@ -1,723 +0,0 @@ -/* $Id$ - * Subroutines used to convert an infix expression to a postfix expression - * - * Author: Bob Dalesio - * Date: 12-12-86 - * - * 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 01-11-89 lrd added right shift and left shift operations - * .02 01-13-89 lrd modified to load into IOCs - * .03 02-01-89 lrd added trigonometric functions - * .04 04-05-89 lrd fixed the order of some operations in the - * element table and added a warning label - * .05 11-26-90 lrd fix SINH, COSH, TANH - * .06 02-20-92 rcz fixed for vxWorks build - * .07 02-24-92 jba add EXP and fixed trailing blanks in expression - * .08 03-03-92 jba added MAX_VAL and MIN_VAL and comma(like close paren) - * .09 03-06-92 jba added multiple conditional expressions ? - * .10 04-01-92 jba allowed floating pt constants in expression - * .11 05-01-92 jba flt pt constant string replaced with double in postfix - * .12 08-21-92 jba ANSI c changes - * .13 08-21-92 jba initialized *ppostfix: needed when calc expr not defined - * .14 12-11-92 mrk Removed include for stdioLib.h - * .15 11-03-93 jba Added test for extra close paren at end of expression - * .16 01-24-94 jba Changed seperator test to catch invalid commas - * .17 05-11-94 jba Added support for CONST_PI, CONST_R2D, and CONST_D2R - * and conversion of infix expression to uppercase - * .18 01-22-98 tmm Changed name postfix() to calcPostfix(). Changed arg list - * from pointer to postfix expression to address of pointer to - * postfix expression. calcPostfix() frees old expression, allocates - * space sufficient to hold new expression, and returns pointer to it. - * Added S2R, R2S (conversions between arc-seconds and radians). Changed - * CONSTANT to LITERAL to avoid conflict with link.h. Support 26 vars (A-Z). - * .19 03-18-98 tmm Added string operators - */ - -/* - * Subroutines - * - * Public - * - * sCalcPostfix convert an algebraic expression to symbolic postfix - * args - * pinfix the algebraic expression - * pp_postfix address of the symbolic postfix expression - * perror error information - * returns - * 0 successful - * -1 not successful - * Private routines for calcPostfix - * - * find_element finds a symbolic element in the expression element tbl - * args - * pbuffer pointer to the infix expression element - * pelement pointer to the expression element table entry - * pno_bytes pointer to the size of this element - * parg pointer to arg (used for fetch) - * returns - * TRUE element found - * FALSE element not found - * - * get_element finds the next expression element in the infix expr - * args - * pinfix pointer into the infix expression - * pelement pointer to the expression element table - * pno_bytes size of the element in the infix expression - * parg pointer to argument (used for fetch) - * returns - * FINE found an expression element - * VARIABLE found a database reference - * UNKNOWN_ELEMENT unknown element found in the infix expression - */ - -#ifdef vxWorks -#include -#endif - -#include -#include -#include -#include - -#include "dbDefs.h" -#define epicsExportSharedSymbols -#include "sCalcPostfix.h" -#include "sCalcPostfixPvt.h" - - -#define OVERRIDESTDCALC 0 -#define DEBUG 0 -volatile int sCalcPostfixDebug=0; - -/* declarations for postfix */ -/* element types */ -#define OPERAND 0 -#define UNARY_OPERATOR 1 -#define BINARY_OPERATOR 2 -#define EXPR_TERM 3 -#define COND 4 -#define CLOSE_PAREN 5 -#define CONDITIONAL 6 -#define ELSE 7 -#define SEPARATOR 8 -#define TRASH 9 -#define FLOAT_PT_CONST 10 -#define MINUS_OPERATOR 11 -#define STRING_CONST 12 -#define CLOSE_BRACKET 13 -#define CLOSE_CURLY 14 - -#define UNARY_MINUS_I_S_P 7 -#define UNARY_MINUS_I_C_P 8 -#define UNARY_MINUS_CODE UNARY_NEG -#define BINARY_MINUS_I_S_P 4 -#define BINARY_MINUS_I_C_P 4 -#define BINARY_MINUS_CODE SUB - -/* parsing return values */ -#define FINE 0 -#define UNKNOWN_ELEMENT -1 -#define END -2 - -/* - * element table - * - * structure of an element - */ -struct expression_element{ - char element[10]; /* character representation of an element */ - char in_stack_pri; /* priority in translation stack */ - char in_coming_pri; /* priority when first checking */ - char type; /* element type */ - char code; /* postfix representation */ -}; - -/* - * NOTE: DO NOT CHANGE WITHOUT READING THIS NOTICE !!!!!!!!!!!!!!!!!!!! - * Because the routine that looks for a match in this table takes the first - * match it finds, elements whose designations are contained in other elements - * MUST come first in this list. (e.g. ABS will match A if A preceeds ABS and - * then try to find BS therefore ABS must be first in this list - */ -static struct expression_element elements[] = { -/* -element i_s_p i_c_p type_element internal_rep */ -"ABS", 7, 8, UNARY_OPERATOR, ABS_VAL, /* absolute value */ -"NOT", 7, 8, UNARY_OPERATOR, UNARY_NEG, /* unary negate */ -"-", 7, 8, MINUS_OPERATOR, UNARY_NEG, /* unary negate (or binary op) */ -"SQRT", 7, 8, UNARY_OPERATOR, SQU_RT, /* square root */ -"SQR", 7, 8, UNARY_OPERATOR, SQU_RT, /* square root */ -"EXP", 7, 8, UNARY_OPERATOR, EXP, /* exponential function */ -"LOGE", 7, 8, UNARY_OPERATOR, LOG_E, /* log E */ -"LN", 7, 8, UNARY_OPERATOR, LOG_E, /* log E */ -"LOG", 7, 8, UNARY_OPERATOR, LOG_10, /* log 10 */ -"ACOS", 7, 8, UNARY_OPERATOR, ACOS, /* arc cosine */ -"ASIN", 7, 8, UNARY_OPERATOR, ASIN, /* arc sine */ -"ATAN2", 7, 8, UNARY_OPERATOR, ATAN2, /* arc tangent */ -"ATAN", 7, 8, UNARY_OPERATOR, ATAN, /* arc tangent */ -"MAX", 7, 8, UNARY_OPERATOR, MAX_VAL, /* maximum of 2 args */ -"MIN", 7, 8, UNARY_OPERATOR, MIN_VAL, /* minimum of 2 args */ -"CEIL", 7, 8, UNARY_OPERATOR, CEIL, /* smallest integer >= */ -"FLOOR", 7, 8, UNARY_OPERATOR, FLOOR, /* largest integer <= */ -"NINT", 7, 8, UNARY_OPERATOR, NINT, /* nearest integer */ -"INT", 7, 8, UNARY_OPERATOR, NINT, /* nearest integer */ -"COSH", 7, 8, UNARY_OPERATOR, COSH, /* hyperbolic cosine */ -"COS", 7, 8, UNARY_OPERATOR, COS, /* cosine */ -"SINH", 7, 8, UNARY_OPERATOR, SINH, /* hyperbolic sine */ -"SIN", 7, 8, UNARY_OPERATOR, SIN, /* sine */ -"TANH", 7, 8, UNARY_OPERATOR, TANH, /* hyperbolic tangent*/ -"TAN", 7, 8, UNARY_OPERATOR, TAN, /* tangent */ -"!=", 3, 3, BINARY_OPERATOR,NOT_EQ, /* not equal */ -"!", 7, 8, UNARY_OPERATOR, REL_NOT, /* not */ -"~", 7, 8, UNARY_OPERATOR, BIT_NOT, /* bitwise not */ -"DBL", 7, 8, UNARY_OPERATOR, TO_DOUBLE, /* convert to double */ -"STR", 7, 8, UNARY_OPERATOR, TO_STRING, /* convert to string */ -"$P", 7, 8, UNARY_OPERATOR, PRINTF, /* formatted print to string */ -"PRINTF", 7, 8, UNARY_OPERATOR, PRINTF, /* formatted print to string */ -"$S", 7, 8, UNARY_OPERATOR, SSCANF, /* scan string argument */ -"SSCANF", 7, 8, UNARY_OPERATOR, SSCANF, /* scan string argument */ -"RNDM", 0, 0, OPERAND, RANDOM, /* Random Number */ -"OR", 1, 1, BINARY_OPERATOR,BIT_OR, /* or */ -"AND", 2, 2, BINARY_OPERATOR,BIT_AND, /* and */ -"XOR", 1, 1, BINARY_OPERATOR,BIT_EXCL_OR, /* exclusive or */ -"PI", 0, 0, OPERAND, CONST_PI, /* pi */ -"D2R", 0, 0, OPERAND, CONST_D2R, /* pi/180 */ -"R2D", 0, 0, OPERAND, CONST_R2D, /* 180/pi */ -"S2R", 0, 0, OPERAND, CONST_S2R, /* arc-sec to radians: pi/(180*3600) */ -"R2S", 0, 0, OPERAND, CONST_R2S, /* radians to arc-sec: (180*3600)/pi */ -"0", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"1", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"2", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"3", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"4", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"5", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"6", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"7", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"8", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"9", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -".", 0, 0, FLOAT_PT_CONST, LITERAL, /* flt pt constant */ -"\"", 0, 0, STRING_CONST, SLITERAL, /* string constant */ -"'", 0, 0, STRING_CONST, SLITERAL, /* string constant */ -"?", 0, 0, CONDITIONAL, COND_IF, /* conditional */ -":", 0, 0, CONDITIONAL, COND_ELSE, /* else */ -"(", 0, 8, UNARY_OPERATOR, PAREN, /* open paren */ -"[", 0, 8, BINARY_OPERATOR,SUBRANGE, /* string subrange */ -"{", 0, 8, BINARY_OPERATOR,REPLACE, /* string replace */ -"^", 6, 6, BINARY_OPERATOR,EXPON, /* exponentiation */ -"**", 6, 6, BINARY_OPERATOR,EXPON, /* exponentiation */ -"+", 4, 4, BINARY_OPERATOR,ADD, /* addition */ -#if 0 /* "-" operator is overloaded; may be unary or binary */ -"-", 4, 4, BINARY_OPERATOR,SUB, /* subtraction */ -#endif -"*", 5, 5, BINARY_OPERATOR,MULT, /* multiplication */ -"/", 5, 5, BINARY_OPERATOR,DIV, /* division */ -"%", 5, 5, BINARY_OPERATOR,MODULO, /* modulo */ -",", 0, 0, SEPARATOR, COMMA, /* comma */ -")", 0, 0, CLOSE_PAREN, PAREN, /* close paren */ -"]", 0, 0, CLOSE_BRACKET, SUBRANGE, /* close bracket */ -"}", 0, 0, CLOSE_CURLY, REPLACE, /* close curly bracket */ -"||", 1, 1, BINARY_OPERATOR,REL_OR, /* logical or */ -"|", 1, 1, BINARY_OPERATOR,BIT_OR, /* bitwise or */ -"&&", 2, 2, BINARY_OPERATOR,REL_AND, /* logical and */ -"&", 2, 2, BINARY_OPERATOR,BIT_AND, /* bitwise and */ -">>", 2, 2, BINARY_OPERATOR,RIGHT_SHIFT, /* right shift */ -">=", 3, 3, BINARY_OPERATOR,GR_OR_EQ, /* greater or equal*/ -">", 3, 3, BINARY_OPERATOR,GR_THAN, /* greater than */ -"<<", 2, 2, BINARY_OPERATOR,LEFT_SHIFT, /* left shift */ -"<=", 3, 3, BINARY_OPERATOR,LESS_OR_EQ,/* less or equal to*/ -"<", 3, 3, BINARY_OPERATOR,LESS_THAN, /* less than */ -"#", 3, 3, BINARY_OPERATOR,NOT_EQ, /* not equal */ -"==", 3, 3, BINARY_OPERATOR,EQUAL, /* equal */ -"=", 3, 3, BINARY_OPERATOR,EQUAL, /* equal */ -"" -}; - -/* - * Element-table entry for "fetch" operation. This element is used for all - * named variables. Currently, letters A-Z (double) and AA-ZZ (string) are - * allowed. Lower and upper case letters mean the same thing. - */ -static struct expression_element fetch_element = { -"A", 0, 0, OPERAND, FETCH, /* fetch var */ -}; - -static struct expression_element fetch_string_element = { -"AA", 0, 0, OPERAND, SFETCH, /* fetch var */ -}; - -#if !defined(UNIX) -static int strncasecmp(char *s1, char *s2, size_t n) -{ - short i; - for (i=0; i<(short)n && (*s1 || *s2); i++, s1++, s2++) { - if (toupper((int)*s1) > toupper((int)*s2)) return(1); - if (toupper((int)*s1) < toupper((int)*s2)) return(-1); - } - return(0); -} -#endif -/* - * FIND_ELEMENT - * - * find the pointer to an entry in the element table - */ -static int find_element(pbuffer, pelement, pno_bytes, parg) - register char *pbuffer; - register struct expression_element **pelement; - register short *pno_bytes, *parg; - { - *parg = 0; - - /* compare the string to each element in the element table */ - *pelement = &elements[0]; - while ((*pelement)->element[0] != NULL){ - if (strncasecmp(pbuffer,(*pelement)->element, strlen((*pelement)->element)) == 0){ - *pno_bytes += strlen((*pelement)->element); - return(TRUE); - } - *pelement += 1; - } - - /* look for a variable reference */ - /* double variables: ["a" - "z"], numbered 1-26 */ - if (isalpha((int)*pbuffer)) { - *pelement = &fetch_element; /* fetch means "variable reference" (fetch or store) */ - *parg = *pbuffer - (isupper((int)*pbuffer) ? 'A' : 'a'); - *pno_bytes += 1; - /* string variables: ["aa" - "zz"], numbered 1-26 */ - if (pbuffer[1] == pbuffer[0]) { - *pelement = &fetch_string_element; - *pno_bytes += 1; - } - return(TRUE); - } - if (sCalcPostfixDebug) printf("find_element: can't find '%s'\n", pbuffer); - return(FALSE); - } - -/* - * GET_ELEMENT - * - * get an expression element - */ -static int get_element(pinfix, pelement, pno_bytes, parg) -register char *pinfix; -register struct expression_element **pelement; -register short *pno_bytes, *parg; -{ - - /* get the next expression element from the infix expression */ - if (*pinfix == NULL) return(END); - *pno_bytes = 0; - while (*pinfix == 0x20){ - *pno_bytes += 1; - pinfix++; - } - if (*pinfix == NULL) return(END); - if (!find_element(pinfix, pelement, pno_bytes, parg)) - return(UNKNOWN_ELEMENT); - if (sCalcPostfixDebug > 5) printf("get_element: found element '%s', arg=%d\n", (*pelement)->element, *parg); - - return(FINE); - - -} - -#if OVERRIDESTDCALC -/* Override standard EPICS expression evaluator (if we're loaded after it). */ -long epicsShareAPI postfix(char *pinfix,char *ppostfix,short *perror) -{ - char *my_ppostfix = NULL, *s, *d; - long retval; - - retval = sCalcPostfix(pinfix, &my_ppostfix, perror); - if (*my_ppostfix == BAD_EXPRESSION) { - *ppostfix = BAD_EXPRESSION; - } else { - for (s = my_ppostfix, d = ppostfix; *s != END_STACK; ) { - *d++=*s++; - } - *d = *s; - } - free(my_ppostfix); - return(retval); -} -#endif - -/* - * sCalcPostFix - * - * convert an infix expression to a postfix expression - */ -long epicsShareAPI sCalcPostfix(char *pinfix, char **pp_postfix, short *perror) -{ - short no_bytes; - register short operand_needed; - register short new_expression; - struct expression_element stack[80]; - struct expression_element *pelement; - register struct expression_element *pstacktop; - double constant; - register char c, *pposthold; - char in_stack_pri, in_coming_pri, code; - char *ppostfix, *ppostfixStart; - short arg; - - if (sCalcPostfixDebug) printf("sCalcPostfix: entry\n"); - - /* Allocate a buffer for the postfix expression. */ - if (*pp_postfix) free(*pp_postfix); /* Free old buffer. */ - ppostfix = calloc(5*strlen(pinfix)+7, 1); - *pp_postfix = ppostfix; - ppostfixStart = ppostfix++; - *ppostfixStart = BAD_EXPRESSION; - *ppostfix = END_STACK; - - /* place the expression elements into postfix */ - operand_needed = TRUE; - new_expression = TRUE; - *perror = 0; - if (*pinfix == 0) { - return(0); - } - pstacktop = &stack[0]; - while (get_element(pinfix, &pelement, &no_bytes, &arg) != END){ - pinfix += no_bytes; - code = pelement->code; - if ((*ppostfixStart != USES_STRING) && ((code == TO_STRING) || - (code == PRINTF) || (code == SSCANF) || (code == SLITERAL) || - (code == SUBRANGE) || (code == SFETCH))) { - *ppostfixStart = USES_STRING; - } - - switch (pelement->type){ - - case OPERAND: - if (!operand_needed){ - *perror = 5; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operand to the expression */ - *ppostfix++ = pelement->code; - - /* if this is a variable reference, append variable number */ - if ((pelement->code == (char)FETCH) || (pelement->code == (char)SFETCH)) { - *ppostfix++ = arg; - } - - operand_needed = FALSE; - new_expression = FALSE; - break; - - case FLOAT_PT_CONST: - if (!operand_needed){ - *perror = 5; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add constant to postfix expression */ - *ppostfix++ = pelement->code; - pposthold = ppostfix; - - pinfix-=no_bytes; - while (*pinfix == ' ') *ppostfix++ = *pinfix++; - while (TRUE) { - if ( ( *pinfix >= '0' && *pinfix <= '9' ) || *pinfix == '.' ) { - *ppostfix++ = *pinfix; - pinfix++; - } else if ( *pinfix == 'E' || *pinfix == 'e' ) { - *ppostfix++ = *pinfix; - pinfix++; - if (*pinfix == '+' || *pinfix == '-' ) { - *ppostfix++ = *pinfix; - pinfix++; - } - } else break; - } - *ppostfix++ = '\0'; - - ppostfix = pposthold; - if ( sscanf(ppostfix,"%lg",&constant) != 1) { - *ppostfix = '\0'; - } else { - memcpy(ppostfix,(void *)&constant,8); - } - ppostfix+=8; - - operand_needed = FALSE; - new_expression = FALSE; - break; - - case STRING_CONST: - if (!operand_needed){ - *perror = 5; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add string literal to the postfix expression */ - *ppostfix++ = pelement->code; - c = pinfix[-1]; - while (*pinfix != c && *pinfix) *ppostfix++ = *pinfix++; - *ppostfix++ = '\0'; - if (*pinfix) pinfix++; - - operand_needed = FALSE; - new_expression = FALSE; - break; - - case BINARY_OPERATOR: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators of higher or equal priority to postfix expression */ - while ((pstacktop->in_stack_pri >= pelement->in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new operator to stack */ - pstacktop++; - *pstacktop = *pelement; - - operand_needed = TRUE; - break; - - case UNARY_OPERATOR: - if (!operand_needed){ - *perror = 5; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators of higher or equal priority to postfix expression */ - while ((pstacktop->in_stack_pri >= pelement->in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new operator to stack */ - pstacktop++; - *pstacktop = *pelement; - - new_expression = FALSE; - break; - - case MINUS_OPERATOR: - if (operand_needed) { - /* then assume minus was intended as a unary operator */ - in_coming_pri = UNARY_MINUS_I_C_P; - in_stack_pri = UNARY_MINUS_I_S_P; - code = UNARY_MINUS_CODE; - new_expression = FALSE; - } else { - /* then assume minus was intended as a binary operator */ - in_coming_pri = BINARY_MINUS_I_C_P; - in_stack_pri = BINARY_MINUS_I_S_P; - code = BINARY_MINUS_CODE; - operand_needed = TRUE; - } - - /* add operators of higher or equal priority to postfix expression */ - while ((pstacktop->in_stack_pri >= in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new operator to stack */ - pstacktop++; - *pstacktop = *pelement; - pstacktop->in_stack_pri = in_stack_pri; - pstacktop->code = code; - - break; - - case SEPARATOR: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators to postfix until open paren */ - while ((pstacktop->element[0] != '(') && (pstacktop->element[0] != '[') - && (pstacktop->element[0] != '{')) { - if (pstacktop == &stack[1] || pstacktop == &stack[0]){ - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - operand_needed = TRUE; - break; - - case CLOSE_PAREN: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators to postfix until matching paren */ - while (pstacktop->element[0] != '(') { - if (pstacktop == &stack[1] || pstacktop == &stack[0]) { - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - pstacktop--; /* remove ( from stack */ - break; - - case CLOSE_BRACKET: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators to postfix until matching bracket */ - while (pstacktop->element[0] != '[') { - if (pstacktop == &stack[1] || pstacktop == &stack[0]) { - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - /* add SUBRANGE operator to postfix */ - if (pstacktop == &stack[0]) { - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - break; - - case CLOSE_CURLY: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators to postfix until matching bracket */ - while (pstacktop->element[0] != '{') { - if (pstacktop == &stack[1] || pstacktop == &stack[0]) { - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - /* add REPLACE operator to postfix */ - if (pstacktop == &stack[0]) { - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - break; - - case CONDITIONAL: - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add operators of higher priority to postfix expression */ - while ((pstacktop->in_stack_pri > pelement->in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new element to the postfix expression */ - *ppostfix++ = pelement->code; - - /* add : operator with COND_END code to stack */ - if (pelement->element[0] == ':'){ - pstacktop++; - *pstacktop = *pelement; - pstacktop->code = COND_END; - } - - operand_needed = TRUE; - break; - - case EXPR_TERM: - if (operand_needed && !new_expression){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add all operators on stack to postfix */ - while (pstacktop >= &stack[1]){ - if (pstacktop->element[0] == '('){ - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new element to the postfix expression */ - *ppostfix++ = pelement->code; - - operand_needed = TRUE; - new_expression = TRUE; - break; - - default: - *perror = 8; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - } - if (operand_needed){ - *perror = 4; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - - /* add all operators on stack to postfix */ - while (pstacktop >= &stack[1]){ - if (pstacktop->element[0] == '('){ - *perror = 6; - *ppostfixStart = BAD_EXPRESSION; return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - *ppostfix++ = END_STACK; - *ppostfix = '\0'; - - if (ppostfixStart[1] == END_STACK) - *ppostfixStart = BAD_EXPRESSION; - else if (*ppostfixStart != USES_STRING) - *ppostfixStart = NO_STRING; - - return(0); -} diff --git a/src/libCom/calc/sCalcPostfix.h b/src/libCom/calc/sCalcPostfix.h deleted file mode 100644 index 3c3e6b14b..000000000 --- a/src/libCom/calc/sCalcPostfix.h +++ /dev/null @@ -1,48 +0,0 @@ -/* sCalcPostfix.h - * Author: Bob Dalesio - * Date: 9-21-88 - * - * 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 03-18-98 tmm derived from postfix.h - * - */ - -#ifndef INCpostfixh -#define INCpostfixh - -#include "shareLib.h" - -#define BAD_EXPRESSION 0 -#define END_STACK 127 - -long epicsShareAPI sCalcPostfix (char *pinfix, - char **pp_postfix, short *perror); -epicsShareFunc long epicsShareAPI - sCalcPerform (double *parg, int numArgs, - char **psarg, int numSArgs, double *presult, - char *psresult, int lenSresult, char *post); - -#endif /* INCpostfixh */ - diff --git a/src/libCom/calc/sCalcPostfixPvt.h b/src/libCom/calc/sCalcPostfixPvt.h deleted file mode 100644 index f7ac29f1e..000000000 --- a/src/libCom/calc/sCalcPostfixPvt.h +++ /dev/null @@ -1,115 +0,0 @@ -/* sCalcPostfixPvt.h - * Author: Bob Dalesio - * Date: 9-21-88 - * - * 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 03-18-98 tmm derived from postfix.h - * - */ - -#ifndef INCpostfixh -#include -#endif -#ifndef INCpostfixPvth -#define INCpostfixPvth - -/* #define BAD_EXPRESSION 0 */ - -/* defines for element table */ -/* elements that define a value */ -#define FETCH 1 -#define SFETCH 2 -#define CONST_PI 3 -#define CONST_D2R 4 -#define CONST_R2D 5 -#define CONST_S2R 6 -#define CONST_R2S 7 -#define RANDOM 8 -#define LITERAL 9 -#define SLITERAL 10 -#define SSCANF 11 - -#define VALUE_ELEMENT 11 - -/* elements that operate on a value */ -#define ACOS 12 -#define ASIN 13 -#define ATAN 14 -#define COS 15 -#define COSH 16 -#define SIN 17 -#define RIGHT_SHIFT 18 -#define LEFT_SHIFT 19 -#define SINH 20 -#define TAN 21 -#define TANH 22 -#define LOG_2 23 -#define COND_ELSE 24 -#define ABS_VAL 25 -#define UNARY_NEG 26 -#define SQU_RT 27 -#define EXP 28 -#define CEIL 29 -#define FLOOR 30 -#define LOG_10 31 -#define LOG_E 32 -#define ADD 33 -#define SUB 34 -#define MULT 35 -#define DIV 36 -#define EXPON 37 -#define MODULO 38 -#define BIT_OR 39 -#define BIT_AND 40 -#define BIT_EXCL_OR 41 -#define GR_OR_EQ 42 -#define GR_THAN 43 -#define LESS_OR_EQ 44 -#define LESS_THAN 45 -#define NOT_EQ 46 -#define EQUAL 47 -#define REL_OR 48 -#define REL_AND 49 -#define REL_NOT 50 -#define BIT_NOT 51 -#define PAREN 52 -#define MAX_VAL 53 -#define MIN_VAL 54 -#define COMMA 55 -#define COND_IF 56 -#define COND_END 57 -#define NINT 58 -#define ATAN2 59 -#define STORE 60 -#define TO_DOUBLE 61 -#define PRINTF 62 -#define SUBRANGE 63 -#define TO_STRING 64 -#define REPLACE 65 -/* #define END_STACK 127 */ - -#define USES_STRING 126 -#define NO_STRING 125 -#endif /* INCpostfixPvth */ diff --git a/src/libCom/cmdSubr.c b/src/libCom/cmdSubr.c deleted file mode 100644 index 9b682b689..000000000 --- a/src/libCom/cmdSubr.c +++ /dev/null @@ -1,315 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 10-24-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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: - * ----------------- - * .00 10-24-90 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 12-05-91 rac abandon use of lightweight process library; - * cmdRead ignores blank lines and comment - * lines; added cmdInitContext - * .03 09-14-92 rac discontinue use of special malloc routines - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code - */ -/*+/mod*********************************************************************** -* TITLE cmdSubr - routines for implementing keyboard command processing -* -* DESCRIPTION -* -* long cmdBgCheck( pCxCmd ) -* void cmdCloseContext( ppCxCmd ) -* void cmdInitContext( ppCxCmd, prompt ) -* char *cmdRead( ppCxCmd ) -* void cmdSource( ppCxCmd ) -* -* BUGS -* o if changes in the command context (e.g., re-directing output) are -* made at other than root context level, such changes aren't preserved -* when closing out the level and moving to the previous level. -* -*-***************************************************************************/ -#ifdef vxWorks -/*---------------------------------------------------------------------------- -* includes and defines for VxWorks compile -*---------------------------------------------------------------------------*/ -# include -# include -# include -#else -/*---------------------------------------------------------------------------- -* includes and defines for Sun compile -*---------------------------------------------------------------------------*/ -# include -# include -# include /* for 'select' operations */ -# include /* for 'select' operations */ - -# include -#endif - -#include -#include - -/*+/subr********************************************************************** -* NAME cmdBgCheck - validate a ``bg'' command -* -* DESCRIPTION -* Check to see if a bg command can be honored. This depends on -* whether the command was in a source'd file (can't have bg there), -* and on whether running under VxWorks (bg is OK) or UNIX (not OK). -* -* If the command shouldn't be honored, this routine prints a message. -* -* RETURNS -* OK, or -* ERROR if the bg command should not be honored -* -*-*/ -long -cmdBgCheck(pCxCmd) -CX_CMD *pCxCmd; /* IO pointer to command context */ -{ - HELP_TOPIC *pBgTopic; - - if (pCxCmd != pCxCmd->pCxCmdRoot) { - (void)printf("can't use bg command in source file\n"); - return ERROR; - } -#ifdef vxWorks - return OK; -#else - pBgTopic = helpTopicFind(&pCxCmd->helpList, "bg"); - if (pBgTopic != NULL) - helpTopicPrint(stdout, pBgTopic); - return ERROR; -#endif -} - -/*+/subr********************************************************************** -* NAME cmdRead - read the next input line -* -* DESCRIPTION -* If a prompt hasn't previously been printed, prints a prompt (except -* if input is from a file). Then a check is made to see if input is -* available. If not, NULL is returned. If input is available, it is -* read into the buffer in the command context. -* -* If input is from a source'd file, no prompt is printed, and the -* input line is printed. At EOF on the file, the "source level" -* in the command context is closed, changing to the previous -* source level; the line buffer will contain a zero length line. -* -* Under VxWorks, this routine always waits until input is available, -* rather than doing a check and early NULL return if none is ready. -* -* RETURNS -* char * pointer to input, or -* NULL if no input was obtained -* -* BUGS -* o under VxWorks, with stdout redirected to a socket, a prompt which -* doesn't end with '\n' doesn't get sent -* -* SEE ALSO -* cmdSource() -* -*-*/ -char * -cmdRead(ppCxCmd) -CX_CMD **ppCxCmd; /* I pointer to pointer to command context */ -{ -#ifndef vxWorks - fd_set fdSet; /* set of fd's to watch with select */ - int fdSetWidth; /* width of select bit mask */ - struct timeval fdSetTimeout;/* timeout interval for select */ - struct rlimit rlp; -#endif - CX_CMD *pCxCmd=*ppCxCmd;/* pointer to command context */ - int i; - -/*----------------------------------------------------------------------------- -* for keyboard and socket input, check to see if input is available -*----------------------------------------------------------------------------*/ - if (pCxCmd->inputName == NULL) { - if (pCxCmd->prompt != NULL && pCxCmd->promptFlag) { - (void)printf("%s", pCxCmd->prompt); - (void)fflush(stdout); - pCxCmd->promptFlag = 0; - } - -#ifndef vxWorks -/* MDA - use getrlimit since getdtablesize() is obsolete - fdSetWidth = getdtablesize(); -*/ - getrlimit(RLIMIT_NOFILE,&rlp); - fdSetWidth = rlp.rlim_cur; - - fdSetTimeout.tv_sec = 0; - fdSetTimeout.tv_usec = 0; - FD_ZERO(&fdSet); - FD_SET(fileno(stdin), &fdSet); - - if (select(fdSetWidth, &fdSet, NULL, NULL, &fdSetTimeout) == 0) - return NULL; -#endif - pCxCmd->promptFlag = 1; - } - - if (fgets(pCxCmd->line, 80, pCxCmd->input) == NULL) { - if (pCxCmd->inputName != NULL) { - (void)printf("EOF on source'd file: %s\n", pCxCmd->inputName); - } - else { - (void)printf("^D\n"); - pCxCmd->inputEOF = 1; - } - clearerr(pCxCmd->input); - cmdCloseContext(ppCxCmd); - pCxCmd = *ppCxCmd; - } - else if (pCxCmd->inputName != NULL) - (void)printf("%s", pCxCmd->line); - - pCxCmd->pLine = pCxCmd->line; - if ((i=nextANField(&pCxCmd->pLine, &pCxCmd->pCommand, &pCxCmd->delim)) < 1) - return NULL; - if (i == 1 && pCxCmd->delim == '#') - return NULL; - return pCxCmd->pLine; -} - -/*+/subr********************************************************************** -* NAME cmdCloseContext - closes a command context -* -* DESCRIPTION -* Closes a command context. The action depends on source of input: -* -* keyboard (or socket): -* o store "quit\n" in the line buffer -* -* source'd file: -* o close out this "source level" -* o move to the previous "source level" -* o store '\0' in the line buffer -* -* RETURNS -* void -* -*-*/ -void -cmdCloseContext(ppCxCmd) -CX_CMD **ppCxCmd; /* IO ptr to pointer to command context */ -{ - CX_CMD *pCxCmd; /* temp pointer */ - - assert(ppCxCmd != NULL); - - if ((*ppCxCmd)->inputName == NULL) - strcpy((*ppCxCmd)->line, "quit\n"); - else { - (void)fclose((*ppCxCmd)->input); - assert((*ppCxCmd)->pPrev != NULL); - pCxCmd = (*ppCxCmd)->pPrev; - free((char *)(*ppCxCmd)); - *ppCxCmd = pCxCmd; - (*ppCxCmd)->line[0] = '\0'; - } -} - -/*+/subr********************************************************************** -* NAME cmdInitContext - closes a command context -* -* DESCRIPTION -* Initializes a command context. -* -* RETURNS -* void -* -*-*/ -void -cmdInitContext(pCxCmd, prompt) -CX_CMD *pCxCmd; /* I pointer to command context */ -char *prompt; /* I pointer to static prompt string */ -{ - assert(pCxCmd != NULL); - - pCxCmd->promptFlag = 1; - pCxCmd->input = stdin; - pCxCmd->inputEOF = 0; - pCxCmd->inputName = NULL; - pCxCmd->dataOut = stdout; - pCxCmd->dataOutRedir = 0; - pCxCmd->prompt = prompt; - pCxCmd->pPrev = NULL; - pCxCmd->pCxCmdRoot = pCxCmd; -} - -/*+/subr********************************************************************** -* NAME cmdSource - process a ``source'' command -* -* DESCRIPTION -* Processes a "source fileName" command. A new command context is -* built and set up for reading from the named file. If an error -* is detected, the present command context is preserved. -* -* RETURNS -* void -* -*-*/ -void -cmdSource(ppCxCmd) -CX_CMD **ppCxCmd; /* IO ptr to pointer to command context. The - pCommand item is assumed to point to the - source command. This routine scans for - the file name. */ -{ - CX_CMD *pCxCmdNew; /* new command context structure */ - CX_CMD *pCxCmd; /* present command context structure */ - - pCxCmd = *ppCxCmd; - pCxCmd->fldLen = - nextNonSpaceField(&pCxCmd->pLine, &pCxCmd->pField, &pCxCmd->delim); - if (pCxCmd->fldLen <= 1) { - (void)printf("you must specify a file name\n"); - return; - } - if ((pCxCmdNew = (CX_CMD *)malloc(sizeof(CX_CMD))) == NULL) { - (void)printf("couldn't malloc command structure\n"); - return; - } - *pCxCmdNew = *pCxCmd; /* inherit useful info from present context */ - if ((pCxCmdNew->input = fopen(pCxCmd->pField, "r")) == NULL) { - (void)printf("couldn't open file\n"); - free((char *)pCxCmdNew); - return; - } - pCxCmdNew->pPrev = pCxCmd; - pCxCmdNew->inputName = pCxCmd->pField; - *ppCxCmd = pCxCmdNew; -} diff --git a/src/libCom/createSoftLinks.sh b/src/libCom/createSoftLinks.sh deleted file mode 100644 index 52e96d2dc..000000000 --- a/src/libCom/createSoftLinks.sh +++ /dev/null @@ -1,47 +0,0 @@ -#! /bin/sh -# $Id$ -# Author: Robert Zieman (ANL) -# Date: 6/03/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 mm-dd-yy iii Comment -# .02 mm-dd-yy iii Comment -# ... -# - -# Tailored script to create local softlinks releative to this directory -# the name createSoftLinks.sh is a key and must not be changed. If the -# release tool sccsGet finds a file by the name of (createSoftLinks.sh), -# after it has retrieved any out-of-date SCCS files, it invokes the -# script to create the defined softlinks - -/bin/rm -f blderrSymTbl -/bin/rm -f errInc.c -/bin/rm -f makeStatTbl - -ln -s ../misc/blderrSymTbl blderrSymTbl -ln -s ../../epicsH/errInc.c errInc.c -ln -s ../misc/makeStatTbl makeStatTbl - diff --git a/src/libCom/cvtFast/cvtFast.c b/src/libCom/cvtFast/cvtFast.c deleted file mode 100644 index 38c82e41a..000000000 --- a/src/libCom/cvtFast/cvtFast.c +++ /dev/null @@ -1,621 +0,0 @@ -/* $Id$*/ -/* Very efficient routines to convert numbers to strings - * Author: Bob Dalesio wrote cvtFloatToString (called FF_TO_STR) - * Code is same for cvtDoubleToString - * Marty Kraimer wrote cvtCharToString,cvtUcharToString - * cvtShortToString,cvtUshortToString, - * cvtLongToString, and cvtUlongToString - * Mark Anderson wrote cvtLongToHexString, cvtLongToOctalString, - * adopted cvt[Float/Double]ExpString and - * cvt[Float/Double]CompactString from fToEStr - * and fixed calls to gcvt - * - * Date: 12 January 1993 - * - * 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 mrk 12-09-92 Taken from dbAccess and made into library - * .02 mda 01-12-93 Add cvt[Float/Double]ToExpString, - * cvt[Float/Double]ToCompactString, - * cvtLongToHex, cvtLongToOctal routines, fix - * calls to gcvt, etc. - * .03 joh 03-30-93 added bit field extract/ insert routines - * .04 mrk 01-28-94 replaced gcvt by e conversion - * .05 mrk 05-06-95 changed ExpString routines to just use sprintf - * It had a bug and performance was not that much - * better (2-5 times) then sprintf. - * Also they are not used on vxWorks - */ - -#ifdef vxWorks -#include -#endif - -#include -#include -#include /* XPG2/XPG3/POSIX.1/FIPS151-1/ANSI-C */ - -#define epicsExportSharedSymbols -#include "cvtFast.h" - -/* - * This routine converts numbers less than 10,000,000. It defers to f_to_str for - * numbers requiring more than 8 places of precision. There are only eight decimal - */ -static long frac_multiplier[] = - {1,10,100,1000,10000,100000,1000000,10000000,100000000}; - -int epicsShareAPI cvtFloatToString( - float flt_value, - char *pstr_value, - unsigned short precision) -{ - unsigned short got_one,i; - long whole,iplace,number,fraction,fplace; - float ftemp; - char *startAddr; - - /* can this routine handle this conversion */ - if (precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) { - sprintf(pstr_value,"%12.5e",(double)flt_value); - return((int)strlen(pstr_value)); - } - startAddr = pstr_value; - - /* determine the sign */ - if (flt_value < 0){ - *pstr_value++ = '-'; - flt_value = -flt_value; - }; - - /* remove the whole number portion */ - whole = (long)flt_value; - ftemp = flt_value - whole; - - /* multiplier to convert fractional portion to integer */ - fplace = frac_multiplier[precision]; - fraction = (long)(ftemp * fplace * 10); - fraction = (fraction + 5) / 10; /* round up */ - - /* determine rounding into the whole number portion */ - if ((fraction / fplace) >= 1){ - whole++; - fraction -= fplace; - } - - /* whole numbers */ - got_one = 0; - for (iplace = 10000000; iplace >= 1; iplace /= 10){ - if (whole >= iplace){ - got_one = 1; - number = whole / iplace; - whole = whole - (number * iplace); - *pstr_value = number + '0'; - pstr_value++; - }else if (got_one){ - *pstr_value = '0'; - pstr_value++; - } - } - if (!got_one){ - *pstr_value = '0'; - pstr_value++; - } - - /* fraction */ - if (precision > 0){ - /* convert fractional portional to ASCII */ - *pstr_value = '.'; - pstr_value++; - for (fplace /= 10, i = precision; i > 0; fplace /= 10,i--){ - number = fraction / fplace; - fraction -= number * fplace; - *pstr_value = number + '0'; - pstr_value++; - } - } - *pstr_value = 0; - - return((int)(pstr_value - startAddr)); -} - -int epicsShareAPI cvtDoubleToString( - double flt_value, - char *pstr_value, - unsigned short precision) -{ - unsigned short got_one,i; - long whole,iplace,number,fraction,fplace; - double ftemp; - char *startAddr; - - /* can this routine handle this conversion */ - if (precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) { - if (precision > 8 || flt_value > 1e16 || flt_value < -1e16) { - if(precision>17) precision=17; - sprintf(pstr_value,"%*.*e",precision+7,precision, - flt_value); - } else { - if(precision>3) precision=3; - sprintf(pstr_value,"%.*f",precision,flt_value); - } - return((int)strlen(pstr_value)); - } - startAddr = pstr_value; - - /* determine the sign */ - if (flt_value < 0){ - *pstr_value++ = '-'; - flt_value = -flt_value; - }; - - /* remove the whole number portion */ - whole = (long)flt_value; - ftemp = flt_value - whole; - - /* multiplier to convert fractional portion to integer */ - fplace = frac_multiplier[precision]; - fraction = (long)(ftemp * fplace * 10); - fraction = (fraction + 5) / 10; /* round up */ - - /* determine rounding into the whole number portion */ - if ((fraction / fplace) >= 1){ - whole++; - fraction -= fplace; - } - - /* whole numbers */ - got_one = 0; - for (iplace = 10000000; iplace >= 1; iplace /= 10){ - if (whole >= iplace){ - got_one = 1; - number = whole / iplace; - whole = whole - (number * iplace); - *pstr_value = number + '0'; - pstr_value++; - }else if (got_one){ - *pstr_value = '0'; - pstr_value++; - } - } - if (!got_one){ - *pstr_value = '0'; - pstr_value++; - } - - /* fraction */ - if (precision > 0){ - /* convert fractional portional to ASCII */ - *pstr_value = '.'; - pstr_value++; - for (fplace /= 10, i = precision; i > 0; fplace /= 10,i--){ - number = fraction / fplace; - fraction -= number * fplace; - *pstr_value = number + '0'; - pstr_value++; - } - } - *pstr_value = 0; - - return((int)(pstr_value - startAddr)); -} - -/* - * cvtFloatToExpString - * - * converts floating point numbers to E-format NULL terminated strings - */ -int epicsShareAPI cvtFloatToExpString( - float f_value, - char *pstr_value, - unsigned short f_precision) -{ - /*sunos uses char*sprint as function prototype*/ - sprintf(pstr_value,"%.*e",(int)f_precision,(double)f_value); - return((int)strlen(pstr_value)); -} - -/* - * cvtFloatToCompactString - * - * Converts floating point numbers to %g format NULL terminated strings, - * resulting in the most "compact" expression of the value - * ("f" notation if 10-4 < |value| < 10+4, otherwise "e" notation) - */ -int epicsShareAPI cvtFloatToCompactString( - float f_value, - char *pstr_value, - unsigned short f_precision ) -{ - if ((f_value < 1.e4 && f_value > 1.e-4) || - (f_value > -1.e4 && f_value < -1.e-4) || f_value == 0.0) { - return(cvtFloatToString(f_value,pstr_value,f_precision)); - } else { - return(cvtFloatToExpString(f_value,pstr_value,f_precision)); - } -} - - - -/* - * cvtDoubleToExpString - * - * converts double precision floating point numbers to E-format NULL - * terminated strings - */ - -int epicsShareAPI cvtDoubleToExpString( - double f_value, - char *pstr_value, - unsigned short f_precision ) -{ - sprintf(pstr_value,"%.*e",(int)f_precision,f_value); - return((int)strlen(pstr_value)); -} - - -/* - * cvtDoubleToCompactString - * - * Converts double precision floating point numbers to %g format NULL - * terminated strings, resulting in the most "compact" expression - * of the value ("f" notation if 10-4 < |value| < 10+4, otherwise - * "e" notation) - */ -int epicsShareAPI cvtDoubleToCompactString( - double f_value, - char *pstr_value, - unsigned short f_precision ) -{ - if ((f_value < 1.e4 && f_value > 1.e-4) || - (f_value > -1.e4 && f_value < -1.e-4) || f_value == 0.0) { - return(cvtDoubleToString(f_value,pstr_value,f_precision)); - } else { - return(cvtDoubleToExpString(f_value,pstr_value,f_precision)); - } -} - -/* Convert various integer types to ascii */ - -static char digit_to_ascii[10]={'0','1','2','3','4','5','6','7','8','9'}; - -int epicsShareAPI cvtCharToString( - char source, - char *pdest) -{ - unsigned char val,temp; - char digit[3]; - int i,j; - char *startAddr = pdest; - - if(source==0) { - *pdest++ = '0'; - *pdest = 0; - return((int)(pdest-startAddr)); - } - if(source<0) { - if(source == CHAR_MIN) { - sprintf(pdest,"%d",CHAR_MIN); - return((int)strlen(pdest)); - } - *pdest++ = '-'; - source = -source; - } - val = source; - for(i=0; val!=0; i++) { - temp = val/10; - digit[i] = digit_to_ascii[val - temp*10]; - val = temp; - } - for(j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return((int)(pdest-startAddr)); -} - - -int epicsShareAPI cvtUcharToString( - unsigned char source, - char *pdest) -{ - unsigned char val,temp; - char digit[3]; - int i,j; - char *startAddr = pdest; - - if(source==0) { - *pdest++ = '0'; - *pdest = 0; - return((int)(pdest-startAddr)); - } - val = source; - for(i=0; val!=0; i++) { - temp = val/10; - digit[i] = digit_to_ascii[val - temp*10]; - val = temp; - } - for(j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return((int)(pdest-startAddr)); -} - - -int epicsShareAPI cvtShortToString( - short source, - char *pdest) -{ - short val,temp; - char digit[6]; - int i,j; - char *startAddr = pdest; - - if(source==0) { - *pdest++ = '0'; - *pdest = 0; - return((int)(pdest-startAddr)); - } - if(source<0) { - if(source == SHRT_MIN) { - sprintf(pdest,"%d",SHRT_MIN); - return((int)(strlen(pdest))); - } - *pdest++ = '-'; - source = -source; - } - val = source; - for(i=0; val!=0; i++) { - temp = val/10; - digit[i] = digit_to_ascii[val - temp*10]; - val = temp; - } - for(j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return((int)(pdest-startAddr)); -} - - -int epicsShareAPI cvtUshortToString( - unsigned short source, - char *pdest) -{ - unsigned short val,temp; - char digit[5]; - int i,j; - char *startAddr = pdest; - - if(source==0) { - *pdest++ = '0'; - *pdest = 0; - return((int)(pdest-startAddr)); - } - val = source; - for(i=0; val!=0; i++) { - temp = val/10; - digit[i] = digit_to_ascii[val - temp*10]; - val = temp; - } - for(j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return((int)(pdest-startAddr)); -} - - -int epicsShareAPI cvtLongToString( - long source, - char *pdest) -{ - long val,temp; - char digit[11]; - int i,j; - char *startAddr = pdest; - - if(source==0) { - *pdest++ = '0'; - *pdest = 0; - return((int)(pdest-startAddr)); - } - if(source<0) { - if(source == LONG_MIN) { - sprintf(pdest,"%ld",LONG_MIN); - return((int)strlen(pdest)); - } - *pdest++ = '-'; - source = -source; - } - val = source; - for(i=0; val!=0; i++) { - temp = val/10; - digit[i] = digit_to_ascii[val - temp*10]; - val = temp; - } - for(j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return((int)(pdest-startAddr)); -} - - -int epicsShareAPI cvtUlongToString( - unsigned long source, - char *pdest) -{ - unsigned long val,temp; - char digit[10]; - int i,j; - char *startAddr = pdest; - - if(source==0) { - *pdest++ = '0'; - *pdest = 0; - return((int)(pdest-startAddr)); - } - val = source; - for(i=0; val!=0; i++) { - temp = val/10; - digit[i] = digit_to_ascii[val - temp*10]; - val = temp; - } - for(j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return((int)(pdest-startAddr)); -} - - -/* Convert hex digits to ascii */ - -static char hex_digit_to_ascii[16]={'0','1','2','3','4','5','6','7','8','9', - 'a','b','c','d','e','f'}; - - -int epicsShareAPI cvtLongToHexString( - long source, - char *pdest) -{ - long val,temp; - char digit[10]; - int i,j; - char *startAddr = pdest; - - if(source==0) { - *pdest++ = '0'; - *pdest = 0; - return((int)(pdest-startAddr)); - } - if(source<0) { - if(source == LONG_MIN) { - sprintf(pdest,"%lx",LONG_MIN); - return((int)strlen(pdest)); - } - *pdest++ = '-'; - source = -source; - } - val = source; - for(i=0; val!=0; i++) { - temp = val/16; - digit[i] = hex_digit_to_ascii[val - temp*16]; - val = temp; - } - for(j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return((int)(pdest-startAddr)); -} - - -int epicsShareAPI cvtLongToOctalString( - long source, - char *pdest) -{ - long val,temp; - char digit[16]; - int i,j; - char *startAddr = pdest; - - if(source==0) { - *pdest++ = '0'; - *pdest = 0; - return((int)(pdest-startAddr)); - } - if(source<0) { - if(source == LONG_MIN) { - sprintf(pdest,"%lo",LONG_MIN); - return((int)strlen(pdest)); - } - *pdest++ = '-'; - source = -source; - } - val = source; - for(i=0; val!=0; i++) { - temp = val/8; - /* reuse digit_to_ascii since octal is a subset of decimal */ - digit[i] = digit_to_ascii[val - temp*8]; - val = temp; - } - for(j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return((int)(pdest-startAddr)); -} - - - - -/* - * - * cvtBitsToUlong() - * - * extract a bit field from the source unsigend long - */ -unsigned long epicsShareAPI cvtBitsToUlong( -unsigned long src, -unsigned bitFieldOffset, -unsigned bitFieldLength) -{ - unsigned long mask; - - src = src >> bitFieldOffset; - - mask = (1< - -#include "shareLib.h" - -#if defined(__STDC__) || defined(__cplusplus) - -/* - * each of these functions return the number of characters "transmitted" - * (as in ANSI-C/POSIX.1/XPG3 sprintf() functions) - */ -epicsShareFunc int epicsShareAPI - cvtFloatToString(float value, char *pstring, unsigned short precision); -epicsShareFunc int epicsShareAPI - cvtDoubleToString(double value, char *pstring, unsigned short precision); -epicsShareFunc int epicsShareAPI - cvtFloatToExpString(float value, char *pstring, unsigned short precision); -epicsShareFunc int epicsShareAPI - cvtDoubleToExpString(double value, char *pstring, unsigned short precision); -epicsShareFunc int epicsShareAPI - cvtFloatToCompactString(float value, char *pstring, unsigned short precision); -epicsShareFunc int epicsShareAPI - cvtDoubleToCompactString(double value, char *pstring, unsigned short precision); -epicsShareFunc int epicsShareAPI - cvtCharToString(char value, char *pstring); -epicsShareFunc int epicsShareAPI - cvtUcharToString(unsigned char value, char *pstring); -epicsShareFunc int epicsShareAPI - cvtShortToString(short value, char *pstring); -epicsShareFunc int epicsShareAPI - cvtUshortToString(unsigned short value, char *pstring); -epicsShareFunc int epicsShareAPI - cvtLongToString(long value, char *pstring); -epicsShareFunc int epicsShareAPI - cvtUlongToString(unsigned long value, char *pstring); -epicsShareFunc int epicsShareAPI - cvtLongToHexString(long value, char *pstring); -epicsShareFunc int epicsShareAPI - cvtLongToOctalString(long value, char *pstring); -epicsShareFunc unsigned long epicsShareAPI cvtBitsToUlong( - unsigned long src, - unsigned bitFieldOffset, - unsigned bitFieldLength); -epicsShareFunc unsigned long epicsShareAPI cvtUlongToBits( - unsigned long src, - unsigned long dest, - unsigned bitFieldOffset, - unsigned bitFieldLength); - -#else /*__STDC__*/ - -epicsShareFunc int epicsShareAPI cvtFloatToString(); -epicsShareFunc int epicsShareAPI cvtDoubleToString(); -epicsShareFunc int epicsShareAPI cvtFloatToExpString(); -epicsShareFunc int epicsShareAPI cvtDoubleToExpString(); -epicsShareFunc int epicsShareAPI cvtFloatToCompactString(); -epicsShareFunc int epicsShareAPI cvtDoubleToCompactString(); -epicsShareFunc int epicsShareAPI cvtCharToString(); -epicsShareFunc int epicsShareAPI cvtUcharToString(); -epicsShareFunc int epicsShareAPI cvtShortToString(); -epicsShareFunc int epicsShareAPI cvtUshortToString(); -epicsShareFunc int epicsShareAPI cvtLongToString(); -epicsShareFunc int epicsShareAPI cvtUlongToString(); -epicsShareFunc int epicsShareAPI cvtLongToHexString(); -epicsShareFunc int epicsShareAPI cvtLongToOctalString(); -epicsShareFunc unsigned long epicsShareAPI cvtBitsToUlong(); -epicsShareFunc unsigned long epicsShareAPI cvtUlongToBits(); - -#endif /*__STDC__*/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCcvtFasth*/ diff --git a/src/libCom/cvtNumbers.c b/src/libCom/cvtNumbers.c deleted file mode 100644 index 8ca51eeb1..000000000 --- a/src/libCom/cvtNumbers.c +++ /dev/null @@ -1,397 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: unknown - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1992, 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 unknown rac initial version, cloned from WETF code - * .02 02-19-92 rac added proper treatment for fractional values - * and printing for integers - * .03 03-09-92 rac fix bug where decPl was sometimes ignored - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE cvtNumbers.c - convert numeric to text -* -* DESCRIPTION -* These routines provide service to convert numeric values to text -* form. -* -* QUICK REFERENCE -* int cvtDblToTxt( text, width, dblVal, decPl ) -* int cvtLngToTxt( text, width, lngVal ) -* -* -*-***************************************************************************/ -#ifdef vxWorks -# include -# include -#else -# include -# include -#endif - -#include - - -#ifdef vxWorks -# define nint(value) (value>=0 ? (int)((value)+.5) : (int)((value)-.5)) -# define exp10(value) (exp(value * log(10.))) -#else -/* really nint and exp10 aren't ANSI-C or POSIX */ -# ifndef sun -# define nint(value) (value>=0 ? (int)((value)+.5) : (int)((value)-.5)) -# define exp10(value) (exp(value * log(10.))) -# endif -#endif - -#if 0 -main() -{ - float x, y; - char text[100]; - int i, iter; - int xi, yi; - - for (x=.000123; x<1000; x*=10.) { - printf("%10.5f", x); - for (i=1; i<10; i++) { - cvtDblToTxt(text, i, x, 3); - printf(" %s", text); - } - printf("\n"); - y = -1. * x; - printf("%10.5f", y); - for (i=1; i<10; i++) { - cvtDblToTxt(text, i, y, 3); - printf(" %s", text); - } - printf("\n"); - } - for (iter=1,xi=0; iter<=12; iter++,xi+=xi*10+xi+1) { - printf("%12d", xi); - for (i=1; i<=iter; i++) { - cvtLngToTxt(text, i, xi); - printf(" %s", text); - } - printf("\n"); - yi = -1 * xi; - printf("%12d", yi); - for (i=1; i<=iter+1; i++) { - cvtLngToTxt(text, i, yi); - printf(" %s", text); - } - printf("\n"); - } -} -#endif - -/*+/subr********************************************************************** -* NAME cvtDblToTxt - convert double to text, being STINGY with space -* -* DESCRIPTION -* Convert a double value to text. The main usefulness of this routine -* is that it maximizes the amount of information presented in a -* minimum number of characters. For example, if a 1 column width -* is specified, only the sign of the value is presented. -* -* When an exponent is needed to represent the value, for narrow -* column widths only the exponent appears. If there isn't room -* even for the exponent, large positive exponents will appear as E*, -* and large negative exponents will appear as E-. -* -* Negative numbers receive some special treatment. In narrow -* columns, very large negative numbers may be represented as - and -* very small negative numbers may be represented as -. or -.E- . -* -* Some example outputs follow (with 3 decimal places assumed): -* -* value printed values for column widths -* 1 2 3 4 5 6 -* -* 0.000 0 0 0 0 0 0 -* -1.000 - -1 -1 -1 -1 -1 -* 0.123 + E- .12 .123 .123 .123 -* -0.00123 - -. -. -.E- -.001 -.001 -* -12.3 - - -12 -12 -12.3 -12.30 -* 123 + E2 123 123 123.0 123.00 -* -*-*/ -cvtDblToTxt(text, width, value, decPl) -char *text; /* O text representation of value */ -int width; /* I max width of text string (not counting '\0') */ -double value; /* I value to print */ -int decPl; /* I max # of dec places to print */ -{ - double valAbs; /* absolute value of caller's value */ - int wholeNdig; /* number of digits in "whole" part of value */ - double logVal; /* log10 of value */ - int decPlaces; /* number of decimal places to print */ - int expI; /* exponent for frac values */ - double expD; - int expWidth; /* width needed for exponent field */ - int excess; /* number of low order digits which - won't fit into the field */ - char tempText[100]; /* temp for fractional conversions */ - int roomFor; - int minusWidth; /* amount of room for - sign--0 or 1 */ - -/*----------------------------------------------------------------------------- -* special cases -*----------------------------------------------------------------------------*/ - if (value == 0.) { - (void)strcpy(text, "0"); - return; - } - else if (value == 1.) { - (void)strcpy(text, "1"); - return; - } - if (width == 1) { - if (value >= 0) - strcpy(text, "+"); - else - strcpy(text, "-"); - return; - } - else if (width == 2 && value <= -1.) { - if (value == -1.) - strcpy(text, "-1"); - else - strcpy(text, "-"); - return; - } - - valAbs = value>0. ? value : -value; - logVal = log10(valAbs); - if (logVal < 0.) { -/*----------------------------------------------------------------------------- -* numbers with only a fractional part -*----------------------------------------------------------------------------*/ - if (width == 2) { - if (value > 0.) - strcpy(tempText, "0E-"); - else - strcpy(tempText, "0-."); - } - else if (width == 3 && value < 0) - strcpy(tempText, "0-."); - else { - if (value < 0.) - minusWidth = 1; - else - minusWidth = 0; - expI = -1 * (int)logVal; - if (expI < 9) - expWidth = 3; /* need E-n */ - else if (expI < 99) - expWidth = 4; /* need E-nn */ - else if (expI < 999) - expWidth = 5; /* need E-nnn */ - else - expWidth = 6; /* need E-nnnn */ - /* figure out how many sig digit can appear if print "as is" */ - /* expI is the number of leading zeros */ - roomFor = width - expI - 1 - minusWidth; /* -1 for the dot */ - if (roomFor >= 1) { - decPlaces = expI + decPl; - if (decPlaces > width -1 - minusWidth) - decPlaces = roomFor + expI; - if (decPlaces > decPl) - decPlaces = decPl; - (void)sprintf(tempText, "%.*f", decPlaces, value); - if (value < 0.) - tempText[1] = '-'; - } - else { - expD = expI; - value *= exp10(expD); - if (value > 0.) - sprintf(tempText, "0.E-%d", expI); - else - sprintf(tempText, "--.E-%d", expI); - } - } - - strncpy(text, &tempText[1], width); - text[width] = '\0'; - return; - } - -/*----------------------------------------------------------------------------- -* numbers with both an integer and a fractional part -* -* find out how many columns are required to represent the integer part -* of the value. A - is counted as a column; the . isn't. -*----------------------------------------------------------------------------*/ - wholeNdig = 1 + (int)logVal; - if (value < 0.) - wholeNdig++; - if (wholeNdig < width-1) { -/*----------------------------------------------------------------------------- -* the integer part fits well within the field. Find out how many -* decimal places can be printed (honoring caller's decPl limit). -*----------------------------------------------------------------------------*/ - decPlaces = width - wholeNdig - 1; - if (decPl < decPlaces) - decPlaces = decPl; - if (decPl > 0) - (void)sprintf(text, "%.*f", decPlaces, value); - else - (void)sprintf(text, "%d", nint(value)); - } - else if (wholeNdig == width || wholeNdig == width-1) { -/*----------------------------------------------------------------------------- -* The integer part just fits within the field. Print the value as an -* integer, without printing the superfluous decimal point. -*----------------------------------------------------------------------------*/ - (void)sprintf(text, "%d", nint(value)); - } - else { -/*----------------------------------------------------------------------------- -* The integer part is too large to fit within the caller's field. Print -* with an abbreviated E notation. -*----------------------------------------------------------------------------*/ - expWidth = 2; /* assume that En will work */ - excess = wholeNdig - (width - 2); - if (excess > 999) { - expWidth = 5; /* no! it must be Ennnn */ - excess += 3; - } - else if (excess > 99) { - expWidth = 4; /* no! it must be Ennn */ - excess += 2; - } - else if (excess > 9) { - expWidth = 3; /* no! it must be Enn */ - excess += 1; - } -/*----------------------------------------------------------------------------- -* Four progressively worse cases, with all or part of exponent fitting -* into field, but not enough room for any of the value -* Ennn positive value; exponent fits -* -Ennn negative value; exponent fits -* +**** positive value; exponent too big -* -**** negative value; exponent too big -*----------------------------------------------------------------------------*/ - if (value >= 0. && expWidth == width) - (void)sprintf(text, "E%d", nint(logVal)); - else if (value < 0. && expWidth == width-1) - (void)sprintf(text, "-E%d", nint(logVal)); - else if (value > 0. && expWidth > width) - (void)sprintf(text, "%.*s", width, "+*******"); - else if (value < 0. && expWidth > width-1) - (void)sprintf(text, "%.*s", width, "-*******"); - else { -/*----------------------------------------------------------------------------- -* The value can fit, in exponential notation -*----------------------------------------------------------------------------*/ - (void)sprintf(text, "%dE%d", - nint(value/exp10((double)excess)), excess); - } - } -} - -/*+/subr********************************************************************** -* NAME cvtLngToTxt - convert long to text, being STINGY with space -* -* DESCRIPTION -* Convert a long value to text. The main usefulness of this routine -* is that it maximizes the amount of information presented in a -* minimum number of characters. For example, if a 1 column width -* is specified, only the sign of the value is presented. -* -* When an exponent is needed to represent the value, for narrow -* column widths only the exponent appears. If there isn't room -* even for the exponent, large positive exponents will appear as E*. -* -* Negative numbers receive some special treatment. In narrow -* columns, very large negative numbers may be represented as - . -* -* Some example outputs follow: -* -* value printed values for column widths -* 1 2 3 4 5 6 -* -* 0 0 0 0 0 0 0 -* -1 - -1 -1 -1 -1 -1 -* 271453 + E5 2E5 27E4 271E3 271453 -* -22621 - - -E4 -2E4 -22E3 - 22621 -* -*-*/ -cvtLngToTxt(text, width, value) -char *text; /* O text representation of value */ -int width; /* I max width of text string (not counting '\0') */ -long value; /* I value to print */ -{ - char Text[100]; - int nDig, expWidth, expVal, sNcol; - - assert(width > 0); - - sprintf(Text, "%d", value); - if ((nDig = strlen(Text)) <= width) { - strcpy(text, Text); - return; - } - if (width == 1) { - if (value > 0) - strcpy(text, "+"); - else - strcpy(text, "-"); - return; - } - if (width == 2 && value < 0) { - strcpy(text, "-"); - return; - } - if (value < 0) - sNcol = 1; - else - sNcol = 0; - expVal = nDig - width + 2; - if (expVal <= 9) { - if (width-sNcol == 2) - expVal--; - sprintf(&Text[width-2], "E%d", expVal); - } - else { - expVal++; - if (width-sNcol == 2) - sprintf(&Text[sNcol], "E*"); - else { - if (width-sNcol == 3) - expVal--; - sprintf(&Text[width-3], "E%d", expVal); - } - } - strcpy(text, Text); - - return; -} diff --git a/src/libCom/cxxTemplates/README b/src/libCom/cxxTemplates/README deleted file mode 100644 index 566497b6a..000000000 --- a/src/libCom/cxxTemplates/README +++ /dev/null @@ -1,56 +0,0 @@ - -C++ templates: -tsSLList.h - type safe single linked list template -tsDLList.h - type safe double linked list template -resourceLib.h - hash table template - -the test subdir contains examples - -Since I am using templates the linked lists are type safe -(no casting of pointers ala ellList and dllList). -Also, the node class in embedded in the item on the -list (more efficent use of pool). - -The file resourceLib.h provides a core hashing library -"resTable " where "itemClass" objects -are stored in the hash table and "idClass" is the data type -of the key for the hash table. The identifier class provides -the hash alg. I have provided simple string "stringId" and -unsigned integer "uintId" key types in resourceLib.h. It -is easy to implement a new key class. - -There are examples under cxxTemplate/test. The list/hashing -templates all depend on a particular inheritance hierarchy. -If the inheritance hierarchy is wrong nothing will compile. -For instance, in tsDLList.h the template data type "T" -must derive from tsDLNode. Likewise, in tsSLList.h -"T" must derive from tsSLNode. Likewise, in resourceLib.h -class "T" (the type stored in the hash table) must derive -from class "ID" (the hash table key type) and also derive from -tsSLNode. - -So far, the only confusion I have run into with templates has been: - -1) strange compiler messages - unrelated to cause of course - -when I get the class declaration order wrong (so that the -compiler has trouble instantiating the template). - -2) sun pro/dec/att compilers use a template database and -gnu/msvc++ compilers use explicit template instantiation. -Therefore blocks of code of this sort are required: - -#include "resourceLib.h" // template def -#include "resourceLib.cc" // template functions (that are not inline) -#if defined (EXPL_TEMPL) - // - // From Stroustrups's "The C++ Programming Language" - // Appendix A: r.14.9 - // - // This explicitly instantiates the template class's member - // functions into "templInst.o" - // - template class resTable; - template class resTable; -#endif - - diff --git a/src/libCom/cxxTemplates/resourceLib.h b/src/libCom/cxxTemplates/resourceLib.h deleted file mode 100644 index 219d1d93d..000000000 --- a/src/libCom/cxxTemplates/resourceLib.h +++ /dev/null @@ -1,787 +0,0 @@ -/* - * $Id$ - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - * 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 - * - * - * History - * $Log$ - * Revision 1.18 1998/10/23 00:20:40 jhill - * attempted to clean up HP-UX warnings - * - * Revision 1.17 1998/06/16 03:00:19 jhill - * cleaned up fast string hash table - * - * Revision 1.16 1998/04/10 23:07:33 jhill - * fixed solaris architecture specific problem where xxx>>32 was ignored - * - * Revision 1.15 1998/02/05 23:25:19 jhill - * workaround vis c++ 5.0 bug - * - * Revision 1.14 1997/08/05 00:53:02 jhill - * changed some inline func to normal func - * - * Revision 1.13 1997/06/30 18:16:13 jhill - * guess at DEC C++ compiler bug workaround - * - * Revision 1.12 1997/06/25 05:48:39 jhill - * moved resourceLib.cc into resourceLib.h - * - * Revision 1.11 1997/06/13 18:26:13 jhill - * allow epicsAssert.h - * - * Revision 1.10 1997/06/13 09:21:51 jhill - * fixed compiler compatibility problems - * - * Revision 1.9 1997/04/23 17:11:15 jhill - * stringId::T[] => stringIdFastHash[] - * - * Revision 1.8 1997/04/10 19:43:09 jhill - * API changes - * - * Revision 1.7 1996/12/06 22:26:36 jhill - * added auto cleanup of installed classes to destroy - * - * Revision 1.6 1996/11/02 01:07:17 jhill - * many improvements - * - * Revision 1.5 1996/09/04 19:57:06 jhill - * string id resource now copies id - * - * Revision 1.4 1996/08/05 19:31:59 jhill - * fixed removes use of iter.cur() - * - * Revision 1.3 1996/07/25 17:58:16 jhill - * fixed missing ref in list decl - * - * Revision 1.2 1996/07/24 22:12:02 jhill - * added remove() to iter class + made node's prev/next private - * - * Revision 1.1.1.1 1996/06/20 22:15:55 jhill - * installed ca server templates - * - * - * NOTES: - * .01 Storage for identifier must persist until an item is deleted - * .02 class T must derive from class ID and tsSLNode - * - * DESIGN NOTES: - * .01 These routines could be made to be significantly faster if the - * size of the hash table was a template parameter, and therefore - * known at compile time. However, there are many applications where - * the size of the hash table must be read in from a file or otherwise - * determined at runtime. The author does not see an easy way to - * provide both compile time and runtime determined hash table - * size without providing two nearly identical versions of these - * routines, and so has provided only runtime determined hash table - * size capabilities. - * - */ - -#ifndef INCresourceLibh -#define INCresourceLibh - -#include -#include -#include -#include -#ifndef assert // allow use of epicsAssert.h -#include -#endif - -#include "tsSLList.h" -#include "shareLib.h" - -typedef int resLibStatus; -typedef unsigned resTableIndex; - -#define resTableIndexBitWidth (sizeof(resTableIndex)*CHAR_BIT) - -// -// class T must derive from class ID and also from class tsSLNode -// -// NOTE: Classes installed into this table should have -// a virtual destructor so that the delete in ~resTable() will -// work correctly. -// -template -class resTable { -public: - resTable() : - pTable(0), hashIdMask(0), hashIdNBits(0), nInUse(0) {} - - int init(unsigned nHashTableEntries); - - virtual ~resTable(); - - // - // destroy all res in the table - // - void destroyAllEntries(); - - // - // call T::show(level) for each res in the table - // - void show (unsigned level) const; - - // - // add a res to the table - // - int add (T &res); - - // - // remove a res from the table - // - T *remove (const ID &idIn) - { - tsSLList &list = this->pTable[this->hash(idIn)]; - return this->findDelete(list, idIn); - } - - - // - // find an res in the table - // - T *lookup (const ID &idIn) - { - tsSLList &list = this->pTable[this->hash(idIn)]; - return this->find(list, idIn); - } - -#ifdef _MSC_VER - // - // required by MS vis c++ 5.0 (but not by 4.0) - // - typedef void (T::*pResTableMFArg_t)(); -# define pResTableMFArg(ARG) pResTableMFArg_t ARG -#else - // - // required by gnu g++ 2.7.2 - // -# define pResTableMFArg(ARG) void (T:: * ARG)() -#endif - - // - // Call (pT->*pCB) () for each item in the table - // - // where pT is a pointer to type T and pCB is - // a pointer to a memmber function of T with - // no parameters that returns void - // - void traverse(pResTableMFArg(pCB)); - -private: - tsSLList *pTable; - unsigned hashIdMask; - unsigned hashIdNBits; - unsigned nInUse; - - resTableIndex hash(const ID & idIn) - { - return idIn.resourceHash(this->hashIdNBits) - & this->hashIdMask; - } - - // - // find - // searches from where the iterator points to the - // end of the list for idIn - // - // iterator points to the item found upon return - // (or NULL if nothing matching was found) - // - T *find (tsSLList &list, const ID &idIn); - - // - // findDelete - // searches from where the iterator points to the - // end of the list for idIn - // - // iterator points to the item found upon return - // (or NULL if nothing matching was found) - // - // removes the item if it finds it - // - T *findDelete (tsSLList &list, const ID &idIn); -}; - -// -// Some ID classes that work with the above template -// - - -// -// unsigned identifier -// -class epicsShareClass uintId { -public: - uintId (unsigned idIn=UINT_MAX) : id(idIn) {} - virtual ~uintId(); - - int operator == (const uintId &idIn) - { - return this->id == idIn.id; - } - - // - // uintId::resourceHash() - // - resTableIndex resourceHash(unsigned nBitsId) const; - - const unsigned getId() const - { - return id; - } -protected: - unsigned id; -}; - - -// -// special resource table which uses -// unsigned integer keys allocated in chronological sequence -// -// NOTE: ITEM must public inherit from uintRes -// -template -class uintResTable : public resTable { -public: - uintResTable() : allocId(1u) {} // hashing is faster close to zero - virtual ~uintResTable(); - - inline void installItem(ITEM &item); -private: - unsigned allocId; -}; - -// -// resource with unsigned chronological identifier -// -template -class uintRes : public uintId, public tsSLNode { -friend class uintResTable; -public: - uintRes(unsigned idIn=UINT_MAX) : uintId(idIn) {} - virtual ~uintRes(); -private: - // - // workaround for bug in DEC compiler - // - void setId(unsigned newId) {this->id = newId;} -}; - - -// -// character string identifier -// -// NOTE: to be robust in situations where the new() -// in the constructor might fail a careful consumer -// of this class should check to see if the -// stringId::resourceName() below -// returns a valid (non--NULL) string pointer. -// Eventually an exception will be thrown if -// new fails (when this is portable). -// -class epicsShareClass stringId { -public: - enum allocationType {copyString, refString}; - - // - // allocCopyString() - // - static inline char * allocCopyString(const char * const pStr) - { - char *pNewStr = new char [strlen(pStr)+1u]; - if (pNewStr) { - strcpy (pNewStr, pStr); - } - return pNewStr; - } - - // - // stringId() constructor - // - // Use typeIn==refString only if the string passed in will exist - // and remain constant during the entire lifespan of the stringId - // object. - // - stringId (char const * const idIn, allocationType typeIn=copyString) : - pStr(typeIn==copyString?allocCopyString(idIn):idIn), - allocType(typeIn) {} - - virtual ~ stringId(); - - // - // The hash algorithm is a modification of the algorithm described in - // Fast Hashing of Variable Length Text Strings, Peter K. Pearson, - // Communications of the ACM, June 1990 - // The modifications were designed by Marty Kraimer - // - resTableIndex resourceHash(unsigned nBitsId) const; - - int operator == (const stringId &idIn) - { - if (this->pStr!=NULL && idIn.pStr!=NULL) { - return strcmp(this->pStr,idIn.pStr)==0; - } - else { - return 0u; // not equal - } - } - - // - // return the pointer to the string - // (also used to test to see if "new()" - // failed in the constructor - // - const char * resourceName() - { - return this->pStr; - } - - void show (unsigned level) const - { - if (level>2u) { - printf ("resource id = %s\n", this->pStr); - } - } -private: - const char * const pStr; - allocationType const allocType; - static const unsigned char stringIdFastHash[256]; -}; - -// -// resTable::init() -// -template -int resTable::init(unsigned nHashTableEntries) -{ - unsigned nbits; - - if (nHashTableEntries<1u) { - return -1; - } - - // - // count the number of bits in the hash index - // - for (nbits=0; nbitshashIdMask = (1<hashIdMask) == 0){ - break; - } - } - this->hashIdNBits = nbits; - this->nInUse = 0u; - this->pTable = new tsSLList [this->hashIdMask+1u]; - if (!pTable) { - return -1; - } - return 0; -} - -// -// resTable::destroyAllEntries() -// -template -void resTable::destroyAllEntries() -{ - tsSLList *pList = this->pTable; - - while (pList<&this->pTable[this->hashIdMask+1]) { - T *pItem; - T *pNextItem; - - { - tsSLIter iter(*pList); - pItem = iter(); - while (pItem) { - pNextItem = iter(); - pItem->destroy(); - pItem = pNextItem; - } - } - - // - // Check to see if a defective class is - // installed that does not remove itself - // from the table when it is destroyed. - // - { - tsSLIterRm iter(*pList); - while ( (pItem=iter()) ) { - fprintf(stderr, -"Warning: Defective class still in resTable after it was destroyed\n"); - // - // remove defective class - // - iter.remove(); - this->nInUse--; - } - } - - pList++; - } -} - -// -// resTable::show -// -template -void resTable::show (unsigned level) const -{ - tsSLList *pList; - double X; - double XX; - double mean; - double stdDev; - unsigned maxEntries; - - printf("resTable with %d resources installed\n", this->nInUse); - - if (level >=1u) { - pList = this->pTable; - X = 0.0; - XX = 0.0; - maxEntries = 0u; - while (pList < &this->pTable[this->hashIdMask+1]) { - unsigned count; - tsSLIter iter(*pList); - T *pItem; - - count = 0; - while ( (pItem = iter()) ) { - if (level >= 3u) { - pItem->show (level); - } - count++; - } - if (count>0u) { - X += count; - XX += count*count; - if (count>maxEntries) { - maxEntries = count; - } - } - pList++; - } - - mean = X/(this->hashIdMask+1); - stdDev = sqrt(XX/(this->hashIdMask+1) - mean*mean); - printf( - "entries/occupied table entry - mean = %f std dev = %f max = %d\n", - mean, stdDev, maxEntries); - } -} - -// -// resTable::traverse -// -template -void resTable::traverse (pResTableMFArg(pCB)) -{ - tsSLList *pList; - - pList = this->pTable; - while (pList < &this->pTable[this->hashIdMask+1]) { - tsSLIter iter(*pList); - T *pItem; - - while ( (pItem = iter()) ) { - (pItem->*pCB) (); - } - pList++; - } -} - -// -// add a res to the table -// -template -int resTable::add (T &res) -{ - // - // T must derive from ID - // - tsSLList &list = this->pTable[this->hash(res)]; - - if (this->find(list, res) != 0) { - return -1; - } - list.add(res); - this->nInUse++; - return 0; -} - -// -// find -// searches from where the iterator points to the -// end of the list for idIn -// -// iterator points to the item found upon return -// (or NULL if nothing matching was found) -// -template -T *resTable::find (tsSLList &list, const ID &idIn) -{ - tsSLIter iter(list); - T *pItem; - ID *pId; - - while ( (pItem = iter()) ) { - pId = pItem; - if (*pId == idIn) { - break; - } - } - return pItem; -} - -// -// findDelete -// searches from where the iterator points to the -// end of the list for idIn -// -// iterator points to the item found upon return -// (or NULL if nothing matching was found) -// -// removes the item if it finds it -// -template -T *resTable::findDelete (tsSLList &list, const ID &idIn) -{ - tsSLIterRm iter(list); - T *pItem; - ID *pId; - - while ( (pItem = iter()) ) { - pId = pItem; - if (*pId == idIn) { - iter.remove(); - this->nInUse--; - break; - } - } - return pItem; -} - -// -// ~resTable::resTable() -// -template -resTable::~resTable() -{ - if (this->pTable) { - this->destroyAllEntries(); - assert (this->nInUse == 0u); - delete [] this->pTable; - } -} - -// -// uintResTable::~uintResTable() -// (not inline because it is virtual) -// -template -uintResTable::~uintResTable() {} - -// -// uintRes::~uintRes() -// (not inline because it is virtual) -// -template -uintRes::~uintRes() {} - -// -// this needs to be instanciated only once (normally in libCom) -// -#ifdef instantiateRecourceLib -// -// uintId::resourceHash() -// -resTableIndex uintId::resourceHash(unsigned /* nBitsId */) const -{ - resTableIndex hashid = this->id; - - // - // This assumes worst case hash table index width of 1 bit. - // We will iterate this loop 5 times on a 32 bit architecture. - // - // A good optimizer will unroll this loop? - // Experiments using the microsoft compiler show that this isnt - // slower than switching on the architecture size and urolling the - // loop explicitly (that solution has resulted in portability - // problems in the past). - // - for (unsigned i=(CHAR_BIT*sizeof(unsigned))/2u; i>0u; i >>= 1u) { - hashid ^= (hashid>>i); - } - - // - // the result here is always masked to the - // proper size after it is returned to the resource class - // - return hashid; -} - -// -// uintResTable::~uintResTable() -// (not inline because it is virtual) -// -uintId::~uintId() {} - -#endif // instantiateRecourceLib - -// -// uintRes::installItem() -// -// NOTE: This detects (and avoids) the case where -// the PV id wraps around and we attempt to have two -// resources with the same id. -// -template -inline void uintResTable::installItem(ITEM &item) -{ - int resTblStatus; - do { - item.uintRes::setId(allocId++); - resTblStatus = this->add(item); - } - while (resTblStatus); -} - -// -// stringId::~stringId() -// -// -// this needs to be instanciated only once (normally in libCom) -// -#ifdef instantiateRecourceLib -stringId::~stringId() -{ - if (this->allocType==copyString) { - if (this->pStr!=NULL) { - // - // the microsoft and solaris compilers will - // not allow a pointer to "const char" - // to be deleted - // - // the HP-UX compiler gives us a warning on - // each cast away of const, but in this case - // it cant be avoided - // - // I hope that deleting a pointer to "char" - // is the same as deleting a pointer to - // "const char" on all compilers - // - delete [] (char * const) this->pStr; - } - } -} -#endif // instantiateRecourceLib - -// -// this needs to be instanciated only once (normally in libCom) -// -#ifdef instantiateRecourceLib -// -// stringId::resourceHash() -// -// The hash algorithm is a modification of the algorithm described in -// Fast Hashing of Variable Length Text Strings, Peter K. Pearson, -// Communications of the ACM, June 1990 -// The modifications were designed by Marty Kraimer -// -resTableIndex stringId::resourceHash(unsigned nBitsId) const -{ - if (this->pStr==NULL) { - return 0u; - } - - unsigned h0 = 0u; - unsigned h1 = 0u; - unsigned c; - unsigned i; - for (i=0u; (c = this->pStr[i]); i++) { - // - // odd - // - if (i&1u) { - h1 = stringIdFastHash[h1 ^ c]; - } - // - // even - // - else { - h0 = stringIdFastHash[h0 ^ c]; - } - } - - // - // does not work well for more than 65k entries ? - // (because some indexes in the table will not be produced) - // - if (nBitsId>=8u) { - h1 = h1 << (nBitsId-8u); - } - return h1 ^ h0; -} -#endif // instantiateRecourceLib - -// -// this needs to be instanciated only once (normally in libCom) -// -#ifdef instantiateRecourceLib -// -// The hash algorithm is a modification of the algorithm described in -// Fast Hashing of Variable Length Text Strings, Peter K. Pearson, -// Communications of the ACM, June 1990 -// The modifications were designed by Marty Kraimer -// -const unsigned char stringId::stringIdFastHash[256] = { - 39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69, -157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160, -176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77, - 75,107,169,138,195,184, 70, 90, 61,166, 7,244,165,108,219, 51, - 9,139,209, 40, 31,202, 58,179,116, 33,207,146, 76, 60,242,124, -254,197, 80,167,153,145,129,233,132, 48,246, 86,156,177, 36,187, - 45, 1, 96, 18, 19, 62,185,234, 99, 16,218, 95,128,224,123,253, - 42,109, 4,247, 72, 5,151,136, 0,152,148,127,204,133, 17, 14, -182,217, 54,199,119,174, 82, 57,215, 41,114,208,206,110,239, 23, -189, 15, 3, 22,188, 79,113,172, 28, 2,222, 21,251,225,237,105, -102, 32, 56,181,126, 83,230, 53,158, 52, 59,213,118,100, 67,142, -220,170,144,115,205, 26,125,168,249, 66,175, 97,255, 92,229, 91, -214,236,178,243, 46, 44,201,250,135,186,150,221,163,216,162, 43, - 11,101, 34, 37,194, 25, 50, 12, 87,198,173,240,193,171,143,231, -111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238, -134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47 -}; - -#endif // instantiateRecourceLib - -#endif // INCresourceLibh - diff --git a/src/libCom/cxxTemplates/test/Makefile b/src/libCom/cxxTemplates/test/Makefile deleted file mode 100644 index 19351fe2b..000000000 --- a/src/libCom/cxxTemplates/test/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -TOP=../../.. - -include $(TOP)/config/CONFIG_BASE - -include $(TOP)/config/RULES_ARCHS - diff --git a/src/libCom/cxxTemplates/test/minmaxTest.cc b/src/libCom/cxxTemplates/test/minmaxTest.cc deleted file mode 100644 index aa9d4b342..000000000 --- a/src/libCom/cxxTemplates/test/minmaxTest.cc +++ /dev/null @@ -1,30 +0,0 @@ - -#include - -#include "tsMinMax.h" - -int main () -{ - float f1 = 3.3f; - float f2 = 3.4f; - float f3; - - f3 = tsMin(f1,f2); - assert(f3==f1); - - f3 = tsMax(f1,f2); - assert(f3==f2); - - int i1 = 3; - int i2 = 4; - int i3; - - i3 = tsMin(i1,i2); - assert(i3==i1); - - i3 = tsMax(i1,i2); - assert(i3==i2); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/resourceLibTest.cc b/src/libCom/cxxTemplates/test/resourceLibTest.cc deleted file mode 100644 index 9d83b3e28..000000000 --- a/src/libCom/cxxTemplates/test/resourceLibTest.cc +++ /dev/null @@ -1,254 +0,0 @@ - - -#include -#include -#include -#include - -#define INSTANCIATE_RES_LIB_STATIC -#include "resourceLib.h" - -#ifdef SUNOS4 -#ifndef CLOCKS_PER_SEC -#define CLOCKS_PER_SEC 1000000 -#endif -#endif - -void empty(); - -class albert : public uintId, public tsSLNode { -public: - albert (resTable &atIn, unsigned idIn) : - at(atIn), uintId(idIn) {} - void show (unsigned level) - { - } - void destroy() - { - at.remove(*this); - delete this; - } -private: - resTable &at; -}; - -class fred : public uintId, public tsSLNode { -public: - fred (const char *pNameIn, unsigned idIn) : - pName(pNameIn), uintId(idIn) {} - void show (unsigned) - { - printf("fred %s\n", pName); - } - void destroy() - { - // always on stack so noop - } -private: - const char * const pName; -}; - -class jane : public stringId, public tsSLNode { -public: - jane (const char *pNameIn) : stringId(pNameIn) {} - - void testTraverse(); - - void destroy() - { - // always on stack so noop - } -}; - -// -// jane::testTraverse() -// -void jane::testTraverse() -{ - printf("Traverse Test\n"); - this->show(10); -} - -// -// explicitly instantiates on compilers that support this -// -#if defined(EXPL_TEMPL) - // - // From Stroustrups's "The C++ Programming Language" - // Appendix A: r.14.9 - // - // This explicitly instantiates the template class's member - // functions into "templInst.o" - // - template class resTable; - template class resTable; -#endif - -main() -{ - unsigned i; - clock_t start, finish; - double duration; - const int LOOPS = 50000; - resTable intTbl; - resTable strTbl; - fred fred1("fred1",0x1000a432); - fred fred2("fred2",0x0000a432); - jane jane1("rrrrrrrrrrrrrrrrrrrrrrrrrr1"); - jane jane2("rrrrrrrrrrrrrrrrrrrrrrrrrr2"); - fred *pFred; - jane *pJane; - uintId uintId1(0x1000a432); - uintId uintId2(0x0000a432); - stringId strId1("rrrrrrrrrrrrrrrrrrrrrrrrrr1"); - stringId strId2("rrrrrrrrrrrrrrrrrrrrrrrrrr2"); - int status; - - status = intTbl.init(8); - if (status) { - return -1; - } - - status = intTbl.add(fred1); - assert (!status); - status = intTbl.add(fred2); - assert (!status); - - start = clock(); - for (i=0; i alTbl; - status = alTbl.init(10000); - assert(!status); - - for(i=0; i<100000; i++) { - unsigned id = (unsigned) rand(); - albert *pa = new albert(alTbl, id); - assert(pa); - status = alTbl.add(*pa); - if (status) { - // - // duplicate ids are possible - // and ignored - // - delete pa; - } - } - alTbl.show(1u); - alTbl.destroyAllEntries(); - - return 0; -} - -void empty() -{ -} \ No newline at end of file diff --git a/src/libCom/cxxTemplates/test/tsBTreeBench.cc b/src/libCom/cxxTemplates/test/tsBTreeBench.cc deleted file mode 100644 index 15a07301f..000000000 --- a/src/libCom/cxxTemplates/test/tsBTreeBench.cc +++ /dev/null @@ -1,83 +0,0 @@ - -#include -#include -#include -#include - -#include "tsBTree.h" -#include "tsSLList.h" - -class A : public tsBTreeNode, public tsSLNode { -public: - A() - { - key = (unsigned) rand(); - } - - btCmp tsBTreeCompare(const A &item) const - { - if (this->key<=item.key) { - return btLessOrEqual; - } - else { - return btGreater; - } - } - - void show() - { - printf("A: %u\n", key); - } -private: - unsigned key; -}; - -#define LOOPCOUNT 10000u - -main () -{ - unsigned i; - tsBTree tree; - tsSLList list; - A *pA; - A a; - clock_t clk; - clock_t diff; - double delay; - - tree.insert(a); - list.add(a); - - for (i=0u; i -#include - -#include "tsBTree.h" - -class A : public tsBTreeNode { -public: - A(const char *pNameIn) : pName(pNameIn) {} - - btCmp tsBTreeCompare(const A &item) const - { - int cmp = strcmp(this->pName, item.pName); - if (cmp<=0) { - return btLessOrEqual; - } - else { - return btGreater; - } - } - - void show() - { - printf("A: %s\n", pName); - } -private: - const char *pName; -}; - -main () -{ - tsBTree tree; - A a0("fred"); - A a1("jane"); - A a2("jane0"); - A a3("bill"); - A a4("jane"); - A a5("dan"); - A a6("joe"); - - tree.insert(a0); - tree.insert(a1); - tree.insert(a2); - tree.insert(a3); - tree.insert(a4); - tree.insert(a5); - - tree.traverse(A::show); - - assert(tree.remove(a6)==tsbtrrNotFound); - tree.insert(a6); - assert(tree.remove(a6)==tsbtrrFound); - assert(tree.remove(a5)==tsbtrrFound); - assert(tree.remove(a5)==tsbtrrNotFound); - assert(!tree.verify(a5)); - assert(tree.verify(a4)); - assert(tree.remove(a0)==tsbtrrFound); - assert(!tree.verify(a0)); - assert(tree.remove(a0)==tsbtrrNotFound); - tree.insert(a5); - assert(tree.verify(a5)); - assert(tree.verify(a2)); - assert(tree.remove(a2)==tsbtrrFound); - assert(!tree.verify(a2)); - assert(tree.remove(a2)==tsbtrrNotFound); - assert(tree.verify(a5)); - assert(tree.remove(a5)==tsbtrrFound); - assert(tree.remove(a5)==tsbtrrNotFound); - assert(tree.remove(a0)==tsbtrrNotFound); - assert(tree.remove(a4)==tsbtrrFound); - assert(tree.remove(a3)==tsbtrrFound); - assert(tree.remove(a4)==tsbtrrNotFound); - assert(tree.remove(a1)==tsbtrrFound); - - tree.traverse(A::show); - - return 0; -} - - diff --git a/src/libCom/cxxTemplates/test/tsDLListBench.cc b/src/libCom/cxxTemplates/test/tsDLListBench.cc deleted file mode 100644 index 235d01cd1..000000000 --- a/src/libCom/cxxTemplates/test/tsDLListBench.cc +++ /dev/null @@ -1,61 +0,0 @@ - -#include -#include -#include -#include - -class fred : public tsDLNode { -public: - fred() : count(0) {} - void inc () {count++;} -private: - unsigned count; -}; - -class jane : public fred, public tsDLNode { -public: - jane() {} -private: -}; - -#define LOOPCOUNT 100000 - -int main () -{ - tsDLList list; - tsDLFwdIter iter(list); - fred *pFred; - unsigned i; - clock_t clk; - clock_t diff; - double delay; - - for (i=0; iinc(); - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - pFred = new fred(); - clk = clock(); - for (i=0; iinc(); - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsDLListTest.cc b/src/libCom/cxxTemplates/test/tsDLListTest.cc deleted file mode 100644 index 10bacd8e5..000000000 --- a/src/libCom/cxxTemplates/test/tsDLListTest.cc +++ /dev/null @@ -1,102 +0,0 @@ - - - -#include -#include -#include - -class fred : public tsDLNode { -public: - fred(const char * const pNameIn) : pName(pNameIn){} - void show () {printf("%s\n", pName);} -private: - const char * const pName; -}; - -class jane : public fred, public tsDLNode { -public: - jane(const char * const pNameIn) : fred(pNameIn){} -private: -}; - -int main () -{ - tsDLList list; - tsDLFwdIter iter(list); - fred *pFred; - fred *pFredII; - fred *pFredBack; - tsDLList janeList; - tsDLFwdIter janeFwdIter(janeList); - tsDLBwdIter janeBwdIter(janeList); - jane *pJane; - - pFred = new fred("A"); - pFredII = new fred("B"); - - list.add(*pFred); - list.add(*pFredII); - pFredBack = iter(); - assert(pFredBack == pFred); - pFredBack = iter(); - assert(pFredBack == pFredII); - list.remove(*pFred); - list.add(*pFred); - pFredBack = list.get(); - assert (pFredBack == pFredII); - pFredBack = list.get(); - assert (pFredBack == pFred); - assert (list.count() == 0u); - list.add(*pFred); - list.add(*pFredII); - list.add(* new fred("C")); - list.add(* new fred("D")); - - iter.reset(); - while ( (pFredBack = iter()) ) { - pFredBack->show(); - } - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - janeList.add(*pJane); - - while ( (pJane = janeFwdIter()) ) { - pJane->show(); - } - - while ( (pJane = janeBwdIter()) ) { - pJane->show(); - } - - iter.reset(); - while ( (pFredBack = iter()) ) { - pFredBack->show(); - } - - iter.reset(); - while ( (pFredBack = iter()) ) { - iter.remove(); - } - assert(list.count()==0); - - janeFwdIter.reset(); - while ( (pFredBack = janeFwdIter()) ) { - janeFwdIter.remove(); - } - assert(janeList.count()==0); - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - janeList.add(*pJane); - janeBwdIter.reset(); - while ( (pFredBack = janeBwdIter()) ) { - janeBwdIter.remove(); - } - assert(janeList.count()==0); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsSLListBench.cc b/src/libCom/cxxTemplates/test/tsSLListBench.cc deleted file mode 100644 index 1cf9fad07..000000000 --- a/src/libCom/cxxTemplates/test/tsSLListBench.cc +++ /dev/null @@ -1,75 +0,0 @@ - - - -#include -#include -#include -#include - -/* - * gnuc does not provide this under sunos4 - */ -#if !defined(CLOCKS_PER_SEC) && defined(SUNOS4) -# define CLOCKS_PER_SEC 1000000 -#endif - -class fred : public tsSLNode { -public: - fred() : count(0) {} - void inc () {count++;} -private: - unsigned count; -}; - -class jane : public fred, public tsSLNode { -public: - jane() {} -private: -}; - -#define LOOPCOUNT 100000 - -int main () -{ - tsSLList list; - fred *pFred; - unsigned i; - clock_t clk; - clock_t diff; - double delay; - - for (i=0; i iter(list); - while ( (pFred = iter()) ) { - pFred->inc(); - } - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - pFred = new fred(); - clk = clock(); - { - tsSLIter iter(list); - for (i=0; iinc(); - } - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsSLListTest.cc b/src/libCom/cxxTemplates/test/tsSLListTest.cc deleted file mode 100644 index 80186681c..000000000 --- a/src/libCom/cxxTemplates/test/tsSLListTest.cc +++ /dev/null @@ -1,103 +0,0 @@ - - - -#include -#include -#include - -class fred : public tsSLNode { -public: - fred(const char * const pNameIn) : pName(pNameIn){} - void show () {printf("%s\n", pName);} -private: - const char * const pName; -}; - -class jane : public fred, public tsSLNode { -public: - jane(const char * const pNameIn) : fred(pNameIn){} -private: -}; - -int main () -{ - tsSLList list; - fred *pFred; - fred *pFredII; - fred *pFredBack; - tsSLList janeList; - jane *pJane; - - pFred = new fred("A"); - pFredII = new fred("B"); - - list.add(*pFred); - list.add(*pFredII); - { - tsSLIter iter(list); - pFredBack = iter(); - assert(pFredBack == pFredII); - } - list.remove(*pFredII); // removes *pFred !! - list.add(*pFred); - pFredBack = list.get(); - assert (pFredBack == pFred); - pFredBack = list.get(); - assert (pFredBack == pFredII); - list.add(*pFredII); - list.add(*pFred); - { - tsSLIterRm iter(list); - while ( (pFredBack = iter()) ) { - iter.remove(); - } - } - pFredBack = list.get(); - assert (pFredBack == 0); - list.add(*pFred); - list.add(*pFredII); - list.add(* new fred("C")); - list.add(* new fred("D")); - - { - tsSLIter iter(list); - while ( (pFredBack = iter()) ) { - pFredBack->show(); - } - } - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - janeList.add(*pJane); - - { - tsSLIter janeIter(janeList); - while ( (pJane = janeIter()) ) { - pJane->show(); - } - } - - { - tsSLIter iter(list); - while ( (pFredBack = iter()) ) { - pFredBack->show(); - } - } - - { - tsSLIterRm iter(list); - while ( (pFredBack = iter()) ) { - iter.remove(); - } - } - - { - tsSLIter iter(list); - pFredBack = iter(); - assert(pFredBack==NULL); - } - - return 0; -} - diff --git a/src/libCom/cxxTemplates/tsBTree.h b/src/libCom/cxxTemplates/tsBTree.h deleted file mode 100644 index 27bad465a..000000000 --- a/src/libCom/cxxTemplates/tsBTree.h +++ /dev/null @@ -1,261 +0,0 @@ - -#ifndef assert // allow use of epicsAssert.h -#include -#endif - -// -// tsBTreeRMRet -// -enum tsbtRR {tsbtrrNotFound, tsbtrrFound}; -template -class tsBTreeRMRet { -public: - tsBTreeRMRet (tsbtRR foundItIn, T *pNewSegIn) : - foundIt(foundItIn), pNewSeg(pNewSegIn) {} - - operator tsbtRR () - { - return this->foundIt; - } - - const tsbtRR foundIt; - T * const pNewSeg; -}; - -// -// tsBTreeNode -// -template -class tsBTreeNode -{ -friend class tsBTree; -public: - // - // when someone copies into a class deriving from this - // do _not_ change the node pointers - // - void operator = (tsBTreeNode &) {} - - enum btCmp {btGreater, btLessOrEqual}; - - // - // class T must supply this member function which - // comapres *this with item - // - // returns: - // btGreater *this is greater than item - // btLessOrEqual *this is less than or equal to item - // - // btCmp tsBTreeCompare(const T &item) const; - // - -private: - T *pLeft; - T *pRight; - - static void traverse(T &self, void (T::*pCB)()) - { - if (self.tsBTreeNode::pLeft) { - tsBTreeNode::traverse - (*self.tsBTreeNode::pLeft, pCB); - } - (self.*pCB)(); - if (self.tsBTreeNode::pRight) { - tsBTreeNode::traverse - (*self.tsBTreeNode::pRight, pCB); - } - } - - // - // NOTE: - // no change to item.pLeft and item.pRight here - // so that an segment of a tree can be inserted - // - static void insert(T &self, T &item) - { - btCmp result = item.tsBTreeCompare(self); - if (result==btLessOrEqual) { - if (self.tsBTreeNode::pLeft) { - tsBTreeNode::insert - (*self.tsBTreeNode::pLeft, item); - } - else { - self.tsBTreeNode::pLeft = &item; - } - } - else if(result==btGreater) { - if (self.tsBTreeNode::pRight) { - tsBTreeNode::insert - (*self.tsBTreeNode::pRight, item); - } - else { - self.tsBTreeNode::pRight = &item; - } - } - else { - assert(0); - } - } - - // - // remove() - // returns pointer to modified tree and found/not found - // (NULL if this portion of the tree is empty) - // - static tsBTreeRMRet remove(T &self, T &item) - { - if (&self == &item) { - if (self.tsBTreeNode::pLeft) { - if (self.tsBTreeNode::pRight) { - T *pR = self.tsBTreeNode::pLeft->tsBTreeNode::pRight; - if (pR) { - tsBTreeNode::insert - (*pR, *self.tsBTreeNode::pRight); - } - else { - self.tsBTreeNode::pLeft->tsBTreeNode::pRight = - self.tsBTreeNode::pRight; - } - } - return tsBTreeRMRet(tsbtrrFound, self.tsBTreeNode::pLeft); // found it - } - else { - return tsBTreeRMRet(tsbtrrFound, self.tsBTreeNode::pRight); // found it - } - } - - btCmp result = item.tsBTreeCompare(self); - if (result==btLessOrEqual) { - if (self.tsBTreeNode::pLeft) { - tsBTreeRMRet ret = tsBTreeNode:: - remove(*self.tsBTreeNode::pLeft, item); - if (ret.foundIt==tsbtrrFound) { - self.tsBTreeNode::pLeft= ret.pNewSeg; - return tsBTreeRMRet(tsbtrrFound,&self); // TRUE - found it - } - } - return tsBTreeRMRet(tsbtrrNotFound, 0u); // not found - } - else if(result==btGreater) { - if (self.tsBTreeNode::pRight) { - tsBTreeRMRet ret = tsBTreeNode:: - remove(*self.tsBTreeNode::pRight, item); - if (ret.foundIt==tsbtrrFound) { - self.tsBTreeNode::pRight = ret.pNewSeg; - return tsBTreeRMRet(tsbtrrFound,&self); // TRUE - found it - } - } - return tsBTreeRMRet(tsbtrrNotFound, 0u); // not found - } - else { - assert(0); - } - } - // - // verify - // - static unsigned verify(const T &self, const T &item) - { - if (&self == &item) { - return 1u; // TRUE -item is present - } - btCmp result = item.tsBTreeCompare(self); - if (result==btLessOrEqual) { - if (self.tsBTreeNode::pLeft) { - return tsBTreeNode::verify - (*self.tsBTreeNode::pLeft, item); - } - else { - return 0u; // FALSE - not found - } - } - else if(result==btGreater) { - if (self.tsBTreeNode::pRight) { - return tsBTreeNode::verify - (*self.tsBTreeNode::pRight, item); - } - else { - return 0u; // FALSE - not found - } - } - else { - assert(0); - } - } -}; - -// -// tsBTree -// -template -class tsBTree -{ -public: - tsBTree() : pRoot(0u) {} - -// ~tsBTree() -// { -// this->traverse(T::~T); -// } - - void insert(T &item) - { - item.tsBTreeNode::pLeft = 0; - item.tsBTreeNode::pRight = 0; - if (this->pRoot) { - tsBTreeNode::insert(*this->pRoot, item); - } - else { - this->pRoot = &item; - } - } - // - // remove item from the tree - // - // returns true if item was in the tree - // (otherwise FALSE) - // - unsigned remove(T &item) - { - if (this->pRoot) { - tsBTreeRMRet ret = - tsBTreeNode::remove(*this->pRoot, item); - if (ret.foundIt) { - this->pRoot = ret.pNewSeg; - return 1u; // TRUE - found it - } - } - return 0u; // FALSE - not found - } - // - // verify that item is in the tree - // - // returns true if item is in the tree - // (otherwise FALSE) - // - unsigned verify(T &item) const - { - if (this->pRoot) { - return tsBTreeNode::verify(*this->pRoot, item); - } - else { - return 0u; // FALSE - not found - } - } - // - // Call (pT->*pCB) () for each item in the table - // - // where pT is a pointer to type T and pCB is - // a pointer to a memmber function of T with - // no parameters and returning void - // - void traverse(void (T::*pCB)()) - { - if (this->pRoot) { - tsBTreeNode::traverse(*this->pRoot, pCB); - } - } -private: - T *pRoot; -}; - diff --git a/src/libCom/cxxTemplates/tsDLList.h b/src/libCom/cxxTemplates/tsDLList.h deleted file mode 100644 index 1495b6c9b..000000000 --- a/src/libCom/cxxTemplates/tsDLList.h +++ /dev/null @@ -1,873 +0,0 @@ -/* - * $Id$ - * - * type safe doubly linked list templates - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - * 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 - * - * - * History - * $Log$ - * Revision 1.13 1998/06/16 03:01:44 jhill - * cosmetic - * - * Revision 1.12 1998/05/29 17:25:47 jhill - * allow use of epicsAssert.h - * - * Revision 1.11 1998/05/05 18:06:57 jhill - * rearranged to allow compilation by g++ 2.8.1 - * - * Revision 1.10 1998/02/05 23:28:21 jhill - * fixed hp sompiler warnings - * - * Revision 1.9 1997/06/13 09:21:52 jhill - * fixed compiler compatibility problems - * - * Revision 1.8 1997/04/11 20:49:48 jhill - * added no arg reset() to bwd iter - * - * Revision 1.7 1997/04/10 19:43:10 jhill - * API changes - * - * Revision 1.6 1997/01/22 21:13:49 jhill - * fixed class decl order for VMS - * - * Revision 1.5 1996/11/02 01:07:19 jhill - * many improvements - * - * Revision 1.4 1996/08/14 12:32:09 jbk - * added first() to list class, added first()/last() to iterator. - * - * Revision 1.3 1996/07/25 18:01:41 jhill - * use pointer (not ref) for list in iter class - * - * Revision 1.2 1996/07/24 22:12:03 jhill - * added remove() to iter class + made node's prev/next private - * - * Revision 1.1.1.1 1996/06/20 22:15:55 jhill - * installed ca server templates - * - * - */ - -#ifndef tsDLListH_include -#define tsDLListH_include - -#ifndef assert // allow use of epicsAssert.h -#include -#endif - -template class tsDLList; -template class tsDLIterBD; -template class tsDLIter; -template class tsDLFwdIter; -template class tsDLBwdIter; - -// -// tsDLNode -// NOTE: T must derive from tsDLNode -// -template -class tsDLNode { -friend class tsDLList; -friend class tsDLIterBD; -friend class tsDLIter; -friend class tsDLFwdIter; -friend class tsDLBwdIter; -public: - tsDLNode() : pNext(0), pPrev(0) {} - // - // when someone copies in a class deriving from this - // do _not_ change the node pointers - // - void operator = (const tsDLNode &) {} - -protected: - T *getNext(void) { return pNext; } - T *getPrev(void) { return pPrev; } -private: - T *pNext; - T *pPrev; -}; - -// -// tsDLList -// NOTE: T must derive from tsDLNode -// -template -class tsDLList { -friend class tsDLIter; -friend class tsDLFwdIter; -friend class tsDLBwdIter; -private: - // - // clear() - // - void clear() - { - this->pFirst = 0; - this->pLast = 0; - this->itemCount = 0u; - } - -public: - - tsDLList () - { - clear(); - } - - // - // count() - // (returns the number of items on the list) - // - unsigned count() const - { - return this->itemCount; - } - - // - // add() - - // adds addList to the end of the list - // (and removes all items from addList) - // - void add (tsDLList &addList); - - // - // add() - // (add an item to the end of the list) - // - void add (T &item); - - // - // get () - // - T * get(); - - // - // insertAfter() - // (place item in the list immediately after itemBefore) - // - void insertAfter (T &item, T &itemBefore); - - // - // insertBefore () - // (place item in the list immediately before itemAfter) - // - void insertBefore (T &item, T &itemAfter); - - // - // remove () - // - void remove (T &item); - - // - // pop () - // (returns the first item on the list) - T * pop(); - - // - // push () - // (add an item at the beginning of the list) - // - void push (T &item); - - // - // find - // returns -1 if the item isnt on the list - // and the node number (beginning with zero if - // it is) - // - int find(T &item) const; - - T *first(void) const { return this->pFirst; } - T *last(void) const { return this->pLast; } - -protected: - T *getFirst(void) const { return pFirst; } - T *getLast(void) const { return pLast; } -private: - T *pFirst; - T *pLast; - unsigned itemCount; - - // - // past functionality incompatible - // with strict definition of a copy - // constructor so this has been eliminated - // - // copying one list item into another and - // ending up with to list headers pointing - // at the same list is always a questionable - // thing to do. - // - // therefore, this is intentionally _not_ - // implemented. - // - tsDLList (const tsDLList &); -}; - - -// -// tsDLIterBD -// (a bi-directional iterator in the style of the STL) -// -template -class tsDLIterBD { -public: - tsDLIterBD () : - pEntry(0) {} - - tsDLIterBD (T *pInitialEntry) : - pEntry(pInitialEntry) {} - - tsDLIterBD (const class tsDLIterBD ©In); - - tsDLIterBD & operator = (T *pNewEntry) - { - this->pEntry = pNewEntry; - return *this; - } - - tsDLIterBD &operator = (const tsDLIterBD ©In) - { - this->pEntry = copyIn.pEntry; - return *this; - } - - int operator == (const tsDLIterBD &rhs) const - { - return (this->pEntry == rhs.pEntry); - } - - int operator != (const tsDLIterBD &rhs) const - { - return (this->pEntry != rhs.pEntry); - } - - T & operator * () const - { - return *this->pEntry; - } - - T * operator -> () const - { - return this->pEntry; - } - - operator T* () const - { - return this->pEntry; - } - - // - // prefix ++ - // - T *operator ++ () - { - tsDLNode *pNode = this->pEntry; - return this->pEntry = pNode->pNext; - } - - // - // postfix ++ - // - T *operator ++ (int) - { - T *pE = this->pEntry; - tsDLNode *pNode = this->pEntry; - this->pEntry = pNode->pNext; - return pE; - } - - // - // prefix -- - // - T *operator -- () - { - tsDLNode *pEntryNode = pEntry; - return this->pEntry = pEntryNode->pPrev; - } - - // - // postfix -- - // - T *operator -- (int) - { - T *pE = this->pEntry; - tsDLNode *pEntryNode = pEntry; - this->pEntry = pEntryNode->pPrev; - return pE; - } -private: - T *pEntry; -}; - -// -// tsDLIter -// -// Notes: -// 2) This iterator does not allow for removal -// of an item in order to avoid problems -// resulting when we remove an item (and -// then dont know whether to make pCurrent -// point at the item before or after the -// item removed -// -template -class tsDLIter { -public: - tsDLIter (tsDLList & listIn) : - pCurrent(0), pList(&listIn) {} - - void reset () - { - this->pCurrent = 0; - } - - void reset (tsDLList &listIn) - { - this->reset(); - this->pList = &listIn; - } - - void operator = (tsDLList &listIn) - { - this->reset(listIn); - } - - T * next (); - - T * prev (); - - T * first() - { - this->pCurrent = this->pList->pFirst; - return this->pCurrent; - } - - T * last() - { - this->pCurrent = this->pList->pLast; - return this->pCurrent; - } - - T * operator () (); - -protected: - T *pCurrent; - tsDLList *pList; -}; - -// -// tsDLFwdIter -// -// Notes: -// 1) No direct access to pCurrent is provided since -// this might allow for confusion when an item -// is removed (and pCurrent ends up pointing at -// an item that has been seen before) -// -// 2) This iterator only moves forward in order to -// avoid problems resulting when we remove an -// item (and then dont know whether to make -// pCurrent point at the item before or after -// the item removed -// -template -class tsDLFwdIter: private tsDLIter { -public: - tsDLFwdIter (tsDLList &listIn) : - tsDLIter(listIn) {} - - void reset () - { - this->tsDLIter::reset(); - } - - void reset (tsDLList &listIn) - { - this->tsDLIter::reset(listIn); - } - - void operator = (tsDLList &listIn) - { - this->tsDLIter::reset(listIn); - } - - T * operator () (); - - T * next (); - - T * first() - { - tsDLIter &iterBase = *this; - return iterBase.first(); - } - - // - // remove () - // (and move current to be the item - // pointed to by pPrev - the item seen - // by the iterator before the current one - - // this guarantee that the list will be - // accessed sequentially even if an item - // is removed) - // - void remove (); -}; - -// -// tsDLBwdIter -// -// Notes: -// 1) No direct access to pCurrent is provided since -// this might allow for confusion when an item -// is removed (and pCurrent ends up pointing at -// an item that has been seen before) -// -// 2) This iterator only moves backward in order to -// avoid problems resulting when we remove an -// item (and then dont know whether to make -// pCurrent point at the item before or after -// the item removed -// -template -class tsDLBwdIter : private tsDLIter { -public: - tsDLBwdIter(tsDLList &listIn) : - tsDLIter(listIn) {} - - void reset () - { - this->tsDLIter::reset(); - } - - void reset (tsDLList &listIn) - { - this->tsDLIter::reset(listIn); - } - - void operator = (tsDLList &listIn) - { - this->tsDLIter::reset(listIn); - } - - T * operator () (); - - T * prev (); - - T * last() - { - return this->tsDLIter::last(); - } - - // - // remove () - // remove current item - // (and move current to be the item - // pointed to by pNext - the item seen - // by the iterator before the current one - - // this guarantee that the list will be - // accessed sequentially even if an item - // is removed) - // - void remove (); -}; - -// -// MS Visual C 6.0 requires that this code is not provided in -// the class definition because the class isnt fully defined yet -// -template -inline tsDLIterBD::tsDLIterBD(const class tsDLIterBD ©In) : - pEntry(copyIn.pEntry) {} - - -// -// tsDLList::remove () -// -template -void tsDLList::remove (T &item) -{ - tsDLNode &node = item; - - if (this->pLast == &item) { - this->pLast = node.pPrev; - } - else { - tsDLNode *pNextNode = node.pNext; - pNextNode->pPrev = node.pPrev; - } - - if (this->pFirst == &item) { - this->pFirst = node.pNext; - } - else { - tsDLNode *pPrevNode = node.pPrev; - pPrevNode->pNext = node.pNext; - } - - this->itemCount--; -} - -// -// tsDLList::get () -// -template -inline T * tsDLList::get() -{ - T *pItem = this->pFirst; - - if (pItem) { - this->remove (*pItem); - } - - return pItem; -} - -// -// tsDLList::pop () -// (returns the first item on the list) -template -inline T * tsDLList::pop() -{ - return this->get(); -} - -// -// add() - -// adds addList to the end of the list -// (and removes all items from addList) -// -template -void tsDLList::add (tsDLList &addList) -{ - // - // NOOP if addList is empty - // - if (addList.itemCount==0u) { - return; - } - - if (this->itemCount==0u) { - // - // this is empty so just init from - // addList - // - *this = addList; - } - else { - tsDLNode *pLastNode = this->pLast; - tsDLNode *pAddListFirstNode = addList.pFirst; - - // - // add addList to the end of this - // - pLastNode->pNext = addList.pFirst; - pAddListFirstNode->pPrev = addList.pLast; - this->pLast = addList.pLast; - this->itemCount += addList.itemCount; - } - - // - // leave addList empty - // - addList.clear(); -} - -// -// add() -// (add an item to the end of the list) -// -template -void tsDLList::add (T &item) -{ - tsDLNode &node = item; - - node.pNext = 0; - node.pPrev = this->pLast; - - if (this->itemCount) { - tsDLNode *pLastNode = this->pLast; - pLastNode->pNext = &item; - } - else { - this->pFirst = &item; - } - - this->pLast = &item; - - this->itemCount++; -} - -// -// insertAfter() -// (place item in the list immediately after itemBefore) -// -template -void tsDLList::insertAfter (T &item, T &itemBefore) -{ - tsDLNode &node = item; - tsDLNode &nodeBefore = itemBefore; - - node.pPrev = &itemBefore; - node.pNext = nodeBefore.pNext; - nodeBefore.pNext = &item; - - if (node.pNext) { - tsDLNode *pNextNode = node.pNext; - pNextNode->pPrev = &item; - } - else { - this->pLast = &item; - } - - this->itemCount++; -} - -// -// insertBefore () -// (place item in the list immediately before itemAfter) -// -template -void tsDLList::insertBefore (T &item, T &itemAfter) -{ - tsDLNode &node = item; - tsDLNode &nodeAfter = itemAfter; - - node.pNext = &itemAfter; - node.pPrev = nodeAfter.pPrev; - nodeAfter.pPrev = &item; - - if (node.pPrev) { - tsDLNode *pPrevNode = node.pPrev; - pPrevNode->pNext = &item; - } - else { - this->pFirst = &item; - } - - this->itemCount++; -} - -// -// push () -// (add an item at the beginning of the list) -// -template -void tsDLList::push (T &item) -{ - tsDLNode &node = item; - node.pPrev = 0; - node.pNext = this->pFirst; - - if (this->itemCount) { - tsDLNode *pFirstNode = this->pFirst; - pFirstNode->pPrev = &item; - } - else { - this->pLast = &item; - } - - this->pFirst = &item; - - this->itemCount++; -} - -// -// tsDLIter::next () -// -template -T * tsDLIter::next () -{ - T *pCur = this->pCurrent; - if (pCur==0) { - pCur = this->pList->pFirst; - } - else { - tsDLNode *pCurNode = pCur; - pCur = pCurNode->pNext; - } - this->pCurrent = pCur; - return pCur; -} - -// -// tsDLIter::prev () -// -template -T * tsDLIter::prev () -{ - T *pCur = this->pCurrent; - if (pCur==0) { - pCur = this->pList->pLast; - } - else { - tsDLNode *pCurNode = pCur; - pCur = pCurNode->pPrev; - } - this->pCurrent = pCur; - return pCur; -} - -// -// tsDLIter::operator () () -// -template -inline T * tsDLIter::operator () () -{ - return this->next(); -} - -// -// remove () -// remove current item -// (and move current to be the item -// pointed to by pNext - the item seen -// by the iterator before the current one - -// this guarantee that the list will be -// accessed sequentially even if an item -// is removed) -// -template -void tsDLBwdIter::remove () -{ - T *pCur = this->pCurrent; - - if (pCur) { - tsDLNode *pCurNode = pCur; - - // - // strip const (we didnt declare the - // list const in the constructor) - // - tsDLList * pMutableList = - (tsDLList *) this->pList; - - // - // Move this->pCurrent to the item after the - // item being deleted - // - this->pCurrent = pCurNode->pNext; - - // - // delete current item - // - pMutableList->remove(*pCur); - } -} - -// -// tsDLBwdIter::operator () () -// -template -inline T * tsDLBwdIter::operator () () -{ - return this->tsDLIter::prev(); -} - -// -// tsDLBwdIter::prev () -// -template -inline T * tsDLBwdIter::prev () -{ - return this->tsDLIter::prev(); -} - -// -// tsDLFwdIter::remove () -// (and move current to be the item -// pointed to by pPrev - the item seen -// by the iterator before the current one - -// this guarantee that the list will be -// accessed sequentially even if an item -// is removed) -// -template -void tsDLFwdIter::remove () -{ - T *pCur = this->pCurrent; - - if (pCur) { - tsDLNode *pCurNode = pCur; - - // - // Move this->pCurrent to the previous item - // - this->pCurrent = pCurNode->pPrev; - - // - // delete current item - // - this->pList->remove(*pCur); - } -} - -// -// tsDLFwdIter::next () -// -template -inline T * tsDLFwdIter::next () -{ - tsDLIter &iterBase = *this; - return iterBase.next(); -} - -// -// tsDLFwdIter::operator () () -// -template -inline T * tsDLFwdIter::operator () () -{ - return this->next(); -} - -// -// tsDLList::find () -// returns -1 if the item isnt on the list -// and the node number (beginning with zero if -// it is) -// -template -int tsDLList::find(T &item) const -{ - tsDLFwdIter iter(*this); - tsDLNode *pItem; - int itemNo=0; - - while ( (pItem = iter.next()) ) { - if (pItem == &item) { - return itemNo; - } - itemNo++; - } - return -1; -} - -#endif // tsDLListH_include - diff --git a/src/libCom/cxxTemplates/tsMinMax.h b/src/libCom/cxxTemplates/tsMinMax.h deleted file mode 100644 index 1cab10dee..000000000 --- a/src/libCom/cxxTemplates/tsMinMax.h +++ /dev/null @@ -1,18 +0,0 @@ - -// -// simple type safe inline template functions to replace -// the min() and max() macros -// - -template -inline const T &tsMax(const T &a, const T &b) -{ - return (a>b) ? a : b; -} - -template -inline const T &tsMin(const T &a, const T &b) -{ - return (a -#endif - -// -// the hp compiler complains about parameterized friend -// class that has not been declared without this? -// -template class tsSLList; -template class tsSLIter; -template class tsSLIterRm; - -// -// tsSLNode<> -// NOTE: T must derive from tsSLNode -// -template -class tsSLNode { -friend class tsSLList; -friend class tsSLIter; -friend class tsSLIterRm; -public: - tsSLNode() : pNext(0) {} - - // - // when someone copies into a class deriving from this - // do _not_ change the node pointers - // - void operator = (const tsSLNode &) {} - -private: - T *pNext; -}; - - -// -// tsSLList<> -// NOTE: T must derive from tsSLNode -// -template -class tsSLList : public tsSLNode { -public: - - // - // insert() - // (itemBefore might be the list header object and therefore - // will not always be of type T) - // - void insert (T &item, tsSLNode &itemBefore) - { - tsSLNode &node = item; - node.pNext = itemBefore.pNext; - itemBefore.pNext = &item; - } - - // - // add() - // - void add (T &item) - { - this->insert (item, *this); - } - - // - // remove () - // **** removes item after "itemBefore" **** - // (itemBefore might be the list header object and therefore - // will not always be of type T) - // - void remove (tsSLNode &itemBefore) - { - T *pItem = itemBefore.pNext; - if (pItem) { - tsSLNode *pNode = pItem; - itemBefore.pNext = pNode->pNext; - } - } - - // - // get () - // - T * get() - { - tsSLNode *pThisNode = this; - T *pItem = pThisNode->pNext; - this->remove(*this); - return pItem; - } - - T * pop() - { - return get(); - } - - void push(T &item) - { - this->add(item); - } -}; - -// -// tsSLIter -// -template -class tsSLIter { -public: - tsSLIter(const tsSLList &listIn) : - pCurrent(0), list(listIn) {}; - - // - // move iterator forward - // - // NULL test here is inefficient, but it appears that some architectures - // (intel) dont like to cast a NULL pointer from a tsSLNode to a T even if - // tsSLNode is always a base class of a T. - // - T * next (); - - // - // move iterator forward - // - T * operator () () - { - return this->next(); - } - -private: - T *pCurrent; - const tsSLList &list; -}; - -// -// tsSLIterRm -// (A tsSLIter that allows removing a node) -// -// adds remove method (and does not construct -// with const list) -// -// tsSLIter isnt a base class because this -// requires striping const from pCurrent which could get -// us in trouble with a high quality -// optimizing compiler -// -// Notes: -// 1) No direct access to pCurrent is provided since -// this might allow for confusion when an item -// is removed (and pCurrent ends up pointing at -// an item that has been seen before) -// -// -template -class tsSLIterRm { -public: - tsSLIterRm(tsSLList &listIn) : - pPrevious(0), pCurrent(0), list(listIn) {}; - - // - // move iterator forward - // - // NULL test here is inefficient, but it appears that some architectures - // (intel) dont like to cast a NULL pointer from a tsSLNode to a T even if - // tsSLNode is always a base class of a T. - // - T * next (); - - // - // move iterator forward - // - T * operator () () - { - return this->next(); - } - - // - // remove current node - // (and move current to be the previos item - - // the item seen by the iterator before the - // current one - this guarantee that the list - // will be accessed sequentially even if an item - // is removed) - // - // This cant be called twice in a row without moving - // the iterator to the next item. If there is - // no current item this function assert fails. - // - void remove (); - -private: - T *pPrevious; - T *pCurrent; - tsSLList &list; -}; - -// -// tsSLIter::next () -// -// move iterator forward -// -// NULL test here is inefficient, but it appears that some architectures -// (intel) dont like to cast a NULL pointer from a tsSLNode to a T even if -// tsSLNode is always a base class of a T. -// -template -T * tsSLIter::next () -{ - if (this->pCurrent!=0) { - tsSLNode *pCurNode = this->pCurrent; - this->pCurrent = pCurNode->pNext; - } - else { - const tsSLNode &first = this->list; - // - // assume that we are starting (or restarting) at the - // beginning of the list - // - this->pCurrent = first.pNext; - } - return this->pCurrent; -} - -// -// tsSLIterRm::next () -// -// move iterator forward -// -// NULL test here is inefficient, but it appears that some architectures -// (intel) dont like to cast a NULL pointer from a tsSLNode to a T even if -// tsSLNode is always a base class of a T. -// -template -T * tsSLIterRm::next () -{ - if (this->pCurrent!=0) { - tsSLNode *pCurNode = this->pCurrent; - this->pPrevious = this->pCurrent; - this->pCurrent = pCurNode->pNext; - } - else { - const tsSLNode &first = this->list; - // - // assume that we are starting (or restarting) at the - // beginning of the list - // - this->pCurrent = first.pNext; - this->pPrevious = 0; - } - return this->pCurrent; -} - -// -// tsSLIterRm::remove () -// -// remove current node -// (and move current to be the previos item - -// the item seen by the iterator before the -// current one - this guarantee that the list -// will be accessed sequentially even if an item -// is removed) -// -// This cant be called twice in a row without moving -// the iterator to the next item. If there is -// no current item this function assert fails. -// -template -void tsSLIterRm::remove () -{ - assert (this->pCurrent!=0); - - tsSLNode *pPrevNode; - tsSLNode *pCurNode = this->pCurrent; - - if (this->pPrevious==0) { - pPrevNode = &this->list; - // - // this assert fails if it is an attempt to - // delete twice without moving the iterator - // - assert (pPrevNode->pNext == this->pCurrent); - } - else { - pPrevNode = this->pPrevious; - } - - pPrevNode->pNext = pCurNode->pNext; - this->pCurrent = this->pPrevious; - this->pPrevious = 0; -} diff --git a/src/libCom/dbmf/dbmf.c b/src/libCom/dbmf/dbmf.c deleted file mode 100644 index 93ffda5ab..000000000 --- a/src/libCom/dbmf/dbmf.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Author: Jim Kowalkowski and Marty Kraimer - * Date: 4/97 - * - * Intended for applications that create and free requently - * - */ - -#include -#include -#include - -#ifdef vxWorks -#include -#include -#else -#define SEM_ID int -#define semGive(x) -#define semTake(x,y) -#define semBCreate(x,y) 0 -#define SEM_Q_PRIORITY 0 -#define SEM_FULL 0 -#endif - -#define epicsExportSharedSymbols -#include "ellLib.h" -#include "dbmf.h" - -/*Default values for dblfInit */ -#define DBMF_SIZE 64 -#define DBMF_INITIAL_ITEMS 10 - -typedef struct chunkNode {/*control block for each set of chunkItems*/ - ELLNODE node; - void *pchunk; - int nNotFree; -}chunkNode; - -typedef struct itemHeader{ - void *pnextFree; - chunkNode *pchunkNode; -}itemHeader; - -typedef struct dbmfPrivate { - ELLLIST chunkList; - SEM_ID sem; - size_t size; - size_t allocSize; - int chunkItems; - size_t chunkSize; - int nAlloc; - int nFree; - int nGtSize; - void *freeList; -} dbmfPrivate; -dbmfPrivate dbmfPvt; -static dbmfPrivate *pdbmfPvt = NULL; -int dbmfDebug=0; - -int epicsShareAPI dbmfInit(size_t size, int chunkItems) -{ - if(pdbmfPvt) { - printf("dbmfInit: Already initialized\n"); - return(-1); - } - pdbmfPvt = &dbmfPvt; - ellInit(&pdbmfPvt->chunkList); - pdbmfPvt->sem = semBCreate(SEM_Q_PRIORITY,SEM_FULL); - /*allign to at least a double*/ - pdbmfPvt->size = size + size%sizeof(double); - pdbmfPvt->allocSize = pdbmfPvt->size + sizeof(itemHeader); - pdbmfPvt->chunkItems = chunkItems; - pdbmfPvt->chunkSize = pdbmfPvt->allocSize * pdbmfPvt->chunkItems; - pdbmfPvt->nAlloc = 0; - pdbmfPvt->nFree = 0; - pdbmfPvt->nGtSize = 0; - pdbmfPvt->freeList = NULL; - return(0); -} - - -void* epicsShareAPI dbmfMalloc(size_t size) -{ - void **pnextFree; - void **pfreeList; - char *pmem = NULL; - chunkNode *pchunkNode; - itemHeader *pitemHeader; - - if(!pdbmfPvt) dbmfInit(DBMF_SIZE,DBMF_INITIAL_ITEMS); - semTake(pdbmfPvt->sem,WAIT_FOREVER); - pfreeList = &pdbmfPvt->freeList; - if(*pfreeList == NULL) { - int i; - size_t nbytesTotal; - - if(dbmfDebug) printf("dbmfMalloc allocating new storage\n"); - nbytesTotal = pdbmfPvt->chunkSize + sizeof(chunkNode); - pmem = (char *)malloc(nbytesTotal); - if(!pmem) { - semGive(pdbmfPvt->sem); - printf("dbmfMalloc malloc failed\n"); - return(NULL); - } - pchunkNode = (chunkNode *)(pmem + pdbmfPvt->chunkSize); - pchunkNode->pchunk = pmem; - pchunkNode->nNotFree=0; - ellAdd(&pdbmfPvt->chunkList,&pchunkNode->node); - for(i=0; ichunkItems; i++) { - pitemHeader = (itemHeader *)pmem; - pitemHeader->pchunkNode = pchunkNode; - pnextFree = &pitemHeader->pnextFree; - *pnextFree = *pfreeList; *pfreeList = (void *)pmem; - pdbmfPvt->nFree++; - pmem += pdbmfPvt->allocSize; - } - } - if(size<=pdbmfPvt->size) { - pnextFree = *pfreeList; *pfreeList = *pnextFree; - pmem = (void *)pnextFree; - pdbmfPvt->nAlloc++; pdbmfPvt->nFree--; - pitemHeader = (itemHeader *)pnextFree; - pitemHeader->pchunkNode->nNotFree += 1; - } else { - pmem = malloc(sizeof(itemHeader) + size); pdbmfPvt->nAlloc++; - pdbmfPvt->nGtSize++; - pitemHeader = (itemHeader *)pmem; - pitemHeader->pchunkNode = NULL; - if(dbmfDebug) printf("dbmfMalloc: size %d mem %p\n",size,pmem); - } - semGive(pdbmfPvt->sem); - return((void *)(pmem + sizeof(itemHeader))); -} - - -void epicsShareAPI dbmfFree(void* mem) -{ - char *pmem = (char *)mem; - chunkNode *pchunkNode; - itemHeader *pitemHeader; - - if(!mem) return; - if(!pdbmfPvt) { - printf("dbmfFree called but dbmfInit never called\n"); - return; - } - pmem -= sizeof(itemHeader); - semTake(pdbmfPvt->sem,WAIT_FOREVER); - pitemHeader = (itemHeader *)pmem; - if(!pitemHeader->pchunkNode) { - if(dbmfDebug) printf("dbmfGree: mem %p\n",pmem); - free((void *)pmem); pdbmfPvt->nAlloc--; - }else { - void **pfreeList = &pdbmfPvt->freeList; - void **pnextFree = &pitemHeader->pnextFree; - - pchunkNode = pitemHeader->pchunkNode; - pchunkNode->nNotFree--; - *pnextFree = *pfreeList; *pfreeList = pnextFree; - pdbmfPvt->nAlloc--; pdbmfPvt->nFree++; - } - semGive(pdbmfPvt->sem); -} - -int epicsShareAPI dbmfShow(int level) -{ - if(pdbmfPvt==NULL) { - printf("Never initialized\n"); - return(0); - } - printf("size %d allocSize %d chunkItems %d ", - pdbmfPvt->size,pdbmfPvt->allocSize,pdbmfPvt->chunkItems); - printf("nAlloc %d nFree %d nChunks %d nGtSize %d\n", - pdbmfPvt->nAlloc,pdbmfPvt->nFree, - ellCount(&pdbmfPvt->chunkList),pdbmfPvt->nGtSize); - if(level>0) { - chunkNode *pchunkNode; - - pchunkNode = (chunkNode *)ellFirst(&pdbmfPvt->chunkList); - while(pchunkNode) { - printf("pchunkNode %p nNotFree %d\n", - pchunkNode,pchunkNode->nNotFree); - pchunkNode = (chunkNode *)ellNext(&pchunkNode->node); - } - } - if(level>1) { - void **pnextFree;; - - semTake(pdbmfPvt->sem,WAIT_FOREVER); - pnextFree = (void**)pdbmfPvt->freeList; - while(pnextFree) { - printf("%p\n",*pnextFree); - pnextFree = (void**)*pnextFree; - } - semGive(pdbmfPvt->sem); - } - return(0); -} - -void epicsShareAPI dbmfFreeChunks(void) -{ - chunkNode *pchunkNode; - chunkNode *pnext;; - - if(!pdbmfPvt) { - printf("dbmfFreeChunks called but dbmfInit never called\n"); - return; - } - semTake(pdbmfPvt->sem,WAIT_FOREVER); - if(pdbmfPvt->nFree - != (pdbmfPvt->chunkItems * ellCount(&pdbmfPvt->chunkList))) { - printf("dbmfFinish: not all free\n"); - semGive(pdbmfPvt->sem); - return; - } - pchunkNode = (chunkNode *)ellFirst(&pdbmfPvt->chunkList); - while(pchunkNode) { - pnext = (chunkNode *)ellNext(&pchunkNode->node); - ellDelete(&pdbmfPvt->chunkList,&pchunkNode->node); - free(pchunkNode->pchunk); - pchunkNode = pnext; - } - pdbmfPvt->nFree = 0; pdbmfPvt->freeList = NULL; - semGive(pdbmfPvt->sem); -} diff --git a/src/libCom/dbmf/dbmf.h b/src/libCom/dbmf/dbmf.h deleted file mode 100644 index 4d17ae0b7..000000000 --- a/src/libCom/dbmf/dbmf.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Author: Jim Kowalkowski and Marty Kraimer - * Date: 4/97 - * - * A library to manage storage that is allocated and then freed. - */ -#ifndef DBMF_H -#define DBMF_H - -#include "shareLib.h" - -epicsShareFunc int epicsShareAPI dbmfInit(size_t size, int chunkItems); -epicsShareFunc void * epicsShareAPI dbmfMalloc(size_t bytes); -epicsShareFunc void epicsShareAPI dbmfFree(void* bytes); -epicsShareFunc void epicsShareAPI dbmfFreeChunks(void); -epicsShareFunc int epicsShareAPI dbmfShow(int level); - -/* Rules: - * 1) Size is always made a multiple of 8. - * 2) if dbmfInit is not called before one of the other routines then it - * is automatically called with size=64 and initial_items=10 - * 3) These routines should only be used to allocate storage that will - * shortly thereafter be freed. - * 4) dbmfFreeChunks can only free chunks that contain only free items -*/ - -#endif diff --git a/src/libCom/ellLib/ellLib.c b/src/libCom/ellLib/ellLib.c deleted file mode 100644 index c6fa3fc0b..000000000 --- a/src/libCom/ellLib/ellLib.c +++ /dev/null @@ -1,830 +0,0 @@ -/* $Id$ - * - * Author: John Winans (ANL) - * Date: 07-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 jrw 07-02-92 created - * .02 rcz 08-26-92 moved to libCom - * .03 joh 12-12-97 added ellverify() - */ - -/* #define DEBUG_DRIVER */ - -#include - -#ifdef vxWorks -#include -#endif - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "ellLib.h" - -#if !defined(NULL) -#define NULL 0 -#endif - - /**************************************************************************** - * - * Initialize a new linked list header structure. - * - *****************************************************************************/ -#ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ -void epicsShareAPI ellInit (ELLLIST *pList) -#else -void epicsShareAPI ellInit (plist) -ELLLIST *plist; -#endif -{ - plist->node.next = NULL; - plist->node.previous = NULL; - plist->count = 0; - return; -} -#endif - /**************************************************************************** - * - * This function adds a node to the end of a linked list. - * - *****************************************************************************/ -#ifdef __STDC__ -void epicsShareAPI ellAdd (ELLLIST *pList, ELLNODE *pNode) -#else -void epicsShareAPI ellAdd (pList, pNode) -ELLLIST *pList; -ELLNODE *pNode; -#endif -{ - pNode->next = NULL; - pNode->previous = pList->node.previous; - - if (pList->count) - pList->node.previous->next = pNode; - else - pList->node.next = pNode; - - pList->node.previous = pNode; - pList->count++; - - return; -} - /**************************************************************************** - * - * This function concatinates the second linked list to the end of the first - * list. The second list is left empty. Either list (or both) lists may - * be empty at the begining of the operation. - * - *****************************************************************************/ -#ifdef __STDC__ -void epicsShareAPI ellConcat (ELLLIST *pDstList, ELLLIST *pAddList) -#else -void epicsShareAPI ellConcat (pDstList, pAddList) -ELLLIST *pDstList; -ELLLIST *pAddList; -#endif -{ - if (pAddList->count == 0) - return; /* Add list is empty, nothing to add. */ - - if (pDstList->count == 0) - { /* Destination list is empty... just transfer the add list over. */ - pDstList->node.next = pAddList->node.next; - pDstList->node.previous = pAddList->node.previous; - pDstList->count = pAddList->count; - } - else - { /* Destination list not empty... append the add list. */ - pDstList->node.previous->next = pAddList->node.next; - pAddList->node.next->previous = pDstList->node.previous; - pDstList->node.previous = pAddList->node.previous; - pDstList->count += pAddList->count; - } - - pAddList->count = 0; - pAddList->node.next = NULL; - pAddList->node.previous = NULL; - - return; -} - /**************************************************************************** - * - * This function returns the number of nodes that are found in a list. - * - *****************************************************************************/ -#ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ -int epicsShareAPI ellCount (ELLLIST *pList) -#else -int epicsShareAPI ellCount (pList) -ELLLIST *pList; -#endif -{ - return(pList->count); -} -#endif - /**************************************************************************** - * - * This function deletes a specific node from a specified list; - * - *****************************************************************************/ -#ifdef __STDC__ -void epicsShareAPI ellDelete (ELLLIST *pList, ELLNODE *pNode) -#else -void epicsShareAPI ellDelete (pList, pNode) -ELLLIST *pList; -ELLNODE *pNode; -#endif -{ - if (pList->node.previous == pNode) - pList->node.previous = pNode->previous; - else - pNode->next->previous = pNode->previous; - - if (pList->node.next == pNode) - pList->node.next = pNode->next; - else - pNode->previous->next = pNode->next; - - pList->count--; - - return; -} - /**************************************************************************** - * - * This function extracts a sublist that starts with pStartNode and ends with - * pEndNode from pSrcList and places it in pDstList. - * - * WRS is unclear as to what happens when pDstList is non-empty at the start - * of the operation. We will place the extracted list at the END of pDstList - * when it is non-empty. - * - *****************************************************************************/ -#ifdef __STDC__ -void epicsShareAPI ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList) -#else -void epicsShareAPI ellExtract (pSrcList, pStartNode, pEndNode, pDstList) -ELLLIST *pSrcList; -ELLNODE *pStartNode; -ELLNODE *pEndNode; -ELLLIST *pDstList; -#endif -{ - ELLNODE *pnode; - int count; - - /* Cut the list out of the source list (update count later) */ - if (pStartNode->previous != NULL) - pStartNode->previous->next = pEndNode->next; - else - pSrcList->node.next = pEndNode->next; - - if (pEndNode->next != NULL) - { - pEndNode->next->previous = pStartNode->previous; - pEndNode->next = NULL; - } - else - pSrcList->node.previous = pStartNode->previous; - - /* Place the sublist into the destination list */ - pStartNode->previous = pDstList->node.previous; - if (pDstList->count) - pDstList->node.previous->next = pStartNode; - else - pDstList->node.next = pStartNode; - - pDstList->node.previous = pEndNode; - - /* Adjust the counts */ - pnode = pStartNode; - count = 1; - while(pnode != pEndNode) - { - pnode = pnode->next; - count++; - } - pSrcList->count -= count; - pDstList->count += count; - - return; -} - /**************************************************************************** - * - * This function returns the first node in the specified list. The node is - * NOT removed from the list. If the list is empty, NULL will be returned. - * - *****************************************************************************/ -#ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ -ELLNODE * epicsShareAPI ellFirst (ELLLIST *pList) -#else -ELLNODE * epicsShareAPI ellFirst (pList) -ELLLIST *pList; -#endif -{ - return(pList->node.next); -} -#endif - /**************************************************************************** - * - * This function returns the first node in the specified list. The node is - * removed from the list. If the list is empty, NULL will be returned. - * - *****************************************************************************/ -#ifdef __STDC__ -ELLNODE * epicsShareAPI ellGet (ELLLIST *pList) -#else -ELLNODE * epicsShareAPI ellGet (pList) -ELLLIST *pList; -#endif -{ - ELLNODE *pnode = pList->node.next; - - if (pnode != NULL) - ellDelete(pList, pnode); - - return(pnode); -} - /**************************************************************************** - * - * This function inserts the specified node pNode after pPrev in the list - * plist. If pPrev is NULL, then pNode will be inserted at the head of the - * list. - * - *****************************************************************************/ -#ifdef __STDC__ -void epicsShareAPI ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode) -#else -void epicsShareAPI ellInsert (plist, pPrev, pNode) -ELLLIST *plist; -ELLNODE *pPrev; -ELLNODE *pNode; -#endif -{ - if (pPrev != NULL) - { - pNode->previous = pPrev; - pNode->next = pPrev->next; - pPrev->next = pNode; - } - else - { - pNode->previous = NULL; - pNode->next = plist->node.next; - plist->node.next = pNode; - } - if (pNode->next == NULL) - plist->node.previous = pNode; - else - pNode->next->previous = pNode; - - plist->count++; - - return; -} - /**************************************************************************** - * - * This function returns the last node in a list. The node is NOT removed - * from the list. If the list is empty, NULL will be returned. - * - *****************************************************************************/ -#ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ -ELLNODE * epicsShareAPI ellLast (ELLLIST *pList) -#else -ELLNODE * epicsShareAPI ellLast (pList) -ELLLIST *pList; -#endif -{ - return(pList->node.previous); -} -#endif - /**************************************************************************** - * - * This function returns the node following pNode. The node is NOT remodev from - * the list. If pNode is the last element in the list, NULL will be returned. - * - *****************************************************************************/ -#ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ -ELLNODE * epicsShareAPI ellNext (ELLNODE *pNode) -#else -ELLNODE * epicsShareAPI ellNext (pNode) -ELLNODE *pNode; -#endif -{ - return(pNode->next); -} -#endif - /**************************************************************************** - * - * This function returns the nodeNum'th element in pList. If there is no - * nodeNum'th node in the list, NULL will be returned. - * - *****************************************************************************/ -#ifdef __STDC__ -ELLNODE * epicsShareAPI ellNth (ELLLIST *pList, int nodeNum) -#else -ELLNODE * epicsShareAPI ellNth (pList, nodeNum) -ELLLIST *pList; -int nodeNum; -#endif -{ - ELLNODE *pnode; - - if ((nodeNum < 1)||(pList->count == 0)) - return(NULL); - - if (nodeNum > pList->count/2) - { - if (nodeNum > pList->count) - return(NULL); - - pnode = pList->node.previous; - nodeNum = pList->count - nodeNum; - while(nodeNum) - { - pnode = pnode->previous; - nodeNum--; - } - return(pnode); - } - - pnode = pList->node.next; - while(--nodeNum > 0) - pnode = pnode->next; - - return(pnode); -} - /**************************************************************************** - * - * This function returns the node that preceeds pNode. If pNode is the first - * element in the list, NULL will be returned. - * - *****************************************************************************/ -#ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ -ELLNODE * epicsShareAPI ellPrevious (ELLNODE *pNode) -#else -ELLNODE * epicsShareAPI ellPrevious (pNode) -ELLNODE *pNode; -#endif -{ - return(pNode->previous); -} -#endif - /**************************************************************************** - * - * This function returns the node, nStep nodes forward from pNode. If there is - * no node that many steps from pNode, NULL will be returned. - * - *****************************************************************************/ -#ifdef __STDC__ -ELLNODE * epicsShareAPI ellNStep (ELLNODE *pNode, int nStep) -#else -ELLNODE * epicsShareAPI ellNStep (pNode, nStep) -ELLNODE *pNode; -int nStep; -#endif -{ - if (nStep > 0) - { - while ((pNode != NULL) && nStep) - { - pNode = pNode->next; - nStep--; - } - } - else - { - while ((pNode != NULL) && nStep) - { - pNode = pNode->previous; - nStep++; - } - } - return(pNode); -} - /**************************************************************************** - * - * This function returns the node number of pNode within pList. If the node is - * not in pList, -1 is returned. Note that the first node is 1. - * - *****************************************************************************/ -#ifdef __STDC__ -int epicsShareAPI ellFind (ELLLIST *pList, ELLNODE *pNode) -#else -int epicsShareAPI ellFind (pList, pNode) -ELLLIST *pList; -ELLNODE *pNode; -#endif -{ - ELLNODE *got = pList->node.next; - int count = 1; - - while ((got != pNode) && (got != NULL)) - { - got = got->next; - count++; - } - if (got == NULL) - return(-1); - - return(count); -} - /**************************************************************************** - * - * This function frees the nodes in a list. It makes the list into an empty - * list, and free()'s all the nodes that are (were) in that list. - * - * NOTE: the nodes in the list are free()'d on the assumption that the node - * structures were malloc()'d one-at-a-time and that the ELLNODE structure is - * the first thing in the "rest of" the node structure. - * In other words, this is a pretty worthless function. - * - *****************************************************************************/ -#ifdef __STDC__ -void epicsShareAPI ellFree (ELLLIST *pList) -#else -void epicsShareAPI ellFree (pList) -ELLLIST *pList; -#endif -{ - ELLNODE *nnode = pList->node.next; - ELLNODE *pnode; - - while (nnode != NULL) - { - pnode = nnode; - nnode = nnode->next; - free(pnode); - } - pList->node.next = NULL; - pList->node.previous = NULL; - pList->count = 0; - - return; -} - - /**************************************************************************** - * - * This function verifies that the list is consistent. - * joh 12-12-97 - * - *****************************************************************************/ -void epicsShareAPI ellVerify (ELLLIST *pList) -{ - ELLNODE *pNode; - ELLNODE *pNext; - int count; - - assert (pList); - - count = 0u; - pNode = ellFirst(pList); - if (pNode) { - assert (ellPrevious(pNode)==NULL); - while (1) { - count++; - pNext = ellNext(pNode); - if (pNext) { - assert (ellPrevious(pNext)==pNode); - } - else { - break; - } - pNode = pNext; - } - assert (ellNext(pNode)==NULL); - } - - assert (pNode==ellLast(pList)); - assert (count==ellCount(pList)); -} - -#ifdef DEBUG_DRIVER - /**************************************************************************** - * - * This is a bunch of code that can be used to test the ellLib code. It is - * provided here so that you may use it if and when you decide to alter - * something in this file, you need not re-create it for testing purposes. - * - * In general, I believe that you will end up with a core dump if the tests - * fail. If all tests complete properly, there will be a: - * printf("All tests completed successful\n") - * to assure you of it. - * - *****************************************************************************/ - -#include -#undef NULL -#include - -struct myNode { - ELLNODE ellNode; - int list; - int num; -}; -main() -{ - ELLLIST list1; - ELLLIST list2; - int i1, i2, i3; - struct myNode *pmyNode, *pfirst, *pn1; - - printf("\nellInit() check... "); - list1.count = 27; - list1.node.next = (ELLNODE *) 0x01010101; - list1.node.previous = (ELLNODE *) 0x10101010; - - ellInit(&list1); - ellInit(&list2); - - if ((list1.count != 0)||(list1.node.next != NULL)||(list1.node.previous != NULL)) - { - printf("FAILED!!!"); - printf("list1.count %d, list1.node.next %08.8X, list1.node.previous %08.8X\n", list1.count, list1.node.next, list1.node.previous); - exit(1); - } - printf("ok"); - - - /* First build a couple lists and fill them with nodes. */ - printf("\nellAdd() check... "); - i1 = 2; - pmyNode = (struct myNode *) malloc(sizeof(struct myNode)); - pmyNode->ellNode.next = (ELLNODE *) 0x10101010; - pmyNode->ellNode.previous = (ELLNODE *) 0x10101010; - - ellAdd(&list1, pmyNode); - pmyNode->list = 1; - pmyNode->num = 1; - - if ((list1.count != 1)||(list1.node.next != (ELLNODE *)pmyNode)|| - (list1.node.previous != (ELLNODE *)pmyNode)||(pmyNode->ellNode.next != NULL)|| - (pmyNode->ellNode.previous != NULL)) - { - printf("FAILED!!!!!\n"); - exit(2); - } - pfirst = pmyNode; - while(i1 <= 21) /* put 21 nodes into LIST1 */ - { - pmyNode = (struct myNode *) malloc(sizeof(struct myNode)); - ellAdd(&list1, pmyNode); - pmyNode->list = 1; - pmyNode->num = i1; - i1++; - } - if ((list1.count != 21)||(list1.node.next != (ELLNODE *)pfirst)|| - (list1.node.previous != (ELLNODE *)pmyNode)||(pmyNode->ellNode.next != NULL)) - { - printf("FAILED!!!\n"); - exit(3); - } - printf("ok\nellFirst() check... "); - - if (ellFirst(&list1) != (ELLNODE *)pfirst) - { - printf("FAILED!!!\n"); - exit(5); - } - printf("ok\nellLast() check... "); - if (ellLast(&list1) != (ELLNODE *)pmyNode) - { - printf("FAILED!!!\n"); - exit(6); - } - printf("ok\nellNext() check... "); - if ((ellNext(pmyNode) != NULL)||(ellNext(pfirst) != (ELLNODE *)(pfirst->ellNode.next))) - { - printf("FAILED!!!\n"); - exit(7); - } - printf("ok\nellNth() check... "); - if ((ellNth(&list1, 0) != NULL)|| - ((pn1 = (struct myNode *)ellNth(&list1, 21)) != pmyNode)|| - (ellNth(&list1, 22) != NULL)|| - (ellNth(&list1, 1) != (ELLNODE *)(pfirst))|| - (ellNth(&list1, 2) != (ELLNODE *)(pfirst->ellNode.next))|| - (ellNth(&list1, 20) != (ELLNODE *)(pmyNode->ellNode.previous))) - { - printf("FAILED!!!\n"); - exit(8); - } - printf("ok\nellPrevious() check... "); - - if ((ellPrevious(pmyNode) != (ELLNODE *)(pmyNode->ellNode.previous))|| - (ellPrevious(pfirst) != NULL)|| - (ellPrevious(pfirst->ellNode.next) != (ELLNODE *)pfirst)) - { - printf("FAILED!!!\n"); - exit(9); - } - printf("ok\nellGet() check... "); - if (((pn1 = (struct myNode *)ellGet(&list1)) != pfirst)|| - (list1.node.next != pfirst->ellNode.next)) - { - printf("FAILED!!!\n"); - exit(10); - } - ellAdd(&list2, pn1); - if (((pn1 = (struct myNode *)ellGet(&list2)) != pfirst)|| - (list2.node.next != NULL)||(list2.node.previous != NULL)) - { - printf("FAILED!!!\n"); - exit(11); - } - printf("ok\nellCount() check... "); - if ((ellCount(&list1) != 20)||(ellCount(&list2) != 0)) - { - printf("FAILED!!!\n"); - exit(4); - } - printf("ok\nellConcat() check... "); - ellConcat(&list1, &list2); - if ((ellCount(&list1) != 20)||(ellCount(&list2) != 0)|| - (list1.node.previous != (ELLNODE *)pmyNode)) - { - printf("FAILED!!! (12)\n"); - exit(12); - } - ellAdd(&list2, pn1); - ellConcat(&list1, &list2); - if ((ellCount(&list1) != 21)||(ellCount(&list2) != 0)|| - (list1.node.previous != (ELLNODE *)pn1)|| - (list2.node.next != NULL)||(list2.node.previous!=NULL)) - { - printf("FAILED!!! (13)\n"); - printf("list1.count = %d list2.count = %d\n", ellCount(&list1), ellCount(&list2)); - exit(13); - } - printf("ok\nellDelete() check... "); - ellDelete(&list1, pn1); - if (ellCount(&list1) != 20) - { - printf("FAILED!!! (14)\n"); - exit(14); - } - printf("ok\nellFind() check... "); - ellAdd(&list2, pn1); - ellConcat(&list2, &list1); - i1 = -23; - if (ellFind(&list1, pn1) != -1) /* empty list */ - { - printf("FAILED!!! (15)\n"); - exit(15); - } - if ((i1 = ellFind(&list2, pn1)) != pn1->num) /* first node */ - { - printf("FAILED!!! (16)\n"); - exit(16); - } - pn1 = (struct myNode *)ellNth(&list2, 18); - if ((i1 = ellFind(&list2, pn1)) != 18) /* 18th node */ - { - printf("FAILED!!! (17)\n"); - exit(17); - } - printf("ok\nellInsert() check... "); - ellDelete(&list2, pn1); - ellInsert(&list2, NULL, pn1); /* move node 18 to top */ - if ((ellCount(&list2) != 21)||(((struct myNode *)(list2.node.next))->num != 18)) - { - printf("FAILED!!! (18)\n"); - exit (18); - } - if (ellFind(&list2, ellNth(&list2, 21)) != 21) - { /* Run thru all pointers to check integrity */ - printf("FAILED!!! (19)\n"); - exit(19); - } - pn1 = (struct myNode *)ellGet(&list2); - pmyNode = (struct myNode *)ellNth(&list2, 17); - ellInsert(&list2, pmyNode, pn1); - if (ellFind(&list2, ellNth(&list2, 21)) != 21) - { /* Run thru all pointers to check integrity */ - printf("FAILED!!! (20)\n"); - exit(20); - } - if ((((struct myNode *)(ellFirst(&list2)))->num != 1)|| - (((struct myNode *)(ellNth(&list2,17)))->num != 17)|| - (((struct myNode *)(ellNth(&list2,18)))->num != 18)) - { - printf("FAILED!!! (21)\n"); - exit(21); - } - pn1 = (struct myNode *)ellLast(&list2); - pmyNode = (struct myNode *) malloc(sizeof(struct myNode)); - ellInsert(&list2, pn1, pmyNode); - if ((ellCount(&list2) != 22)||(ellFind(&list2, ellNth(&list2, 22)) != 22)) - { - printf("FAILED!!! (33)\n"); - exit(33); - } - ellDelete(&list2, pmyNode); - free(pmyNode); - - printf("ok\nellExtract() check... "); - ellExtract(&list2, ellNth(&list2,9), ellNth(&list2, 19), &list1); - if ((ellCount(&list2) != 10)||(ellCount(&list1) != 11)) - { - printf("FAILED!!! (22)\n"); - exit(22); - } - if ((ellFind(&list2, ellNth(&list2, 10)) != 10)|| - (ellFind(&list1, ellNth(&list1, 11)) != 11)) - { - printf("FAILED!!! (23)\n"); - exit(23); - } - printf("ok\nellFree() check... "); - ellFree(&list2); - if (ellCount(&list2) != 0) - { - printf("FAILED!!! (24)\n"); - exit(24); - } - printf("ok\nellNStep() check... "); - pn1 = (struct myNode *)ellFirst(&list1); - i1 = 1; - while(pn1 != NULL) - { - pn1->num = i1++; - pn1 = (struct myNode *)ellNext(pn1); - } - pn1 = (struct myNode *)ellFirst(&list1); - if (pn1 == NULL) - { - printf("FAILED!!! (30)\n"); - exit(30); - } - pmyNode = (struct myNode *)ellNStep(pn1, 3); - if (pmyNode == NULL) - { - printf("FAILED!!! (27)\n"); - exit(27); - } - if (pmyNode->num != 4) - { - printf("FAILED!!! (25)\n"); - printf("got number %d\n", pmyNode->num); - exit(25); - - } - pmyNode = (struct myNode *)ellNStep(pn1, 30); - if (pmyNode != NULL) - { - printf("FAILED!!! (26)\n"); - exit(26); - } - pmyNode = (struct myNode *)ellNStep(pn1, 10); - if (pmyNode == NULL) - { - printf("FAILED!!! (28)\n"); - exit(28); - } - if (pmyNode->num != 11) - { - printf("FAILED!!! (29)\n"); - exit(29); - } - pmyNode = (struct myNode *)ellNStep(pmyNode, 0); - if (pmyNode->num != 11) - { - printf("FAILED!!! (31)\n"); - exit(31); - } - pmyNode = (struct myNode *)ellNStep(pmyNode, -4); - if (pmyNode->num != 7) - { - printf("FAILED!!! (32)\n"); - exit(32); - } - printf("ok\n\nAll tests completed successful\n"); -} -#endif diff --git a/src/libCom/ellLib/ellLib.h b/src/libCom/ellLib/ellLib.h deleted file mode 100644 index 8db17270d..000000000 --- a/src/libCom/ellLib/ellLib.h +++ /dev/null @@ -1,145 +0,0 @@ -/* ellLib.h $Id$ - * - * Author: John Winans (ANL) - * Date: 07-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 jrw 07-02-92 created - * .02 rcz 07-23-93 changed name - * .03 rcz 07-26-93 changed name again - * .04 joh 12-12-97 added ellverify() - */ -#ifndef INCellLibh -#define INCellLibh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -#define DLLLIB_USE_MACROS - -struct ELLNODE { - struct ELLNODE *next; - struct ELLNODE *previous; -}; -typedef struct ELLNODE ELLNODE; - -struct ELLLIST { - ELLNODE node; - int count; -}; -typedef struct ELLLIST ELLLIST; - -#if defined(__STDC__) || defined(__cplusplus) - -#ifdef DLLLIB_USE_MACROS - -#define ellInit(PLIST) { ((ELLLIST *)(PLIST))->node.next = NULL;\ - ((ELLLIST *)(PLIST))->node.previous = NULL;\ - ((ELLLIST *)(PLIST))->count = 0; } - -#define ellCount(PLIST) (((ELLLIST *)(PLIST))->count) - -#define ellFirst(PLIST) (((ELLLIST *)(PLIST))->node.next) - -#define ellLast(PLIST) (((ELLLIST *)(PLIST))->node.previous) - -#define ellNext(PNODE) (((ELLNODE *)(PNODE))->next) - -#define ellPrevious(PNODE) (((ELLNODE *)(PNODE))->previous) - -#else /*DLLLIB_USE_MACROS*/ - -epicsShareFunc void epicsShareAPI ellInit (ELLLIST *pList); -epicsShareFunc int epicsShareAPI ellCount (ELLLIST *pList); -epicsShareFunc ELLNODE * epicsShareAPI ellFirst (ELLLIST *pList); -epicsShareFunc ELLNODE * epicsShareAPI ellLast (ELLLIST *pList); -epicsShareFunc ELLNODE * epicsShareAPI ellNext (ELLNODE *pNode); -epicsShareFunc ELLNODE * epicsShareAPI ellPrevious (ELLNODE *pNode); - -#endif /*DLLLIB_USE_MACROS*/ - -epicsShareFunc void epicsShareAPI ellAdd (ELLLIST *pList, ELLNODE *pNode); -epicsShareFunc void epicsShareAPI ellConcat (ELLLIST *pDstList, ELLLIST *pAddList); -epicsShareFunc void epicsShareAPI ellDelete (ELLLIST *pList, ELLNODE *pNode); -epicsShareFunc void epicsShareAPI ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList); -epicsShareFunc ELLNODE * epicsShareAPI ellGet (ELLLIST *pList); -epicsShareFunc void epicsShareAPI ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode); -epicsShareFunc ELLNODE * epicsShareAPI ellNth (ELLLIST *pList, int nodeNum); -epicsShareFunc ELLNODE * epicsShareAPI ellNStep (ELLNODE *pNode, int nStep); -epicsShareFunc int epicsShareAPI ellFind (ELLLIST *pList, ELLNODE *pNode); -epicsShareFunc void epicsShareAPI ellFree (ELLLIST *pList); -epicsShareFunc void epicsShareAPI ellVerify (ELLLIST *pList); - -#else /*__STDC__*/ - -#ifdef DLLLIB_USE_MACROS - -#define ellInit(PLIST) { ((ELLLIST *)(PLIST))->node.next = NULL;\ - ((ELLLIST *)(PLIST))->node.previous = NULL;\ - ((ELLLIST *)(PLIST))->count = 0; } - -#define ellCount(PLIST) (((ELLLIST *)(PLIST))->count) - -#define ellFirst(PLIST) (((ELLLIST *)(PLIST))->node.next) - -#define ellLast(PLIST) (((ELLLIST *)(PLIST))->node.previous) - -#define ellNext(PNODE) (((ELLNODE *)(PNODE))->next) - -#define ellPrevious(PNODE) (((ELLNODE *)(PNODE))->previous) - -#else /*DLLLIB_USE_MACROS*/ - -void ellInit (); -int ellCount (); -ELLNODE *ellFirst (); -ELLNODE *ellNext (); -ELLNODE *ellLast (); -ELLNODE *ellPrevious (); - -#endif /*DLLLIB_USE_MACROS*/ - -epicsShareFunc void epicsShareAPI ellAdd (); -epicsShareFunc void epicsShareAPI ellConcat (); -epicsShareFunc void epicsShareAPI ellDelete (); -epicsShareFunc void epicsShareAPI ellExtract (); -epicsShareFunc ELLNODE * epicsShareAPI ellGet (); -epicsShareFunc void epicsShareAPI ellInsert (); -epicsShareFunc ELLNODE * epicsShareAPI ellNth (); -epicsShareFunc ELLNODE * epicsShareAPI ellNStep (); -epicsShareFunc int epicsShareAPI ellFind (); -epicsShareFunc void epicsShareAPI ellFree (); -epicsShareFunc void ellVerify (); - -#endif /*__STDC__*/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCellLibh*/ diff --git a/src/libCom/env/bldEnvData.pl b/src/libCom/env/bldEnvData.pl deleted file mode 100644 index 6e09c429f..000000000 --- a/src/libCom/env/bldEnvData.pl +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/perl -# -# Author: Kay-Uwe Kasemir -# based on bldEnvData shell scripts, Andrew Johnson (RGO) -# Date: 1-30-97 -# -# Experimental Physics and Industrial Control System (EPICS) -# -# tool to build envData.c from envDefs.h and config/CONFIG*ENV - -use Cwd; - -# We need exactly one argument: -$usage="Usage:\tbldEnvData "; -die $usage unless $#ARGV==0; - -$start_dir=cwd(); -$config_dir=$ARGV[0]; - -# Don't see a reason for this directory hopping, -# it's copied from the original: -chdir $config_dir or die "cannot change dir to $config_dir"; -$config_dir=cwd(); -chdir $start_dir; - -$SRC = "../envDefs.h"; -$env_data = "${config_dir}/CONFIG_ENV"; -$site_data= "${config_dir}/CONFIG_SITE_ENV"; -$out_name = "envData.c"; -$OUT = "> $out_name"; - -# $tool = basename of this script -$tool=$0; -$tool=~ s'.*/''; - - -# Start by extracting the ENV_PARAM declarations from $SRC -# i.e. gather the names of params we are interested in: -# -open SRC or die "Cannot open $SRC"; -while () -{ - if (m'epicsShareExtern[ \t]+READONLY[ \t]+ENV_PARAM[ \t]+([A-Za-z_]+)[ \t;]*') - { - $need_var{$1} = 1; - } -} -close SRC; - - - -# Read the default values from the config file into shell variables -sub GetVars -{ - my ($filename) = @_; - - open IN, $filename or die "Cannot read $filename"; - while () - { - # word space = space rest - if (m'([A-Za-z_]+)[ \t]*=[ \t]*(.*)') - { - $var = $1; - # Check if we need that variable: - next unless $need_var{$var}; - - # cosmetics: - # Some vars are given as "", - # so that $value{$var} is empty (=undefined). - # To avoid "no value for .." warning I use %have_value - $have_value{$var} = 1; - $value{$var} = $2; - # remove '"' - if ($value{$var} =~ m'"(.*)"') - { - $value{$var} = $1; - } - } - } - close IN; -} - -GetVars ($env_data); -GetVars ($site_data); - -# Generate header file -# - -print "Generating $out_name\n"; - -open OUT or die "cannot create $out_name"; - -# Write header -print OUT "/*\t$out_name\n"; -print OUT " *\n"; -print OUT " *\tcreated by $tool\n"; -print OUT " *\n"; -print OUT " *\tfrom:\n"; -print OUT " *\t$SRC\n"; -print OUT " *\t$env_data\n"; -print OUT " *\t$site_data\n"; -print OUT " *\n"; -print OUT " *\t" . localtime() . "\n"; -print OUT " *\n"; -print OUT " */\n"; -print OUT "\n"; -print OUT "#define epicsExportSharedSymbols\n"; -print OUT "#include \"envDefs.h\"\n"; -print OUT "\n"; - - -# Print variables -# -foreach $var ( sort keys %need_var ) -{ - if ($have_value{$var}) - { - $default = $value{$var}; - } - else - { - $default = ""; - print "Cannot find value for $var\n"; - } - - printf OUT "epicsShareDef READONLY ENV_PARAM %s = { \"%s\", \"%s\" };\n", - $var, $var, $default; -} - -# Now create an array pointing to all parameters - -print OUT "\n"; -print OUT "epicsShareDef READONLY ENV_PARAM* env_param_list[EPICS_ENV_VARIABLE_COUNT+1] =\n"; -print OUT "{\n"; - -# Contents are the addresses of each parameter -foreach $var ( sort keys %need_var ) -{ - print OUT "\t&$var,\n"; -} - -# Finally finish list with 0 -print OUT "\t0\n"; -print OUT "};\n"; -print OUT "\n"; -print OUT "/*\tEOF $out_name */\n"; - -close OUT; - -# EOF bldEnvData.pl diff --git a/src/libCom/env/envDefs.h b/src/libCom/env/envDefs.h deleted file mode 100644 index 6c996757c..000000000 --- a/src/libCom/env/envDefs.h +++ /dev/null @@ -1,141 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 07-20-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 07-20-91 rac initial version - * .02 08-07-91 joh added ioc log env - * .03 09-26-94 joh ifdef out double inclusion - * .04 11-28-94 joh new CA env var - * .05 04-20-95 anj moved defaults to CONFIG_ENV - * .06 09-11-96 joh ANSI prototypes - * .07 09-18-96 joh added envParamIsEmpty() - * .08 03-18-97 joh remove env param length limit - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE envDefs.h - definitions for environment get/set routines -* -* DESCRIPTION -* This file defines the environment parameters for EPICS. These -* ENV_PARAM's are initialized by $epics/share/bin/envSetupParams for -* use by EPICS programs running under UNIX and VxWorks. -* -* User programs can define their own environment parameters for their -* own use--the only caveat is that such parameters aren't automatically -* setup by EPICS. -* -* SEE ALSO -* $epics/share/bin/envSetupParams, envSubr.c -* -*-***************************************************************************/ - -#ifndef envDefsH -#define envDefsH - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" -#include "osiSock.h" - -typedef struct envParam { - char *name; /* text name of the parameter */ - char *pdflt; -} ENV_PARAM; - -/* - * bldEnvData looks for "epicsShareExtern READONLY ENV_PARAM" - */ -epicsShareExtern READONLY ENV_PARAM EPICS_CA_ADDR_LIST; -epicsShareExtern READONLY ENV_PARAM EPICS_CA_CONN_TMO; -epicsShareExtern READONLY ENV_PARAM EPICS_CA_BEACON_PERIOD; -epicsShareExtern READONLY ENV_PARAM EPICS_CA_AUTO_ADDR_LIST; -epicsShareExtern READONLY ENV_PARAM EPICS_CA_REPEATER_PORT; -epicsShareExtern READONLY ENV_PARAM EPICS_CA_SERVER_PORT; -epicsShareExtern READONLY ENV_PARAM EPICS_CAS_INTF_ADDR_LIST; -epicsShareExtern READONLY ENV_PARAM EPICS_CAS_BEACON_ADDR_LIST; -epicsShareExtern READONLY ENV_PARAM EPICS_CAS_SERVER_PORT; -epicsShareExtern READONLY ENV_PARAM EPICS_TS_MIN_WEST; -epicsShareExtern READONLY ENV_PARAM EPICS_TS_NTP_INET; -epicsShareExtern READONLY ENV_PARAM EPICS_IOC_LOG_PORT; -epicsShareExtern READONLY ENV_PARAM EPICS_IOC_LOG_INET; -epicsShareExtern READONLY ENV_PARAM EPICS_IOC_LOG_FILE_LIMIT; -epicsShareExtern READONLY ENV_PARAM EPICS_IOC_LOG_FILE_NAME; -epicsShareExtern READONLY ENV_PARAM EPICS_IOC_LOG_FILE_COMMAND; -epicsShareExtern READONLY ENV_PARAM EPICS_CMD_PROTO_PORT; -epicsShareExtern READONLY ENV_PARAM EPICS_AR_PORT; -#define EPICS_ENV_VARIABLE_COUNT 18 - -/* - * N elements added here to satisfy microsoft development tools - * (includes room for nill termination) - * - * bldEnvData looks for "epicsShareExtern ENV_PARAM" so - * this always needs to be divided into two lines - */ -epicsShareExtern READONLY ENV_PARAM - *env_param_list[EPICS_ENV_VARIABLE_COUNT+1]; - -#if defined(__STDC__) || defined(__cplusplus) -epicsShareFunc char * epicsShareAPI - envGetConfigParam(const ENV_PARAM *pParam, int bufDim, char *pBuf); -epicsShareFunc const char * epicsShareAPI - envGetConfigParamPtr(const ENV_PARAM *pParam); -epicsShareFunc long epicsShareAPI - envPrtConfigParam(const ENV_PARAM *pParam); -epicsShareFunc long epicsShareAPI - envSetConfigParam(const ENV_PARAM *pParam, char *value); -epicsShareFunc long epicsShareAPI - envGetInetAddrConfigParam(const ENV_PARAM *pParam, struct in_addr *pAddr); -epicsShareFunc long epicsShareAPI - envGetDoubleConfigParam(const ENV_PARAM *pParam, double *pDouble); -epicsShareFunc long epicsShareAPI - envGetLongConfigParam(const ENV_PARAM *pParam, long *pLong); -epicsShareFunc const char * epicsShareAPI - envGetConfigParamPtr(const ENV_PARAM *pParam); -#else -epicsShareFunc char * epicsShareAPI envGetConfigParam(); -epicsShareFunc char * epicsShareAPI envGetConfigParamPtr(); -epicsShareFunc long epicsShareAPI envPrtConfigParam(); -epicsShareFunc long epicsShareAPI envSetConfigParam(); -epicsShareFunc long epicsShareAPI envGetInetAddrConfigParam(); -epicsShareFunc long epicsShareAPI envGetDoubleConfigParam(); -epicsShareFunc long epicsShareAPI envGetLongConfigParam(); -epicsShareFunc char * epicsShareAPI envGetConfigParamPtr(); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /*envDefsH*/ - diff --git a/src/libCom/env/envSubr.c b/src/libCom/env/envSubr.c deleted file mode 100644 index 7752872e2..000000000 --- a/src/libCom/env/envSubr.c +++ /dev/null @@ -1,506 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 07-20-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 07-20-91 rac initial version - * .02 08-07-91 joh added config get for long and double C types - * .03 08-07-91 joh added config get for struct in_addr type - * .04 01-11-95 joh use getenv()/putenv() to fetch/write env - * vars under vxWorks - * .05 04-20-95 anj changes to use CONFIG_ENV - * .06 05-24-95 joh added return stmnt to epicsPrtEnvParams() - * .07 11-03-96 joh fixed bug occuring when diagnostic is - * printed and the env var cant be found - * .08 09-11-96 joh ANSI prototypes - * .09 10-18-96 joh added envParamIsEmpty() - * .10 03-18-97 joh added envGetConfigParamPtr() - * (replaces envParamIsEmpty()) - * .11 03-18-97 joh remove env param length limits - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE envSubr.c - routines to get and set EPICS environment parameters -* -* DESCRIPTION -* These routines are oriented for use with EPICS environment -* parameters under UNIX and VxWorks. They may be used for other -* purposes, as well. -* -* Many EPICS environment parameters are predefined in envDefs.h. -* -* QUICK REFERENCE -* #include "envDefs.h" -* ENV_PARAM param; -* char *envGetConfigParamPtr( pParam ) -* char *envGetConfigParam( pParam, bufDim, pBuf ) -* long envGetLongConfigParam( pParam, pLong ) -* long envGetDoubleConfigParam( pParam, pDouble ) -* long envGetInetAddrConfigParam( pParam, pAddr ) -* long envPrtConfigParam( pParam ) -* long envSetConfigParam( pParam, valueString ) -* -* SEE ALSO -* $epics/share/bin/envSetupParams, envDefs.h -* -*-***************************************************************************/ - -#include -#include -#include - -#ifdef vxWorks -#include -#include -#include -#endif - -#define epicsExportSharedSymbols -#include "errMdef.h" -#include "envDefs.h" -#include "epicsAssert.h" -#include "bsdSocketResource.h" - - -/*+/subr********************************************************************** -* NAME envGetConfigParamPtr - returns a pointer to the configuration -* parameter value string -* -* DESCRIPTION -* Returns a pointer to a configuration parameter value. -* If the configuration parameter isn't found in the environment, -* then a pointer to the default value for the parameter is copied. -* If no parameter is found and there is no default, then -* NULL is returned. -* -* RETURNS -* pointer to the environment variable value string, or -* NULL if no parameter value and no default value was found -* -* EXAMPLES -* 1. Get the value for the EPICS-defined environment parameter -* EPICS_TS_MIN_WEST. -* -* #include "envDefs.h" -* const char *pStr; -* -* pStr = envGetConfigParamPtr(&EPICS_TS_MIN_WEST); -* if (pStr) { -* printf("minutes west of UTC is: %s\n", pStr); -* } -* -*-*/ -const char * epicsShareAPI envGetConfigParamPtr( -const ENV_PARAM *pParam /* I pointer to config param structure */ -) -{ - const char *pEnv; /* pointer to environment string */ - - pEnv = getenv(pParam->name); - - if (pEnv == NULL) { - pEnv = pParam->pdflt; - } - - if (pEnv) { - if (pEnv[0u] == '\0') { - pEnv = NULL; - } - } - - return pEnv; -} - - -/*+/subr********************************************************************** -* NAME envGetConfigParam - get value of a configuration parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it -* into the caller's buffer. If the configuration parameter -* isn't found in the environment, then the default value for -* the parameter is copied. If no parameter is found and there -* is no default, then '\0' is copied and NULL is returned. -* -* RETURNS -* pointer to callers buffer, or -* NULL if no parameter value or default value was found -* -* EXAMPLES -* 1. Get the value for the EPICS-defined environment parameter -* EPICS_TS_MIN_WEST. -* -* #include "envDefs.h" -* char temp[80]; -* -* printf("minutes west of UTC is: %s\n", -* envGetConfigParam(&EPICS_TS_MIN_WEST, sizeof(temp), temp)); -* -* 2. Get the value for the DISPLAY environment parameter under UNIX. -* -* #include "envDefs.h" -* char temp[80]; -* ENV_PARAM display={"DISPLAY",""} -* -* if (envGetConfigParam(&display, sizeof(temp), temp) == NULL) -* printf("DISPLAY isn't defined\n"); -* else -* printf("DISPLAY is %s\n", temp); -* -*-*/ -char * epicsShareAPI envGetConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -int bufDim, /* I dimension of parameter buffer */ -char *pBuf /* I pointer to parameter buffer */ -) -{ - const char *pEnv; /* pointer to environment string */ - - pEnv = envGetConfigParamPtr(pParam); - if (!pEnv) { - return NULL; - } - - strncpy(pBuf, pEnv, bufDim-1); - pBuf[bufDim-1] = '\0'; - - return pBuf; -} - -/*+/subr********************************************************************** -* NAME envGetDoubleConfigParam - get value of a double configuration parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it into the -* caller's real (double) buffer. If the configuration parameter isn't -* found in the environment, then the default value for the parameter -* is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the caller's buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value for the real environment parameter EPICS_THRESHOLD. -* -* #include "envDefs.h" -* double threshold; -* long status; -* -* status = envGetDoubleConfigParam(&EPICS_THRESHOLD, &threshold); -* if (status == 0) { -* printf("the threshold is: %lf\n", threshold); -* } -* else { -* printf("%s could not be found or was not a real number\n", -* EPICS_THRESHOLD.name); -* } -* -*-*/ -long epicsShareAPI envGetDoubleConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -double *pDouble /* O pointer to place to store value */ -) -{ - char text[128]; - char *ptext; - int count; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext != NULL) { - count = sscanf(text, "%lf", pDouble); - if (count == 1) { - return 0; - } - (void)fprintf(stderr,"Unable to find a real number in %s=%s\n", - pParam->name, text); - } - - return -1; -} - -/*+/subr********************************************************************** -* NAME envGetInetAddrConfigParam - get value of an inet addr config parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it into -* the caller's (struct in_addr) buffer. If the configuration parameter -* isn't found in the environment, then the default value for -* the parameter is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the callers buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value for the inet address environment parameter EPICS_INET. -* -* #include "envDefs.h" -* struct in_addr addr; -* long status; -* -* status = envGetInetAddrConfigParam(&EPICS_INET, &addr); -* if (status == 0) { -* printf("the s_addr is: %x\n", addr.s_addr); -* } -* else { -* printf("%s could not be found or was not an inet address\n", -* EPICS_INET.name); -* } -* -*-*/ -long epicsShareAPI envGetInetAddrConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -struct in_addr *pAddr /* O pointer to struct to receive inet addr */ -) -{ - char text[128]; - char *ptext; - long status; - struct sockaddr_in sin; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext) { - status = aToIPAddr (text, 0u, &sin); - if (status == 0) { - *pAddr = sin.sin_addr; - return 0; - } - (void)fprintf(stderr,"Unable to find an IP address or valid host name in %s=%s\n", - pParam->name, text); - } - return -1; -} - -/*+/subr********************************************************************** -* NAME envGetLongConfigParam - get value of an integer config parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it -* into the caller's integer (long) buffer. If the configuration -* parameter isn't found in the environment, then the default value for -* the parameter is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the callers buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value as a long for the integer environment parameter -* EPICS_NUMBER_OF_ITEMS. -* -* #include "envDefs.h" -* long count; -* long status; -* -* status = envGetLongConfigParam(&EPICS_NUMBER_OF_ITEMS, &count); -* if (status == 0) { -* printf("and the count is: %d\n", count); -* } -* else { -* printf("%s could not be found or was not an integer\n", -* EPICS_NUMBER_OF_ITEMS.name); -* } -* -*-*/ -long epicsShareAPI envGetLongConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -long *pLong /* O pointer to place to store value */ -) -{ - char text[128]; - char *ptext; - int count; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext) { - count = sscanf(text, "%ld", pLong); - if (count == 1) - return 0; - (void)fprintf(stderr,"Unable to find an integer in %s=%s\n", - pParam->name, text); - } - return -1; -} - -/*+/subr********************************************************************** -* NAME envPrtConfigParam - print value of a configuration parameter -* -* DESCRIPTION -* Prints the value of a configuration parameter. -* -* RETURNS -* 0 -* -* EXAMPLE -* 1. Print the value for the EPICS-defined environment parameter -* EPICS_TS_MIN_WEST. -* -* #include "envDefs.h" -* -* envPrtConfigParam(&EPICS_TS_MIN_WEST); -* -*-*/ -long epicsShareAPI envPrtConfigParam( -const ENV_PARAM *pParam) /* pointer to config param structure */ -{ - const char *pVal; - - pVal = envGetConfigParamPtr(pParam); - if (pVal == NULL) - fprintf(stderr, "%s is undefined\n", pParam->name); - else - fprintf(stdout,"%s: %s\n", pParam->name, pVal); - return 0; -} - -/*+/subr********************************************************************** -* NAME envSetConfigParam - set value of a configuration parameter -* -* DESCRIPTION -* Sets the value of a configuration parameter. -* -* RETURNS -* 0 -* -* NOTES -* 1. Performs a useful function only under VxWorks. -* -* EXAMPLE -* 1. Set the value for the EPICS-defined environment parameter -* EPICS_TS_MIN_WEST to 360, for USA central time zone. -* -* Under UNIX: -* -* % setenv EPICS_TS_MIN_WEST 360 -* -* In a program running under VxWorks: -* -* #include "envDefs.h" -* -* envSetConfigParam(&EPICS_TS_MIN_WEST, "360"); -* -* Under the VxWorks command shell: -* -* envSetConfigParam &EPICS_TS_MIN_WEST,"360" -* -*-*/ -long epicsShareAPI envSetConfigParam ( -const ENV_PARAM *pParam, /* I pointer to config param structure */ -char *value /* I pointer to value string */ -) -{ -#ifndef vxWorks - fprintf(stderr, "envSetConfigParam can only be used under vxWorks\n"); - return -1L; -#else - long retCode = 0; - int status; - char *pEnv; - - /* - * space for two strings, an '=' character, - * and a null termination - */ - pEnv = malloc (strlen (pParam->name) + strlen (value) + 2); - if (!pEnv) { - errPrintf( - -1L, - __FILE__, - __LINE__, -"Failed to set environment parameter \"%s\" to \"%s\" because \"%s\"\n", - pParam->name, - value, - strerror (errnoGet())); - return -1L; - } - - strcpy (pEnv, pParam->name); - strcat (pEnv, "="); - strcat (pEnv, value); - status = putenv (pEnv); - if (status<0) { - errPrintf( - -1L, - __FILE__, - __LINE__, -"Failed to set environment parameter \"%s\" to \"%s\" because \"%s\"\n", - pParam->name, - value, - strerror (errnoGet())); - retCode = -1L; - } - /* - * vxWorks copies into a private buffer - * (this does not match UNIX behavior) - */ - free (pEnv); - - return retCode; -#endif -} - -/*+/subr********************************************************************** -* NAME epicsPrtEnvParams - print value of all configuration parameters -* -* DESCRIPTION -* Prints all configuration parameters and their current value. -* -* RETURNS -* 0 -* -* EXAMPLE -* 1. Print the value for all EPICS-defined environment parameters. -* -* #include "envDefs.h" -* -* epicsPrtEnvParams(); -* -*-*/ -long -epicsPrtEnvParams() -{ - const ENV_PARAM **ppParam = env_param_list; - - while (*ppParam != NULL) - envPrtConfigParam(*(ppParam++)); - - return 0; -} - diff --git a/src/libCom/epicsEnvParams.h b/src/libCom/epicsEnvParams.h deleted file mode 100644 index cb7b62078..000000000 --- a/src/libCom/epicsEnvParams.h +++ /dev/null @@ -1,18 +0,0 @@ -/* $Id$ - * $Log$ - * Revision 1.3 1994/11/01 14:55:15 jba - * set values for ANL/APS/ASD - * - * Revision 1.2 1994/09/09 12:40:30 mrk - * Removed env variables for old time support. New uses standard Unix methods. - * - * Revision 1.1 1994/07/17 07:14:24 bordua - * Initial version. - * - */ -/*These are env variables meant to be modified by each epics site*/ - -char *EPICS_TS_MIN_VALUE= "360"; -char *EPICS_IOC_LOG_VALUE= "164.54.8.167"; -char *EPICS_IOC_FILE_VALUE= "1000000"; -char *EPICS_IOC_LOG_FILE_TXT= "/home/phebos1/epics/apple/log/iocLog.text"; diff --git a/src/libCom/error/epicsPrint.h b/src/libCom/error/epicsPrint.h deleted file mode 100644 index 3f66530ce..000000000 --- a/src/libCom/error/epicsPrint.h +++ /dev/null @@ -1,9 +0,0 @@ -/*epicsPrint.h */ - -/*This is now obsolete. Remlaced by errlog.h */ -#ifndef INCepicsPrintH -#define INCepicsPrintH - -#include "errlog.h" - -#endif /*INCepicsPrintH*/ diff --git a/src/libCom/error/errMdef.h b/src/libCom/error/errMdef.h deleted file mode 100644 index 901f25b7c..000000000 --- a/src/libCom/error/errMdef.h +++ /dev/null @@ -1,125 +0,0 @@ -/* errMdef.h err.h - Error Handling definitions */ -/* share/epicsH $Id$ */ -/* - * 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 mm-dd-yy iii Comment - * .02 12-02-91 jrw added GPIB and BB message codes - * .03 03-11-93 joh added __FILE__ and __LINE__ to errMessage() - * .04 04-01-93 joh added vxi - * .05 04-29-93 joh added errPrintStatus() func proto - * .06 09-04-93 rcz added functions ... for errSymLib.c merge - * .07 02-03-94 mrk RTN_SUCCESS is true only if status=0 - * .08 02-03-94 mrk Add access security library - * .09 05-23-95 joh Add bucket hashing library - */ - -#ifndef INCerrMdefh -#define INCerrMdefh - -#ifdef __cplusplus -extern "C" { -#define errMDefUseProtoANSI -#endif - -#ifdef __STDC__ -#ifndef errMDefUseProtoANSI -#define errMDefUseProtoANSI -#endif -#endif - -#ifdef errMDefUseProtoANSI -# include -#else -# include -#endif - -#include "ellLib.h" -#include "shareLib.h" - -/*The following is only included because before 3.13.0beta12 errMessage */ -/*and errPrintf were defined here */ -#include "errlog.h" - -#define RTN_SUCCESS(STATUS) ((STATUS)==0) - -#define M_dbAccess (501 <<16) /*Database Access Routines */ -#define M_drvSup (503 <<16) /*Driver Support*/ -#define M_devSup (504 <<16) /*Device Support*/ -#define M_recSup (505 <<16) /*Record Support*/ -#define M_recType (506 <<16) /*Record Type*/ -#define M_record (507 <<16) /*Database Records*/ -#define M_ar (508 <<16) /*Archiver; see arDefs.h*/ -#define M_ts (509 <<16) /*Time Stamp Routines; see tsDefs.h*/ -#define M_arAcc (510 <<16) /*Archive Access Library Routines*/ -#define M_bf (511 <<16) /*Block File Routines; see bfDefs.h*/ -#define M_syd (512 <<16) /*Sync Data Routines; see sydDefs.h*/ -#define M_ppr (513 <<16) /*Portable Plot Routines; see pprPlotDefs.h*/ -#define M_env (514 <<16) /*Environment Routines; see envDefs.h*/ -#define M_gen (515 <<16) /*General Purpose Routines; see genDefs.h*/ -#define M_gpib (516 <<16) /*Gpib driver & device support; see drvGpibInterface.h*/ -#define M_bitbus (517 <<16) /*Bitbus driver & device support; see drvBitBusInterface.h*/ -#define M_dbLib (519 <<16) /*Static Database Access */ -#define M_epvxi (520 <<16) /*VXI Driver*/ -#define M_devLib (521 <<16) /*Device Resource Registration*/ -#define M_asLib (522 <<16) /*Access Security */ -#define M_cas (523 <<16) /*CA server*/ -#define M_casApp (524 <<16) /*CA server application*/ -#define M_bucket (525 <<16) /*Bucket Hash*/ -#define M_gddFuncTbl (526 <<16) /*gdd jump table*/ - -#ifdef errMDefUseProtoANSI -epicsShareFunc int epicsShareAPI errSymFind(long status, char *name); -epicsShareFunc int epicsShareAPI UnixSymFind(long status, char *name, long *value); -epicsShareFunc int epicsShareAPI ModSymFind(long status, char *name, long *value); -epicsShareFunc void epicsShareAPI errSymTest(unsigned short modnum, unsigned short begErrNum, unsigned short endErrNum); -epicsShareFunc void epicsShareAPI errSymTestPrint(long errNum); -epicsShareFunc int epicsShareAPI errSymBld(); -epicsShareFunc int epicsShareAPI errSymbolAdd (long errNum,char *name); -epicsShareFunc void epicsShareAPI errSymDump(); -epicsShareFunc void epicsShareAPI tstErrSymFind(); - -#else /* errMDefUseProtoANSI */ - -epicsShareFunc void epicsShareAPI errSymTest(); -epicsShareFunc int epicsShareAPI errSymFind(); -epicsShareFunc int epicsShareAPI UnixSymFind(); -epicsShareFunc int epicsShareAPI ModSymFind(); -epicsShareFunc void epicsShareAPI errSymTestPrint(); -epicsShareFunc int epicsShareAPI errSymBld(); -epicsShareFunc int epicsShareAPI errSymbolAdd(); -epicsShareFunc void epicsShareAPI errSymDump(); -epicsShareFunc void epicsShareAPI tstErrSymFind(); -#endif /* errMDefUseProtoANSI */ - -extern int errVerbose; - -#ifdef __cplusplus -} -#endif - -#endif /*INCerrMdefh*/ diff --git a/src/libCom/error/errSymLib.c b/src/libCom/error/errSymLib.c deleted file mode 100644 index ff912e34f..000000000 --- a/src/libCom/error/errSymLib.c +++ /dev/null @@ -1,456 +0,0 @@ -/* $Id$ - * errSymLib.c - * 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: errSymLib.c - * ----------------- - * .01 mm-dd-yy rcz See below for Creation/Merge - **** Merged Modification Logs: - * Modification Log: errMessage.c - * ----------------- - * .01 10-08-91 mrk Allow logMsg or printF - * .02 03-10-93 joh expanded errMessage() to accept the - * same format string and variable - * length arguments as printf() - * and renamed it errPrintf() - * .03 03-11-93 joh added __FILE__ and __LINE__ to errPrintf() - * created macro errMessage() that calls - * errPrintf with __FILE__ and __LINE__ - * as arguments - * errMessage.c - Handle error messages - *************************************************************************** - * This must ultimately be replaced by a facility that allows remote - * nodes access to the error messages. A message handling communication - * task should be written that allows multiple remote nodes to request - * notification of all error messages. - * For now lets just print messages and last errno via logMsg or printf - *************************************************************************** - * Modification Log: errPrint.c - * ----------------- - * .01 10-08-91 mrk Allow logMsg or printf - * .02 04-29-93 joh extra arg for errPrint() - * .03 04-29-93 joh errPrint() became errPrintStatus() - * .04 05-06-93 joh errPrintStatus() get var args - * for vprintf() - * .05 05-02-94 joh errToLogMsg now defaults to TRUE - * - * Modification Log: errSymLib.c - * ----------------- - * .01 09-04-93 rcz Merged errMessage.c, errPrint.c, errSymFind.c - * rcz into one file (errSymLib.c) and changed method - * rcz of errSymTable lookup. - * .02 01-13-95 joh call mprintf() instead of logMsg() - * and eliminated errToLogMsg variable - */ - -#include -#include -#include -#include - -#ifdef vxWorks -#include -#include -#include -#include -#include - -extern SYMTAB_ID statSymTbl; - -#endif - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "errMdef.h" -#include "errSymTbl.h" - - -#ifdef __STDC__ -static unsigned short errhash(long errNum); -#else /*__STDC__*/ -static unsigned short errhash(); -#endif /*__STDC__*/ - - -#ifdef vxWorks -#define MYERRNO (errnoGet()&0xffff) -#else -#define MYERRNO errno -#endif - -typedef struct errnumnode { - ELLNODE node; - long errNum; - struct errnumnode *hashnode; - char *message; - long pad; -} ERRNUMNODE; -#define NHASH 256 - - -static ELLLIST errnumlist; -static ERRNUMNODE **hashtable; -static int initialized = FALSE; -extern ERRSYMTAB_ID errSymTbl; - - -/*Declare storage for errVerbose( defined in errMdef.h)*/ -int errVerbose=0; - - - -/**************************************************************** - * ERRSYMBLD - * - * Create the normal ell LIST of sorted error messages nodes - * Followed by linked hash lists - that link together those - * ell nodes that have a common hash number. - * - ***************************************************************/ -int epicsShareAPI errSymBld() -{ - ERRSYMBOL *errArray = errSymTbl->symbols; - ELLLIST *perrnumlist = &errnumlist; - ERRNUMNODE *perrNumNode = NULL; - ERRNUMNODE *pNextNode = NULL; - ERRNUMNODE **phashnode = NULL; - int i; - int modnum; - unsigned short hashInd; - - if(initialized) return(0); - hashtable = (ERRNUMNODE**)calloc(NHASH, sizeof(ERRNUMNODE*)); - if(!hashtable) { - printf("errSymBld: Can't allocate storage\n"); -#ifdef vxWorks - taskSuspend(0); -#else - abort(); -#endif - } - for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { - modnum = errArray->errNum >> 16; - if (modnum < 501) { - printf("errSymBld: ERROR - Module number in errSymTbl < 501 was Module=%lx Name=%s\n", - errArray->errNum, errArray->name); - continue; - } - if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) { - printf("errSymBld: ERROR - errSymbolAdd() failed \n"); - continue; - } - } - perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist); - while (perrNumNode) { - /* hash each perrNumNode->errNum */ - hashInd = errhash(perrNumNode->errNum); - phashnode = (ERRNUMNODE**)&hashtable[hashInd]; - pNextNode = (ERRNUMNODE*) *phashnode; - /* search for last node (NULL) of hashnode linked list */ - while (pNextNode) { - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - *phashnode = perrNumNode; - perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); - } - initialized = TRUE; - return(0); -} - - - -/**************************************************************** - * HASH - * returns the hash index of errNum -****************************************************************/ -#ifdef __STDC__ -static -unsigned short errhash(long errNum) -#else -static -unsigned short errhash(errNum) -long errNum; -#endif /* __STDC__ */ -{ -unsigned short modnum; -unsigned short errnum; - - modnum = (unsigned short) (errNum >> 16); - errnum = (unsigned short) (errNum & 0xffff); - return((unsigned short)(((modnum - 500) * 20) + errnum) % NHASH); -} - -/**************************************************************** - * ERRSYMBOLADD - * adds symbols to the master errnumlist as compiled from errSymTbl.c - ***************************************************************/ -#ifdef __STDC__ -int epicsShareAPI errSymbolAdd (long errNum,char *name) -#else -int epicsShareAPI errSymbolAdd (errNum,name) -long errNum; -char *name; -#endif /* __STDC__ */ -{ - ELLLIST *perrnumlist = &errnumlist; - ERRNUMNODE *pNew; - - pNew = (ERRNUMNODE*)calloc(1, sizeof(ERRNUMNODE)); - if(!pNew) { - printf("errSymbolAdd: Can't allocate storage\n"); -#ifdef vxWorks - taskSuspend(0); -#else - abort(); -#endif - } - pNew->errNum = errNum; - pNew->message = name; - ellAdd(perrnumlist,(ELLNODE*)pNew); - return(0); -} - -/**************************************************************** - * UNIXSYMFIND - ***************************************************************/ -/* - * Use of sys_nerr and sys_errlist in this routine - * present portability problems - * - * ANSI strerror() provides this functionality - * so this is hopefully no longer needed - * joh 10-02-96 - * - */ -#if 0 -#ifndef vxWorks -#ifdef __STDC__ -int epicsShareAPI UnixSymFind(long status, char *pname, long *pvalue) -#else -int epicsShareAPI UnixSymFind(status, pname, pvalue) - long status; - char *pname; - long *pvalue; -#endif /* __STDC__ */ -{ - if(!initialized) errSymBld(); - if (status >= sys_nerr || status < 1) { - *pvalue = -1; - return(0); - } - strcpy(pname, sys_errlist[status]); - *pvalue = status; - return(0); -} -#endif -#endif - - -/**************************************************************** - * MODSYMFIND - ***************************************************************/ -#ifdef __STDC__ -int epicsShareAPI ModSymFind(long status, char *pname, long *pvalue) -#else -int epicsShareAPI ModSymFind(status, pname, pvalue) - long status; - char *pname; - long *pvalue; -#endif /* __STDC__ */ -{ - unsigned short modNum; - unsigned short hashInd; - ERRNUMNODE *pNextNode; - ERRNUMNODE **phashnode = NULL; - - if(!initialized) errSymBld(); - modNum = (unsigned short) (status >> 16); - if (modNum < 501) { - *pvalue = -1; - return(0); - } - hashInd = errhash(status); - phashnode = (ERRNUMNODE**)&hashtable[hashInd]; - pNextNode = *phashnode; - while (pNextNode) { - if (pNextNode->errNum == status) { - strcpy(pname, pNextNode->message); - *pvalue = status; - return(0); - } - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - *pname = 0; - *pvalue = -1; - return(0); -} - -/**************************************************************** - * ERRSYMFIND - ***************************************************************/ -#ifdef __STDC__ -int epicsShareAPI errSymFind(long status, char *name) -#else -/* errSymFind - Locate error symbol */ -int epicsShareAPI errSymFind(status, name) - long status; - char *name; -#endif /* __STDC__ */ -{ - long value; -#ifdef vxWorks - unsigned char type; -#endif - unsigned short modnum; - - if (!initialized) errSymBld(); - - modnum = (unsigned short) (status >> 16); - if (modnum <= 500) -#ifdef vxWorks - symFindByValue((SYMTAB_ID)statSymTbl, status, name,(int*) &value, (SYM_TYPE*)&type); -#else - { - const char *pStr = strerror(status); - if (pStr) { - strcpy(name,strerror(status)); - value = status; - } - else { - sprintf(name,"err = %ld", status); - } - } -#endif - else - ModSymFind(status, name, &value); - if (value != status) - return (-1); - else - return (0); -} - - -/**************************************************************** - * errSymDump - ***************************************************************/ -#ifdef __STDC__ -void epicsShareAPI errSymDump() -#else -void epicsShareAPI errSymDump() -#endif /* __STDC__ */ -{ -ERRNUMNODE **phashnode = NULL; -ERRNUMNODE *pNextNode; -int i; -int modnum; -int errnum; -int msgcount; -int firstTime; - - if (!initialized) errSymBld(); - - msgcount = 0; - printf("errSymDump: number of hash slots=%d\n", NHASH); - for ( i=0; i < NHASH; i++) { - phashnode = &hashtable[i]; - pNextNode = *phashnode; - firstTime=1; - while (pNextNode) { - if (firstTime) { - printf("HASHNODE=%d\n", i); - firstTime=0; - } - modnum = pNextNode->errNum >> 16; - errnum = pNextNode->errNum & 0xffff; - printf("\tmod %d num %d \"%s\"\n" - , modnum , errnum , pNextNode->message); - msgcount++; - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - } - printf("\nerrSymDump: total number of error messages=%d\n", msgcount); -} - - -/**************************************************************** - * errSymTestPrint - ***************************************************************/ -#ifdef __STDC__ -void epicsShareAPI errSymTestPrint(long errNum) -#else -void epicsShareAPI errSymTestPrint(errNum) -long errNum; -#endif /* __STDC__ */ -{ - char message[256]; - unsigned short modnum; - unsigned short errnum; - - if (!initialized) errSymBld(); - - message[0] = '\0'; - modnum = (unsigned short) (errNum >> 16); - errnum = (unsigned short) (errNum & 0xffff); - if (modnum < 501) { - printf("Usage: errSymTestPrint(long errNum) \n"); - printf("errSymTestPrint: module number < 501 \n"); - return; - } - errSymFind(errNum, message); - if ( message[0] == '\0' ) return; - printf("module %hu number %hu message=\"%s\"\n", - modnum, errnum, message); - return; -} - -/**************************************************************** - * ERRSYMTEST -****************************************************************/ -#ifdef __STDC__ -void epicsShareAPI errSymTest(unsigned short modnum, unsigned short begErrNum, unsigned short endErrNum) -#else -void epicsShareAPI errSymTest(modnum, begErrNum, endErrNum) -unsigned short modnum; -unsigned short begErrNum; -unsigned short endErrNum; -#endif /* __STDC__ */ -{ - long errNum; - unsigned short errnum; - - if(!initialized) errSymBld(); - if (modnum < 501) - return; - - /* print range of error messages */ - for (errnum = begErrNum; errnum <= endErrNum; errnum++) { - errNum = modnum << 16; - errNum |= (errnum & 0xffff); - errSymTestPrint(errNum); - } -} diff --git a/src/libCom/error/errSymTbl.h b/src/libCom/error/errSymTbl.h deleted file mode 100644 index 8c219fe29..000000000 --- a/src/libCom/error/errSymTbl.h +++ /dev/null @@ -1,24 +0,0 @@ - -#ifndef INCerrSymTblh -#define INCerrSymTblh 1 - -#ifndef NELEMENTS -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) -#endif -#define LOCAL static - -typedef struct /* ERRSYMBOL - entry in symbol table */ - { - char *name; /* pointer to symbol name */ - long errNum; /* errMessage symbol number */ - } ERRSYMBOL; -typedef struct /* ERRSYMTAB - symbol table */ - { - short nsymbols; /* current number of symbols in table */ - ERRSYMBOL *symbols; /* ptr to array of symbol entries */ - } ERRSYMTAB; -typedef ERRSYMTAB *ERRSYMTAB_ID; - - -#endif /* INCerrSymTblh */ diff --git a/src/libCom/error/errlog.c b/src/libCom/error/errlog.c deleted file mode 100644 index 9adc3da69..000000000 --- a/src/libCom/error/errlog.c +++ /dev/null @@ -1,481 +0,0 @@ -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ -/* - * Author: Marty Kraimer and Jeff Hill - * Date: 07JAN1998 - * NOTE: Original version is adaptation of old version of errPrintfVX.c -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ERRLOG_INIT -#include "epicsAssert.h" -#include "errMdef.h" -#include "error.h" -#include "ellLib.h" -#include "task_params.h" -#include "errlog.h" - - -#ifndef LOCAL -#define LOCAL static -#endif /* LOCAL */ - -#define BUFFER_SIZE 1280 -#define MAX_MESSAGE_SIZE 256 -#define TRUNCATE_SIZE 80 -#define MAX_ALIGNMENT 8 - -LOCAL void errlogTask(void); - -LOCAL char *msgbufGetFree(void); -LOCAL void msgbufSetSize(int size); -LOCAL char * msgbufGetSend(void); -LOCAL void msgbufFreeSend(void); - -LOCAL void *pvtCalloc(size_t count,size_t size); -LOCAL void pvtSemTake(SEM_ID semid); - -typedef struct listenerNode{ - ELLNODE node; - errlogListener listener; -}listenerNode; - -/*each message consists of a msgNode immediately followed by the message */ -typedef struct msgNode { - ELLNODE node; - char *message; - int length; -} msgNode; - -LOCAL struct { - SEM_ID errlogTaskWaitForWork; - SEM_ID msgQueueLock; - SEM_ID listenerLock; - ELLLIST listenerList; - ELLLIST msgQueue; - msgNode *pnextSend; - int buffersize; - int sevToLog; - int toConsole; - int missedMessages; - void *pbuffer; -}pvtData; - -epicsShareFunc int epicsShareAPIV errlogPrintf( const char *pFormat, ...) -{ - va_list pvar; - int nchar; - - if(INT_CONTEXT()) { - logMsg("errlogPrintf called from interrupt level\n",0,0,0,0,0,0); - return 0; - } - errlogInit(0); - va_start(pvar, pFormat); - nchar = errlogVprintf(pFormat,pvar); - va_end (pvar); - return(nchar); -} - -epicsShareFunc int epicsShareAPIV errlogVprintf( - const char *pFormat,va_list pvar) -{ - int nchar; - char *pbuffer; - - if(INT_CONTEXT()) { - logMsg("errlogVprintf called from interrupt level\n",0,0,0,0,0,0); - return 0; - } - errlogInit(0); - pbuffer = msgbufGetFree(); - if(!pbuffer) return(0); - nchar = vsprintf(pbuffer,pFormat,pvar); - msgbufSetSize(nchar+1);/*include the \0*/ - return nchar; -} - -epicsShareFunc int epicsShareAPI errlogMessage(const char *message) -{ - int status; - char *pbuffer; - - if(INT_CONTEXT()) { - status = logMsg ("errlogMessage called from interrupt level %s", - message,0,0,0,0,0); - return 0; - } - errlogInit(0); - pbuffer = msgbufGetFree(); - if(!pbuffer) return(0); - strcpy(pbuffer,message); - msgbufSetSize(strlen(message) +1); - return 0; -} - -epicsShareFunc int epicsShareAPIV errlogSevPrintf( - const errlogSevEnum severity,const char *pFormat, ...) -{ - va_list pvar; - int nchar; - - if(INT_CONTEXT()) { - logMsg("errlogSevPrintf called from interrupt level\n",0,0,0,0,0,0); - return 0; - } - errlogInit(0); - if(pvtData.sevToLog>severity) return(0); - va_start(pvar, pFormat); - nchar = errlogSevVprintf(severity,pFormat,pvar); - va_end (pvar); - return(nchar); -} - -epicsShareFunc int epicsShareAPIV errlogSevVprintf( - const errlogSevEnum severity,const char *pFormat,va_list pvar) -{ - char *pnext; - int nchar; - int totalChar=0; - - if(pvtData.sevToLog>severity) return(0); - if(INT_CONTEXT()) { - logMsg("errlogSevVprintf called from interrupt level\n",0,0,0,0,0,0); - return 0; - } - errlogInit(0); - pnext = msgbufGetFree(); - if(!pnext) return(0); - nchar = sprintf(pnext,"sevr=%s ",errlogGetSevEnumString(severity)); - pnext += nchar; totalChar += nchar; - nchar = vsprintf(pnext,pFormat,pvar); - pnext += nchar; totalChar += nchar; - sprintf(pnext,"\n"); - totalChar += 2; /*include \n and \0*/ - msgbufSetSize(totalChar); - return(nchar); -} - -epicsShareFunc char * epicsShareAPI errlogGetSevEnumString( - const errlogSevEnum severity) -{ - static char unknown[] = "unknown"; - - errlogInit(0); - if(severity<0 || severity>3) return(unknown); - return(errlogSevEnumString[severity]); -} - -epicsShareFunc void epicsShareAPI errlogSetSevToLog( - const errlogSevEnum severity ) -{ - errlogInit(0); - pvtData.sevToLog = severity; -} - -epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog() -{ - errlogInit(0); - return(pvtData.sevToLog); -} - -epicsShareFunc void epicsShareAPI errlogAddListener( - errlogListener listener) -{ - listenerNode *plistenerNode; - - errlogInit(0); - plistenerNode = pvtCalloc(1,sizeof(listenerNode)); - pvtSemTake(pvtData.listenerLock); - plistenerNode->listener = listener; - ellAdd(&pvtData.listenerList,&plistenerNode->node); - semGive(pvtData.listenerLock); -} - -epicsShareFunc void epicsShareAPI errlogRemoveListener( - errlogListener listener) -{ - listenerNode *plistenerNode; - - errlogInit(0); - pvtSemTake(pvtData.listenerLock); - plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList); - while(plistenerNode) { - if(plistenerNode->listener==listener) { - ellDelete(&pvtData.listenerList,&plistenerNode->node); - free((void *)plistenerNode); - break; - } - plistenerNode = (listenerNode *)ellNext(&plistenerNode->node); - } - semGive(pvtData.listenerLock); - if(!plistenerNode) printf("errlogRemoveListener did not find listener\n"); -} - -epicsShareFunc int epicsShareAPI eltc(int yesno) -{ - errlogInit(0); - pvtData.toConsole = yesno; - return(0); -} - -epicsShareFunc void epicsShareAPIV errPrintf(long status, const char *pFileName, - int lineno, const char *pformat, ...) -{ - va_list pvar; - char *pnext; - int nchar; - int totalChar=0; - - if(INT_CONTEXT()) { - logMsg("errPrintf called from interrupt level\n",0,0,0,0,0,0); - return; - } - errlogInit(0); - pnext = msgbufGetFree(); - if(!pnext) return; - if(pFileName){ - nchar = sprintf(pnext,"filename=\"%s\" line number=%d\n", - pFileName, lineno); - pnext += nchar; totalChar += nchar; - } - if(status==0) status = MYERRNO; - if(status>0) { - int rtnval; - char name[256]; - - rtnval = errSymFind(status,name); - if(rtnval) { - unsigned short modnum,errnum; - - modnum = status >> 16; errnum = status & 0xffff; - nchar = sprintf(pnext, "status (%hu,%hu) not in symbol table ", - modnum, errnum); - } else { - nchar = sprintf(pnext,"%s ",name); - } - pnext += nchar; totalChar += nchar; - } - va_start (pvar, pformat); - nchar = vsprintf(pnext,pformat,pvar); - va_end (pvar); - if(nchar>0) { - pnext += nchar; - totalChar += nchar; - } - sprintf(pnext,"\n"); - totalChar += 2; /*include the \n and the \0*/ - msgbufSetSize(totalChar); -} - -#define optionsSemM SEM_Q_PRIORITY|SEM_DELETE_SAFE|SEM_INVERSION_SAFE -epicsShareFunc int epicsShareAPI errlogInit(int bufsize) -{ - static int errlogInitFlag=0; - void *pbuffer;; - - if(!vxTas(&errlogInitFlag)) return(0); - if(bufsizelistener)(pmessage); - plistenerNode = (listenerNode *)ellNext(&plistenerNode->node); - } - semGive(pvtData.listenerLock); - msgbufFreeSend(); - } - } -} - -LOCAL msgNode *msgbufGetNode() -{ - char *pbuffer = (char *)pvtData.pbuffer; - msgNode *pnextSend = 0; - - if(ellCount(&pvtData.msgQueue) == 0 ) { - pnextSend = (msgNode *)pbuffer; - } else { - int needed; - int remaining; - msgNode *plast; - - plast = (msgNode *)ellLast(&pvtData.msgQueue); - needed = MAX_MESSAGE_SIZE + sizeof(msgNode) + MAX_ALIGNMENT; - remaining = pvtData.buffersize - - ((plast->message - pbuffer) + plast->length); - if(needed < remaining) { - int length,adjust; - - length = plast->length; - /*Make length a multiple of MAX_ALIGNMENT*/ - adjust = length%MAX_ALIGNMENT; - if(adjust) length += (MAX_ALIGNMENT-adjust); - pnextSend = (msgNode *)(plast->message + length); - } - } - if(!pnextSend) return(0); - pnextSend->message = (char *)pnextSend + sizeof(msgNode); - pnextSend->length = 0; - return(pnextSend); -} - -LOCAL char *msgbufGetFree() -{ - msgNode *pnextSend; - - pvtSemTake(pvtData.msgQueueLock); - if((ellCount(&pvtData.msgQueue) == 0) && pvtData.missedMessages) { - int nchar; - - pnextSend = msgbufGetNode(); - nchar = sprintf(pnextSend->message,"errlog = %d messages were discarded\n", - pvtData.missedMessages); - pnextSend->length = nchar + 1; - pvtData.missedMessages = 0; - ellAdd(&pvtData.msgQueue,&pnextSend->node); - } - pvtData.pnextSend = pnextSend = msgbufGetNode(); - if(pnextSend) return(pnextSend->message); - ++pvtData.missedMessages; - semGive(pvtData.msgQueueLock); - return(0); -} - -LOCAL void msgbufSetSize(int size) -{ - char *pbuffer = (char *)pvtData.pbuffer; - msgNode *pnextSend = pvtData.pnextSend; - char *message = pnextSend->message; - - if(size>MAX_MESSAGE_SIZE) { - int excess; - int nchar; - - excess = size - (pvtData.buffersize -(message - pbuffer)); - message[TRUNCATE_SIZE] = 0; - if(excess> 0) { - printf("errlog: A message overran buffer by %d. This is VERY bad\n", - excess); - nchar = sprintf(&message[TRUNCATE_SIZE], - "\nerrlog = previous message overran buffer. It was truncated." - " size = %d excess = %d\n", size,excess); - } else { - nchar = sprintf(&message[TRUNCATE_SIZE], - "\nerrlog = previous message too long. It was truncated." - " size=%d It was truncated\n",size); - } - pnextSend->length = TRUNCATE_SIZE + nchar +1; - } else { - pnextSend->length = size+1; - } - ellAdd(&pvtData.msgQueue,&pnextSend->node); - semGive(pvtData.msgQueueLock); - semGive(pvtData.errlogTaskWaitForWork); -} - -/*errlogTask is the only task that calls msgbufGetSend and msgbufFreeSend*/ -/*Thus errlogTask is the ONLY task that removes messages from msgQueue */ -/*This is why each can lock and unlock msgQueue */ -/*This is necessary to prevent other tasks from waiting for errlogTask */ -LOCAL char * msgbufGetSend() -{ - msgNode *pnextSend; - - pvtSemTake(pvtData.msgQueueLock); - pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue); - semGive(pvtData.msgQueueLock); - if(!pnextSend) return(0); - return(pnextSend->message); -} - -LOCAL void msgbufFreeSend() -{ - msgNode *pnextSend; - - pvtSemTake(pvtData.msgQueueLock); - pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue); - if(!pnextSend) { - printf("errlog: msgbufFreeSend logic error\n"); - taskSuspend(0); - } - ellDelete(&pvtData.msgQueue,&pnextSend->node); - semGive(pvtData.msgQueueLock); -} - -LOCAL void *pvtCalloc(size_t count,size_t size) -{ - size_t *pmem; - - pmem = calloc(count,size); - if(!pmem) { - printf("calloc failed in errlog\n"); - taskSuspend(0); - } - return(pmem); -} - -LOCAL void pvtSemTake(SEM_ID semid) -{ - if(semTake(semid,WAIT_FOREVER)!=OK) { - logMsg("epicsPrint: semTake returned error\n",0,0,0,0,0,0); - taskSuspend(0); - } -} diff --git a/src/libCom/error/errlog.h b/src/libCom/error/errlog.h deleted file mode 100644 index ce9894c7e..000000000 --- a/src/libCom/error/errlog.h +++ /dev/null @@ -1,108 +0,0 @@ -/* src/libCom/errlog.h */ -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ - -#ifndef INCerrlogh -#define INCerrlogh - - - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#define epicsPrintUseProtoANSI -#endif - -#ifdef __STDC__ -#ifndef epicsPrintUseProtoANSI -#define epicsPrintUseProtoANSI -#endif -#endif - -#ifdef epicsPrintUseProtoANSI -# include -#else -# include -#endif - -/* define errMessage with a macro so we can print the file and line number*/ -#define errMessage(S, PM) \ - errPrintf(S, __FILE__, __LINE__, PM) -/* epicsPrintf and epicsVprintf old versions of errlog routines*/ -#define epicsPrintf errlogPrintf -#define epicsVprintf errlogVprintf - -#ifdef __STDC__ -typedef void(*errlogListener) (const char *message); -#else -typedef void(*errlogListener) (); -#endif -typedef enum {errlogInfo,errlogMinor,errlogMajor,errlogFatal} errlogSevEnum; - -#ifdef ERRLOG_INIT -epicsShareDef char * errlogSevEnumString[] = {"info","minor","major","fatal"}; -#else -epicsShareExtern char * errlogSevEnumString[]; -#endif - -#ifdef epicsPrintUseProtoANSI - -epicsShareFunc int epicsShareAPIV errlogPrintf( - const char *pformat, ...); -epicsShareFunc int epicsShareAPIV errlogVprintf( - const char *pformat,va_list pvar); -epicsShareFunc int epicsShareAPIV errlogSevPrintf( - const errlogSevEnum severity,const char *pformat, ...); -epicsShareFunc int epicsShareAPIV errlogSevVprintf( - const errlogSevEnum severity,const char *pformat,va_list pvar); -epicsShareFunc int epicsShareAPI errlogMessage( - const char *message); - -epicsShareFunc char * epicsShareAPI errlogGetSevEnumString( - const errlogSevEnum severity); -epicsShareFunc void epicsShareAPI errlogSetSevToLog( - const errlogSevEnum severity ); -epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog(void); - -epicsShareFunc void epicsShareAPI errlogAddListener( - errlogListener listener); -epicsShareFunc void epicsShareAPI errlogRemoveListener( - errlogListener listener); - -epicsShareFunc int epicsShareAPI eltc(int yesno); -epicsShareFunc int epicsShareAPI errlogInit(int bufsize); - -/*other routines that write to log file*/ -epicsShareFunc void epicsShareAPIV errPrintf(long status, const char *pFileName, - int lineno, const char *pformat, ...); - -#else /* not epicsPrintUseProtoANSI */ -epicsShareFunc int epicsShareAPI errlogPrintf(); -epicsShareFunc int epicsShareAPI errlogVprintf(); -epicsShareFunc int epicsShareAPI errlogSevPrintf(); -epicsShareFunc int epicsShareAPI errlogSevVprintf(); -epicsShareFunc int epicsShareAPI errlogMessage(); -epicsShareFunc char * epicsShareAPI errlogGetSevEnumString(); -epicsShareFunc void epicsShareAPI errlogSetSevToLog(); -epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog(); -epicsShareFunc void epicsShareAPI errlogAddListener(); -epicsShareFunc void epicsShareAPI errlogRemoveListener(); -epicsShareFunc void epicsShareAPI eltc(); -epicsShareFunc void epicsShareAPI errlogInit(); -epicsShareFunc void epicsShareAPI errPrintf(); -#endif /* ifdef epicsPrintUseProtoANSI */ - -#ifdef __cplusplus -} -#endif - -#endif /*INCerrlogh*/ diff --git a/src/libCom/error/error.h b/src/libCom/error/error.h deleted file mode 100644 index cbb0a49f9..000000000 --- a/src/libCom/error/error.h +++ /dev/null @@ -1,74 +0,0 @@ -/* error.h - errMessage symbol table header */ -/* share/epicsH $Id$ */ - -/* - * 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 mm-dd-yy iii Comment - */ - - -#ifndef INCerrorh -#define INCerrorh 1 - -#define LOCAL static -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) - - -typedef struct /* ERRSYMBOL - entry in symbol table */ - { - char *name; /* pointer to symbol name */ - long errNum; /* errMessage symbol number */ - } ERRSYMBOL; -typedef struct /* ERRSYMTAB - symbol table */ - { - short nsymbols; /* current number of symbols in table */ - ERRSYMBOL *symbols; /* ptr to array of symbol entries */ - } ERRSYMTAB; -typedef ERRSYMTAB *ERRSYMTAB_ID; - -#ifdef vxWorks -#define MYERRNO (errnoGet()&0xffff) -#else -#define MYERRNO errno -#endif - - -/*************************************************************/ -struct errSet { /* This defines one module error set */ - long number; /* dimension of err strings */ - char **papName; /* ptr to arr of ptr to error string */ -}; -struct errDes { /* An array of error sets for modules */ - long number; /* number of err modules */ - struct errSet **papErrSet; /* ptr to arr of ptr to errSet */ -}; -extern struct errDes *dbErrDes; -/*************************************************************/ - -#endif /*INCerrorh*/ diff --git a/src/libCom/error/makeStatTbl.pl b/src/libCom/error/makeStatTbl.pl deleted file mode 100644 index 2e66f0720..000000000 --- a/src/libCom/error/makeStatTbl.pl +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/local/bin/perl -# -# makeStatTbl.pl - Create Error Symbol Table -# -# Kay-Uwe Kasemir, 1-31-97, -# based on makeStatTbl shell script. -# -# SYNOPSIS -# perl makeStatTbl.pl hdir [...] -# -# DESCRIPTION -# This tool creates a symbol table (ERRSYMTAB) structure which contains the -# names and values of all the status codes defined in the .h files in the -# specified directory(s). The status codes must be prefixed with "S_" -# in order to be included in this table. -# A "err.h" file must exist in each hdir which defines the module -# numbers, eg. "M_". The table is created on standard output. -# -# This tool's primary use is for creating an error status table used -# by errPrint, and errSymFind. -# -# FILES -# errMdef.h module number file for each h directory -# -# SEE ALSO: errnoLib(1), symLib(1) -#*/ - -use Cwd; - -die "No args (files to parse) given" if ($#ARGV < 0); - -# parse all lines of all files given: -while (<>) -{ - if (m'^#define[ /t]*S_') - { - chomp; - push @err_sym_line, $_; - } - if (m'^#[ \t]*define[ /t]+M_') - { - chomp; - push @err_facility_line, $_; - } -} - -$out_name = "errSymTbl.c"; -$dir = cwd(); - -open OUT, ">$out_name" or die "Cannot open $out_name"; - -print OUT "/*\n"; -print OUT " * status code symbol table\n"; -print OUT " *\n"; -print OUT " * CREATED BY makeStatTbl.pl\n"; -print OUT " * FROM $dir\n"; -print OUT " * ON " . localtime() . "\n"; -print OUT " */\n"; -print OUT "\n"; -print OUT "#include \"errMdef.h\"\n"; -print OUT "#include \"errSymTbl.h\"\n"; -print OUT "\n"; - - -foreach $line ( @err_facility_line ) -{ - if ($line =~ m'^#[ \t]*define[ \t]+(M_[A-Za-z0-9_]+)[ \t]+(.*)') - { - printf OUT "#ifndef %s\n", $1; - printf OUT "#define %s %s\n", $1, $2; - printf OUT "#endif /* ifdef %s */\n", $1; - } -} - -$count = 0; -foreach $line ( @err_sym_line ) -{ - print OUT "$line\n"; - # define S_symbol /* comment */ - if ($line =~ m'[ \t#]define[ \t]*(S_[A-Za-z0-9_]+).*\/\*(.+)\*\/') - { - $symbol[$count] = $1; - $comment[$count]= $2; - ++$count; - } - else - { - # Some status values for '0' (=OK) have no comment: - unless ($line =~ m'[ \t#]define[ \t]*(S_[A-Za-z0-9_]+)') - { - die "cannot decode this line:\n$line\n"; - } - } -} - - -print OUT "\n"; -print OUT "LOCAL ERRSYMBOL symbols[] =\n"; -print OUT "{\n"; - -for ($i=0; $i<$count; ++$i) -{ - printf OUT "\t{ \"%s\", (long) %s },\n", - $comment[$i], $symbol[$i]; -} - -print OUT "};\n"; -print OUT "\n"; -print OUT "LOCAL ERRSYMTAB symTbl =\n"; -print OUT "{\n"; -print OUT "\tNELEMENTS(symbols), /* current number of symbols in table */\n"; -print OUT "\tsymbols, /* ptr to symbol array */\n"; -print OUT "};\n"; -print OUT "\n"; -print OUT "ERRSYMTAB_ID errSymTbl = &symTbl;\n"; -print OUT "\n"; -print OUT "/*\tEOF $out_name */\n"; - diff --git a/src/libCom/ezsSockSubr.c b/src/libCom/ezsSockSubr.c deleted file mode 100644 index 660acfd21..000000000 --- a/src/libCom/ezsSockSubr.c +++ /dev/null @@ -1,538 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 11-23-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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: - * ----------------- - * .00 11-23-90 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 09-05-91 joh updated for v5 vxWorks; included systime.h for utime.h - * .03 12-08-91 rac added a comment for ezsFopenToFd - * .04 10-09-92 rac use SO_REUSEADDR with socket - * .05 08-11-93 mrk removed V5_vxWorks - * .06 05-04-94 pg HPUX port changes. - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE ezsSockSubr.c - easy-to-use socket routines -* -* DESCRIPTION -* This set of routines supports using Internet sockets for transferring -* text, with a bias toward use by server/client programs. -* -* All of these routines use the sockets as TCP/IP sockets, with the -* sockets specified as SOCK_STREAM. -* -* QUICK REFERENCE -* #include -* int ezsCheckFdRead( fd ) -* int ezsCheckFpRead( fp ) -* int ezsConnectToServer( >pServerSock, portNum, hostName ) -* int ezsCreateListenSocket( >pListenSock, portNum ) -* int ezsFopenToFd( pFp, pFd ) -* int ezsFreopenToFd( fp, pFd, >pOldFd ) -* int ezsListenExclusiveUse( pClientSock, pListenSock, pInUseFlag, -* >clientName, greetingMsg ) -* void ezsSleep( seconds, usec ) -* -* BUGS -* o doesn't provide a way for client to distinguish between server output -* to stdout and stderr, since if server redirects those streams to the -* same socket, their individual identity is lost -* o needs examples -*-***************************************************************************/ - -#include -#include -#ifdef vxWorks -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -/*+/subr********************************************************************** -* NAME ezsCheckFpRead - check fp to see if read is possible -* -* DESCRIPTION -* Checks the specified stream to see if a read operation is possible. -* -* ezsCheckFdRead(fd) performs a similar function for fd's. -* -* RETURNS -* >0 if a read can be done -* 0 if a read can't presently be done -* -* BUGS -* o due to restrictions in VxWorks 4.0.2, cannot be used for stdin, -* stdout, or stderr -* -*-*/ -int -ezsCheckFpRead(fp) -FILE *fp; /* I pointer to FILE to check for "input available" */ -{ -#ifdef vxWorks - if (fp == stdin) assertAlways(0); - else if (fp == stdout) assertAlways(0); - else if (fp == stderr) assertAlways(0); -#endif - - return(ezsCheckFdRead(fileno(fp))); -} -ezsCheckFdRead(fd) -int fd; -{ - fd_set readbits, other; - struct timeval timer; - int ret; - - timer.tv_sec = 0; - timer.tv_usec = 0; - FD_ZERO(&readbits); - FD_ZERO(&other); - FD_SET(fd, &readbits); - - ret = select(fd+1, &readbits, &other, &other, &timer); -#ifdef vxWorks - return ret; -#else - if (FD_ISSET(fd, &readbits)) - return 1; - return 0; -#endif -} - -/*+/subr********************************************************************** -* NAME ezsConnectToServer - attempt to connect via socket to server -* -* DESCRIPTION -* -* RETURNS -* 0, or -* -1 if an error occurs, or -* -2 if the host name can't be found or the server rejects the -* connection. The message buffer will contain a relevant message. -* -* BUGS -* o under VxWorks 4.0.2, if the server is on the same machine as the -* client, then the connect will fail unless the machine's name is -* in the host table -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -int -ezsConnectToServer(pServerSock, portNum, hostName, message) -int *pServerSock; /* O ptr to socket connected to server */ -int portNum; /* I port number of server */ -char *hostName; /* I name (or Internet address) of host on which - the server runs */ -char *message; /* O message from server (dimension of 80 assumed) */ -{ - struct sockaddr_in server; - struct hostent *hp; -#ifndef vxWorks - struct hostent *gethostbyname(); -#endif - int i; - int optval=1; - - assert(pServerSock != NULL); - assert(portNum > 0); - assert(hostName != NULL); - assert(message != NULL); - -/*----------------------------------------------------------------------------- -* set up to create the socket and connect it to the server -*----------------------------------------------------------------------------*/ - bzero(&server, sizeof(server)); - server.sin_family = AF_INET; - server.sin_port = htons(portNum); - - if (isdigit(hostName[0])) - server.sin_addr.s_addr = inet_addr(hostName); - else { -#ifdef vxWorks - if ((server.sin_addr.s_addr = hostGetByName(hostName)) == ERROR) { - sprintf(message, "host not in VxWorks host table: %s", hostName); - return -2; - } -#else - if ((hp = gethostbyname(hostName)) == NULL) { - sprintf(message, "host unknown: %s", hostName); - return -2; - } - bcopy(hp->h_addr, &server.sin_addr, hp->h_length); -#endif - } - - *pServerSock = socket(AF_INET, SOCK_STREAM, 0); - if (*pServerSock < 0) - return -1; - if (setsockopt(*pServerSock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != 0) { - close(*pServerSock); - *pServerSock = -1; - return -1; - } - if (connect(*pServerSock, &server, sizeof(server)) < 0) { - close(*pServerSock); - *pServerSock = -1; - return -1; - } - -/*----------------------------------------------------------------------------- -* now, with connection completed to server, wait for the message from -* server--the message will either identify the server, or else indicate -* that the connection is rejected. -*----------------------------------------------------------------------------*/ - if ((i=read(*pServerSock, message, 79)) <= 0) { - close(*pServerSock); - *pServerSock = -1; - sprintf(message, "connection rejected"); - return -2; - } - message[i] = '\0'; - if (strncmp(message, "***", 3) == 0) { - close(*pServerSock); - *pServerSock = -1; - return -2; - } - - return 0; -} - -/*+/subr********************************************************************** -* NAME ezsCreateListenSocket - create socket to listen for connections -* -* DESCRIPTION -* Create a socket to be used by a server to listen for connections -* by potential clients. The socket is bound to the caller-specified -* port number. -* -* The port number specified, in conjunction with the name of the -* host, constitutes a network "address" at which the server can be -* reached. -* -* Ideally, the port number and service name would be registered with -* the system manager, who would place the information in the -* /etc/services file. If this is done, then getservbyname(3N) can be -* used by a potential client to determine the proper port number to -* use. In actual practice, potential clients would "know" what port -* number to use by means of an include file provided by the service -* for compiling clients. -* -* RETURNS -* 0, or -* -1 if an error occurs (errno will have error code) -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -int -ezsCreateListenSocket(pListenSock, portNum) -int *pListenSock; /* O ptr to socket for listening for connects */ -int portNum; /* I number of service's port */ -{ - struct sockaddr_in server; /* temporary Internet socket structure */ - - assert(pListenSock != NULL); - assert(portNum > 0); - - if ((*pListenSock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - return -1; - - bzero(&server, sizeof(server)); - server.sin_family = AF_INET; /* internet */ - server.sin_addr.s_addr = INADDR_ANY; /* anybody can connect */ - server.sin_port = htons(portNum); /* server's port */ - if (bind(*pListenSock, (struct sockaddr *)&server, sizeof(server)) < 0) { - close(*pListenSock); - return -1; - } - - if (listen(*pListenSock, 1) < 0) - return -1; - - return 0; -} - -/*+/subr********************************************************************** -* NAME ezsFopenToFd - open a specified stream to an fd -* -* DESCRIPTION -* Open a stream to an fd. Typically, this is used to open a stream -* to a socket. -* -* This routine should not be used for stdin, stdout, or stderr. For -* these streams, ezsFreopenToFd() should be used. -* -* RETURNS -* 0, or -* -1 if errors are encountered (errno has error code) -* -* BUGS -* o the stream is always opened in "r+" (update) mode -* -* SEE ALSO -* ezsFreopenToFd(), ezsFrestoreToOldFd() -* -* NOTES -* 1. For input streams in a client monitoring the output of a server, -* it will often be useful to set the stream to unbuffered: -* FILE *myIn; -* ezsFopenToFd(&myIn, socket); -* setbuf(myIn, NULL); -* -*-*/ -int -ezsFopenToFd(pFp, pFd) -FILE **pFp; /* O pointer to pointer to new FILE */ -int *pFd; /* I pointer tofd to be used by file pointer */ -{ - assert(pFp != NULL); - assert(pFd != NULL); - - if ((*pFp=fdopen(*pFd, "r+")) == NULL) - return -1; - return 0; -} - -/*+/subr********************************************************************** -* NAME ezsFreopenToFd - reopen a specified stream to an fd -* -* DESCRIPTION -* Reopens a stream (assumed to presently be open) to an fd. Typically, -* this is used in a server program to redirect stdin, stdout, or stderr -* to use a socket. -* -* Under VxWorks, this is a pseudo re-open, which applies only to -* the current task. If a "program" consists of several tasks, each -* task must re-direct its I/O. Typically, one task will supply a -* non-NULL pOldFd argument, and other tasks will use NULL. -* -* RETURNS -* 0, or -* -1 if errors are encountered (errno has error code) -* -2 if illegal stream is used -* -* BUGS -* o the only streams which are handled are stdin, stdout, and stderr -* o stdout and stderr are line buffered under VxWorks, and output won't -* get sent (even if fflush() is used, as of 4.0.2) until '\n' is sent. -* -* SEE ALSO -* ezsFopenToFd(), ezsFrestoreToOldFd() -* -* EXAMPLE -* -*-*/ -int -ezsFreopenToFd(fp, pFd, pOldFd) -FILE *fp; /* IO pointer to FILE, such as stdin or stdout */ -int *pFd; /* I pointer to fd to be used by file pointer */ -int *pOldFd; /* O NULL, or pointer to place to store fd - previously used by file pointer */ -{ - int fdNumber; - - assert(fp != NULL); - assert(pFd != NULL); - - if (fp == stdin) fdNumber = 0; - else if (fp == stdout) fdNumber = 1; - else if (fp == stderr) fdNumber = 2; - else return -2; - -#ifdef vxWorks - if (pOldFd != NULL) - *pOldFd = ioTaskStdGet(0, fdNumber); - ioTaskStdSet(0, fdNumber, *pFd); -#else - if (pOldFd != NULL) { - if ((*pOldFd = dup(fileno(fp))) < 0) - return -1; - } - if (dup2(*pFd, fileno(fp)) < 0) - return -1; -#endif - - return 0; -} - -/*+/subr********************************************************************** -* NAME ezsListenExclusiveUse - listen for client connect; allow only 1 -* -* DESCRIPTION -* Checks to see if a client connect request is queued. If so, the -* action depends on whether a client is presently connected: -* -* o if no client is presently connected, then the connection is made: -* - a socket is created to converse with the client, -* - a greeting message is sent to the new client, -* - the inUseFlag is set to 1, and -* - the new socket is returned to the caller -* o if a client is presently connected, then the connection is -* refused, with a rejection message sent to the hopeful new client. -* The rejection message has the form "*** server inuse by host", -* where "host" is the name of the host from which the present client -* is connected. -* -* This routine simply polls the listen socket. It must be called -* periodically. Only one queued request is processed on each call. -* -* RETURNS -* -1 if an error occurs -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -int -ezsListenExclusiveUse(pClientSock, pListenSock, pInUseFlag, name, greetMsg) -int *pClientSock; /* IO ptr to socket (to be) connected to client */ -int *pListenSock; /* I socket for listening for connects */ -int *pInUseFlag; /* I ptr to flag; 1 indicates server already engaged */ -char *name; /* O ptr to buf[30] where client name will go */ -char *greetMsg; /* I greeting message to sent to new client */ -{ - int i; - static char inUseText[80]; - int connSock; /* socket connected to potential client */ - struct sockaddr_in clientAddr;/* address of client socket */ - struct hostent *clientHost; - char *clientHostAddr; - char clientHostAddrText[30]; - char clientBuf[80]; - - if (ezsCheckFdRead(*pListenSock)) { - i = sizeof(clientAddr); - connSock = accept(*pListenSock, (struct sockaddr *)&clientAddr, &i); - if (connSock < 0) - return -1; - if (*pInUseFlag) { -/*----------------------------------------------------------------------------- -* server is already engaged; send rejection message to hopeful client -*----------------------------------------------------------------------------*/ - write(connSock, inUseText, strlen(inUseText)); - close(connSock); - } - else { -/*----------------------------------------------------------------------------- -* server available; consummate connection: -* o set inUseFlag to 1 -* o build a rejection message to send if other clients attempt connect -* o send greeting message to new client -*----------------------------------------------------------------------------*/ -#ifndef vxWorks - clientHost = - gethostbyaddr((char *)&clientAddr.sin_addr, i, AF_INET); - if (clientHost != NULL) - sprintf(clientHostAddrText, "%s", clientHost->h_name); - else { -#endif - clientHostAddr = inet_ntoa(clientAddr.sin_addr); - sprintf(clientHostAddrText, "%s", clientHostAddr); -#ifndef vxWorks - } -#endif - (void)strcpy(name, clientHostAddrText); - sprintf(inUseText, "*** server in use by %s", clientHostAddrText); - write(connSock, greetMsg, strlen(greetMsg)); - *pClientSock = connSock; - *pInUseFlag = 1; - } - } - return 0; -} - -/*+/subr********************************************************************** -* NAME ezsSleep - sleep -* -* DESCRIPTION -* The current task sleeps for the specified time. -* -* This routine should not be used by programs implemented with the -* UNIX lwp (light-weight process) library--taskSleep() in genTaskSubr.c -* should be used, instead. -* -* RETURNS -* void -* -* SEE ALSO -* taskSleep() -* -*-*/ -void -ezsSleep(seconds, usec) -int seconds; /* I number of seconds (added to usec) to sleep */ -int usec; /* I number of micro-sec (added to sec) to sleep */ -{ -#ifndef vxWorks - sleep((unsigned int)seconds); -/* MDA - usleep isn't POSIX - usleep((unsigned)(seconds*1000000 + usec)); -*/ -#else - int ticks; - static int ticksPerSec=0; - static int usecPerTick; - - if (ticksPerSec == 0) { - ticksPerSec = sysClkRateGet(); - usecPerTick = 1000000 / ticksPerSec; - } - - ticks = seconds*ticksPerSec + usec/usecPerTick + 1; - taskDelay(ticks); -#endif -} diff --git a/src/libCom/fdmgr/fdManager.cpp b/src/libCom/fdmgr/fdManager.cpp deleted file mode 100644 index 0edccbe4e..000000000 --- a/src/libCom/fdmgr/fdManager.cpp +++ /dev/null @@ -1,432 +0,0 @@ - -// -// $Id$ -// -// -// $Log$ -// Revision 1.14 1998/06/16 02:06:32 jhill -// lazy init sock lib when its a static build & recoverfrom select differences in winsock -// -// Revision 1.13 1998/05/29 20:22:44 jhill -// made hashing routine portable -// -// Revision 1.12 1998/02/05 21:12:09 jhill -// removed questionable inline -// -// Revision 1.11 1997/08/05 00:37:00 jhill -// removed warnings -// -// Revision 1.10 1997/06/25 05:45:49 jhill -// cleaned up pc port -// -// Revision 1.9 1997/06/13 09:39:09 jhill -// fixed warnings -// -// Revision 1.8 1997/05/29 21:37:38 tang -// add ifdef for select call to support HP-UX -// -// Revision 1.7 1997/05/27 14:53:11 tang -// fd_set cast in select for both Hp and Sun -// -// Revision 1.6 1997/05/08 19:49:12 tang -// added int * cast in select for HP port compatibility -// -// Revision 1.5 1997/04/23 17:22:57 jhill -// fixed WIN32 DLL symbol exports -// -// Revision 1.4 1997/04/10 19:45:33 jhill -// API changes and include with not <> -// -// Revision 1.3 1996/11/02 02:04:42 jhill -// fixed several subtle bugs -// -// Revision 1.2 1996/09/04 21:50:16 jhill -// added hashed fd to fdi convert -// -// Revision 1.1 1996/08/13 22:48:23 jhill -// dfMgr =>fdManager -// -// - -// -// -// NOTES: -// 1) This library is not thread safe -// -// - -// -// ANSI C -// -#include -#include -#include - -// Both the functions in osiTimer and fdManager are -// implemented in this DLL -> define epicsExportSharesSymbols -#define epicsExportSharedSymbols -#define instantiateRecourceLib -#include "osiTimer.h" -#include "fdManager.h" -#include "osiSleep.h" -#include "bsdSocketResource.h" - -// -// if the compiler supports explicit instantiation of -// template member functions -// -#if defined(EXPL_TEMPL) - // - // From Stroustrups's "The C++ Programming Language" - // Appendix A: r.14.9 - // - // This explicitly instantiates the template class's member - // functions used by fdManager - // - // - // instantiated by "fdManager fileDescriptorManager;" statement below? - // (according to ms vis C++) - // - template class resTable ; -#endif - -epicsShareDef fdManager fileDescriptorManager; - -// -// fdManager::fdManager() -// -epicsShareFunc fdManager::fdManager() -{ - size_t i; - - assert (bsdSockAttach()); - - for (i=0u; ifdSets)/sizeof(this->fdSets[0u]); i++) { - FD_ZERO(&this->fdSets[i]); - } - this->maxFD = 0; - this->processInProg = 0u; - this->pCBReg = 0; - // - // should throw an exception here - // when most compilers are implementing - // exceptions - // - assert (this->fdTbl.init(0x100)>=0); -} - -// -// fdManager::~fdManager() -// -epicsShareFunc fdManager::~fdManager() -{ - fdReg *pReg; - - while ( (pReg = this->regList.get()) ) { - pReg->state = fdrLimbo; - pReg->destroy(); - } - while ( (pReg = this->activeList.get()) ) { - pReg->state = fdrLimbo; - pReg->destroy(); - } - bsdSockRelease(); -} - -// -// fdManager::process() -// -epicsShareFunc void fdManager::process (const osiTime &delay) -{ - static const tsDLIterBD eol; // end of list - tsDLIterBD iter; - tsDLIterBD tmp; - osiTime minDelay; - osiTime zeroDelay; - fdReg *pReg; - struct timeval tv; - int status; - int ioPending = 0; - - // - // no recursion - // - if (this->processInProg) { - return; - } - this->processInProg = 1; - - // - // One shot at expired timers prior to going into - // select. This allows zero delay timers to arm - // fd writes. We will never process the timer queue - // more than once here so that fd activity get serviced - // in a reasonable length of time. - // - minDelay = staticTimerQueue.delayToFirstExpire(); - if (zeroDelay>=minDelay) { - staticTimerQueue.process(); - minDelay = staticTimerQueue.delayToFirstExpire(); - } - - if (minDelay>=delay) { - minDelay = delay; - } - - for (iter=this->regList.first(); iter!=eol; ++iter) { - FD_SET(iter->getFD(), &this->fdSets[iter->getType()]); - ioPending = 1; - } - - tv.tv_sec = minDelay.getSecTruncToLong (); - tv.tv_usec = minDelay.getUSecTruncToLong (); - - /* - * win32 requires this (others will - * run faster with this installed) - */ - if (!ioPending) { - /* - * recover from subtle differences between - * windows sockets and UNIX sockets implementation - * of select() - */ - if (tv.tv_sec!=0 || tv.tv_usec!=0) { - osiSleep (tv.tv_sec, tv.tv_usec); - } - status = 0; - } - else { - status = select (this->maxFD, &this->fdSets[fdrRead], - &this->fdSets[fdrWrite], &this->fdSets[fdrExcp], &tv); - } - - staticTimerQueue.process(); - if (status==0) { - this->processInProg = 0; - return; - } - else if (status<0) { - if (SOCKERRNO == SOCK_EINTR) { - this->processInProg = 0; - return; - } - else { - fprintf(stderr, - "fdManager: select failed because errno=%d=\"%s\"\n", - SOCKERRNO, SOCKERRSTR); - } - } - - // - // Look for activity - // - iter=this->regList.first(); - while (iter!=eol) { - tmp = iter; - tmp++; - if (FD_ISSET(iter->getFD(), &this->fdSets[iter->getType()])) { - FD_CLR(iter->getFD(), &this->fdSets[iter->getType()]); - this->regList.remove(*iter); - this->activeList.add(*iter); - iter->state = fdrActive; - } - iter=tmp; - } - - // - // I am careful to prevent problems if they access the - // above list while in a "callBack()" routine - // - while ( (pReg = this->activeList.get()) ) { - pReg->state = fdrLimbo; - - // - // Tag current reg so that we - // can detect if it was deleted - // during the call back - // - this->pCBReg = pReg; - pReg->callBack(); - if (this->pCBReg != NULL) { - // - // check only after we see that it is non-null so - // that we dont trigger bounds-checker dangling pointer - // error - // - assert (this->pCBReg==pReg); - this->pCBReg = 0; - if (pReg->onceOnly) { - pReg->destroy(); - } - else { - this->regList.add(*pReg); - pReg->state = fdrPending; - } - } - } - this->processInProg = 0; -} - -// -// fdReg::destroy() -// (default destroy method) -// -epicsShareFunc void fdReg::destroy() -{ - delete this; -} - -// -// fdReg::~fdReg() -// -epicsShareFunc fdReg::~fdReg() -{ - fileDescriptorManager.removeReg(*this); -} - -// -// fdReg::show() -// -epicsShareFunc void fdReg::show(unsigned level) const -{ - printf ("fdReg at %p\n", (void *) this); - if (level>1u) { - printf ("\tstate = %d, onceOnly = %d\n", - this->state, this->onceOnly); - } - this->fdRegId::show(level); -} - -// -// fdRegId::show() -// -void fdRegId::show(unsigned level) const -{ - printf ("fdRegId at %p\n", this); - if (level>1u) { - printf ("\tfd = %d, type = %d\n", - this->fd, this->type); - } -} - -// -// fdRegId::resourceHash() -// -resTableIndex fdRegId::resourceHash (unsigned) const -{ - resTableIndex hashid = (unsigned) this->fd; - - // - // This assumes worst case hash table index width of 1 bit. - // We will iterate this loop 5 times on a 32 bit architecture. - // - // A good optimizer will unroll this loop? - // Experiments using the microsoft compiler show that this isnt - // slower than switching on the architecture size and urolling the - // loop explicitly (that solution has resulted in portability - // problems in the past). - // - for (unsigned i=(CHAR_BIT*sizeof(unsigned))/2u; i>0u; i >>= 1u) { - hashid ^= (hashid>>i); - } - - // - // evenly distribute based on the type of interest also - // - hashid ^= this->type; - - // - // the result here is always masked to the - // proper size after it is returned to the resource class - // - return hashid; -} - -// -// fdManager::installReg() -// -epicsShareFunc void fdManager::installReg (fdReg ®) -{ - int status; - - this->maxFD = fdManagerMaxInt(this->maxFD, reg.getFD()+1); - this->regList.add(reg); - reg.state = fdrPending; - status = this->fdTbl.add(reg); - if (status) { - fprintf (stderr, - "**** Warning - duplicate fdReg object\n"); - fprintf (stderr, - "**** will not be seen by fdManager::lookUpFD()\n"); - } -} - -// -// fdManager::removeReg() -// -void fdManager::removeReg(fdReg ®) -{ - fdReg *pItemFound; - - pItemFound = this->fdTbl.remove(reg); - if (pItemFound!=®) { - fprintf(stderr, - "fdManager::removeReg() bad fd registration object\n"); - return; - } - - // - // signal fdManager that the fdReg was deleted - // during the call back - // - if (this->pCBReg == ®) { - this->pCBReg = 0; - } - - switch (reg.state) { - case fdrActive: - this->activeList.remove(reg); - break; - case fdrPending: - this->regList.remove(reg); - break; - case fdrLimbo: - break; - default: - // - // here if memory corrupted - // - assert(0); - } - reg.state = fdrLimbo; - - FD_CLR(reg.getFD(), &this->fdSets[reg.getType()]); -} - -// -// lookUpFD() -// -epicsShareFunc fdReg *fdManager::lookUpFD(const SOCKET fd, const fdRegType type) -{ - if (fd<0) { - return NULL; - } - fdRegId id (fd,type); - return this->fdTbl.lookup(id); -} - -// -// fdReg::fdReg() -// -fdReg::fdReg (const SOCKET fdIn, const fdRegType typIn, - const unsigned onceOnlyIn) : - fdRegId(fdIn,typIn), state(fdrLimbo), onceOnly(onceOnlyIn) -{ - if (!FD_IN_FDSET(fdIn)) { - fprintf (stderr, "%s: fd > FD_SETSIZE ignored\n", - __FILE__); - return; - } - fileDescriptorManager.installReg(*this); -} diff --git a/src/libCom/fdmgr/fdManager.h b/src/libCom/fdmgr/fdManager.h deleted file mode 100644 index 65edc39d5..000000000 --- a/src/libCom/fdmgr/fdManager.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * $Id$ - * - * File descriptor management C++ class library - * (for multiplexing IO in a single threaded environment) - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - * 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 - * - * - * History - * $Log$ - * Revision 1.10 1998/10/23 19:47:12 jhill - * fixed inline is too big warning - * - * Revision 1.9 1998/06/16 02:04:07 jhill - * fixed spelling - * - * Revision 1.8 1998/02/05 21:12:10 jhill - * removed questionable inline - * - * Revision 1.7 1997/08/05 00:37:01 jhill - * removed warnings - * - * Revision 1.6 1997/06/25 05:45:50 jhill - * cleaned up pc port - * - * Revision 1.5 1997/04/23 17:22:58 jhill - * fixed WIN32 DLL symbol exports - * - * Revision 1.4 1997/04/10 19:45:38 jhill - * API changes and include with not <> - * - * Revision 1.3 1996/11/02 02:04:41 jhill - * fixed several subtle bugs - * - * Revision 1.2 1996/09/04 21:50:16 jhill - * added hashed fd to fdi convert - * - * Revision 1.1 1996/08/13 22:48:21 jhill - * dfMgr =>fdManager - * - * - */ - -#ifndef fdManagerH_included -#define fdManagerH_included - -#include - -#include "shareLib.h" // reset share lib defines -#include "tsDLList.h" -#include "resourceLib.h" -#include "osiTime.h" -#include "osiSock.h" - -enum fdRegType {fdrRead, fdrWrite, fdrExcp, fdRegTypeNElem}; -enum fdRegState {fdrActive, fdrPending, fdrLimbo}; - -class epicsShareClass fdRegId -{ -public: - fdRegId (const SOCKET fdIn, const fdRegType typeIn) : - fd(fdIn), type(typeIn) {} - - SOCKET getFD () - { - return this->fd; - } - - fdRegType getType () - { - return this->type; - } - - int operator == (const fdRegId &idIn) - { - return this->fd == idIn.fd && this->type==idIn.type; - } - - resTableIndex resourceHash (unsigned nBitsId) const; - - virtual void show (unsigned level) const; -private: - const SOCKET fd; - const fdRegType type; -}; - -// -// fdReg -// file descriptor registration -// -class fdReg : public tsDLNode, public fdRegId, public tsSLNode { - friend class fdManager; -public: - epicsShareFunc fdReg (const SOCKET fdIn, const fdRegType typ, - const unsigned onceOnly=0); - epicsShareFunc virtual ~fdReg (); - - epicsShareFunc virtual void show(unsigned level) const; - - // - // Called by the file descriptor manager: - // 1) If the fdManager is deleted and there are still - // fdReg objects attached - // 2) Immediately after calling "callBack()" if - // the constructor specified "onceOnly" - // - // fdReg::destroy() does a "delete this" - // - epicsShareFunc virtual void destroy (); -private: - - // - // called when there is activity on the fd - // NOTES - // 1) the fdManager will call this only once during the - // lifetime of a fdReg object if the constructor - // specified "onceOnly" - // - epicsShareFunc virtual void callBack ()=0; - - unsigned char state; // fdRegState goes here - unsigned char onceOnly; -}; - -// -// fdManager -// file descriptor manager -// -class fdManager { -friend class fdReg; -public: - epicsShareFunc fdManager(); - epicsShareFunc ~fdManager(); - epicsShareFunc void process (const osiTime &delay); - - // - // returns NULL if the fd is unknown - // - epicsShareFunc fdReg *lookUpFD(const SOCKET fd, const fdRegType type); -private: - tsDLList regList; - tsDLList activeList; - resTable fdTbl; - fd_set fdSets[fdRegTypeNElem]; - - int maxFD; - unsigned processInProg; - // - // Set to fdreg when in call back - // and nill otherwise - // - fdReg *pCBReg; - - epicsShareFunc void installReg (fdReg ®); - void removeReg (fdReg ®); -}; - -epicsShareExtern fdManager fileDescriptorManager; - -// -// fdManagerMaxInt () -// -inline int fdManagerMaxInt (int a, int b) -{ - if (a>b) { - return a; - } - else { - return b; - } -} - -#endif // fdManagerH_included - diff --git a/src/libCom/fdmgr/fdmgr.h b/src/libCom/fdmgr/fdmgr.h deleted file mode 100644 index d5254c421..000000000 --- a/src/libCom/fdmgr/fdmgr.h +++ /dev/null @@ -1,236 +0,0 @@ -/* fdmgr.h - * - * share/epicsH/$Id$ - * - * Header file associated with a file descriptor manager - * for use with the UNIX system call select - * - * Author Jeffrey O. Hill - * hill@atdiv.lanl.gov - * 505 665 1831 - * - * 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 - * - * - * - * History - * .00 joh 011993 Created - * .01 pg 050494 HPUX port modifications. - * - * - */ - -#ifndef includeFdmgrH -#define includeFdmgrH - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ellLib.h" -#include "bucketLib.h" -#include "osiSock.h" -#include "shareLib.h" - -enum fdi_type {fdi_read, fdi_write, fdi_excp}; -enum alarm_list_type {alt_invalid, alt_alarm, alt_expired, alt_free}; - -typedef struct{ - ELLLIST fdentry_list; - ELLLIST fdentry_in_use_list; - ELLLIST fdentry_free_list; - ELLLIST alarm_list; - ELLLIST expired_alarm_list; - ELLLIST free_alarm_list; - fd_set readch; - fd_set writech; - fd_set excpch; - BUCKET *pAlarmBucket; - unsigned nextAlarmId; - SOCKET maxfd; - int select_tmo; -# if defined (vxWorks) - SEM_ID lock; - SEM_ID fdmgr_pend_event_lock; - SEM_ID expired_alarm_lock; - SEM_ID fd_handler_lock; - unsigned long clk_rate; /* ticks per sec */ - unsigned long last_tick_count; - unsigned long sec_offset; - WIND_TCB *fdmgr_pend_event_tid; -# else - unsigned fdmgr_pend_event_in_use; -# endif -}fdctx; - -/* - * C "typedef" name "alarm" was changed to "fdmgrAlarm" to avoid collisions - * with other libraries. Next the identifier was changed again to - * an unsigned integer type "fdmgrAlarmId". - * - * This "#define" is for codes that used to use a pointer to the old typedef - * "alarm" or "fdmgrAlarm" types to identify an alarm. - * - * ie the following code will allow compilation against - * all versions: - * - * #if defined (NEW_FDMGR_ALARMID) - * fdmgrAlarmId XXXX - * #elif defined (NEW_FDMGR_ALARM) - * fdmgrAlarm *XXXX; - * #else - * alarm *XXXX; - * #endif - * - * XXXX = fdmgrAlarmId fdmgr_add_timeout() - */ -typedef unsigned fdmgrAlarmId; -#define NEW_FDMGR_ALARMID - -#ifdef __STDC__ - -/* - * - * Initialize a file descriptor manager session - * - */ -epicsShareFunc fdctx * epicsShareAPI fdmgr_init(void); - -/* - * Specify a function to be called with a specified parameter - * after a specified delay relative to the current time - * - * Returns fdmgrNoAlarm (zero) if alarm cant be created - */ -#define fdmgrNoAlarm 0 -epicsShareFunc fdmgrAlarmId epicsShareAPI fdmgr_add_timeout( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -struct timeval *ptimeout, /* relative delay from current time */ -void (*func)(void *pParam), - /* function (handler) to call */ -void *param /* first parameter passed to the func */ -); - -/* - * Clear a timeout which has not executed its function (handler) - * yet. - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_timeout( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -fdmgrAlarmId id /* alarm to delete */ -); - -/* - * - * Specify a function (handler) to be called with a specified parameter - * when a file descriptor becomes active. The parameter fdi (file - * descriptor interest) specifies the type of activity (IO) we wish - * to be informed of: read, write, or exception. For more - * info on this see the man pages for the UNIX system call select(). - * - * read and exception callbacks are permanent( ie the application's - * function (handler) continues to be called each time the - * file descriptor becomes active until fdmgr_add_callback() - * is called). - * - * write callbacks are called only once after each call to - * fdmgr_add_callback() - * - */ -epicsShareFunc int epicsShareAPI fdmgr_add_callback( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, /* file descriptor */ -enum fdi_type fdi, /* file descriptor interest type */ -void (*pfunc)(void *pParam), /* function (handler) to call */ -void *param /* first parameter passed to the func */ -); - -/* - * - * Clear nterest in a type of file descriptor activity (IO). - * - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_callback( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, /* file descriptor */ -enum fdi_type fdi /* file descriptor interest type */ -); - -/* - * - * Wait a specified delay relative from the current time for file - * descriptor activity (IO) or timeouts (timer expiration). Application - * specified functions (handlers) will not be called unless the - * application waits in this function or polls it frequently - * enough. - * - */ -epicsShareFunc int epicsShareAPI fdmgr_pend_event( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -struct timeval *ptimeout -); - - -/* - * obsolete interface - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_fd( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd -); - -/* - * obsolete interface - */ -epicsShareFunc int epicsShareAPI fdmgr_add_fd( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, -void (*pfunc)(void *pParam), -void *param -); - -epicsShareFunc int epicsShareAPI fdmgr_delete(fdctx *pfdctx); - -#else - -epicsShareFunc fdctx * epicsShareAPI fdmgr_init(); -epicsShareFunc fdmgrAlarmId epicsShareAPI fdmgr_add_timeout(); -epicsShareFunc int epicsShareAPI fdmgr_clear_timeout(); -epicsShareFunc int epicsShareAPI fdmgr_add_callback(); -epicsShareFunc int epicsShareAPI fdmgr_clear_callback(); -epicsShareFunc int epicsShareAPI fdmgr_pend_event(); -epicsShareFunc int epicsShareAPI fdmgr_delete(); - -/* - * obsolete interface - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_fd(); -epicsShareFunc int epicsShareAPI fdmgr_add_fd(); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef includeFdmgrH (last line in this file) */ - diff --git a/src/libCom/freeList/freeList.h b/src/libCom/freeList/freeList.h deleted file mode 100644 index 9e19ea55d..000000000 --- a/src/libCom/freeList/freeList.h +++ /dev/null @@ -1,67 +0,0 @@ -/* share/epicsH/freeList.h */ -/* share/epicsH $Id$ */ -/* Author: Marty Kraimer Date: 04-19-94 */ -/***************************************************************** - 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). - * - * Modification Log: - * ----------------- - * .01 04-19-94 mrk Initial Implementation - */ - -#ifndef INCfreeListh -#define INCfreeListh - -#include "shareLib.h" - -epicsShareFunc void epicsShareAPI freeListInitPvt(void **ppvt,int size,int nmalloc); -epicsShareFunc void * epicsShareAPI freeListCalloc(void *pvt); -epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt); -epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem); -epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt); -epicsShareFunc size_t epicsShareAPI freeListItemsAvail(void *pvt); - -#endif /*INCfreeListh*/ diff --git a/src/libCom/freeList/freeListLib.c b/src/libCom/freeList/freeListLib.c deleted file mode 100644 index 0a3c387bd..000000000 --- a/src/libCom/freeList/freeListLib.c +++ /dev/null @@ -1,207 +0,0 @@ -/* $Id$ */ -/* Author: Marty Kraimer Date: 04-19-94 */ -/***************************************************************** - 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). - * - * Modification Log: - * ----------------- - * .01 04-19-94 mrk Initial Implementation - * .02 03-28-97 joh added freeListItemAvail() function - */ - -#ifdef vxWorks -#include -#include -#include "fast_lock.h" -#endif - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "freeList.h" -#include "adjustment.h" - -typedef struct allocMem { - struct allocMem *next; - void *memory; -}allocMem; -typedef struct { - int size; - int nmalloc; - void *head; - allocMem *mallochead; - size_t nBlocksAvailable; -#ifdef vxWorks - FAST_LOCK lock; -#endif -}FREELISTPVT; - -epicsShareFunc void epicsShareAPI - freeListInitPvt(void **ppvt,int size,int nmalloc) -{ - FREELISTPVT *pfl; - - pfl = (void *)calloc((size_t)1,(size_t)sizeof(FREELISTPVT)); - if(!pfl) { -#ifdef vxWorks - taskSuspend(0); -#else - abort(); -#endif - } - pfl->size = adjustToWorstCaseAlignment(size); - pfl->nmalloc = nmalloc; - pfl->head = NULL; - pfl->mallochead = NULL; - pfl->nBlocksAvailable = 0u; -#ifdef vxWorks - FASTLOCKINIT(&pfl->lock); -#endif - *ppvt = (void *)pfl; - return; -} - -epicsShareFunc void * epicsShareAPI freeListCalloc(void *pvt) -{ - FREELISTPVT *pfl = pvt; - void *ptemp; - - ptemp = freeListMalloc(pvt); - if(ptemp) memset((char *)ptemp,0,pfl->size); - return(ptemp); -} - -epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt) -{ - FREELISTPVT *pfl = pvt; - void *ptemp; - void **ppnext; - allocMem *pallocmem; - int i; - -#ifdef vxWorks - FASTLOCK(&pfl->lock); -#endif - ptemp = pfl->head; - if(ptemp==0) { - ptemp = (void *)malloc(pfl->nmalloc*pfl->size); - if(ptemp==0) { -#ifdef vxWorks - FASTUNLOCK(&pfl->lock); -#endif - return(0); - } - pallocmem = (allocMem *)calloc(1,sizeof(allocMem)); - if(pallocmem==0) { -#ifdef vxWorks - FASTUNLOCK(&pfl->lock); -#endif - free(ptemp); - return(0); - } - pallocmem->memory = ptemp; - if(pfl->mallochead) - pallocmem->next = pfl->mallochead; - pfl->mallochead = pallocmem; - for(i=0; inmalloc; i++) { - ppnext = ptemp; - *ppnext = pfl->head; - pfl->head = ptemp; - ptemp = ((char *)ptemp) + pfl->size; - } - ptemp = pfl->head; - pfl->nBlocksAvailable += pfl->nmalloc; - } - ppnext = pfl->head; - pfl->head = *ppnext; - pfl->nBlocksAvailable--; -#ifdef vxWorks - FASTUNLOCK(&pfl->lock); -#endif - return(ptemp); -} - -epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem) -{ - FREELISTPVT *pfl = pvt; - void **ppnext; - -#ifdef vxWorks - FASTLOCK(&pfl->lock); -#endif - ppnext = pmem; - *ppnext = pfl->head; - pfl->head = pmem; - pfl->nBlocksAvailable++; -#ifdef vxWorks - FASTUNLOCK(&pfl->lock); -#endif -} - -epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt) -{ - FREELISTPVT *pfl = pvt; - allocMem *phead; - allocMem *pnext; - - phead = pfl->mallochead; - while(phead) { - pnext = phead->next; - free(phead->memory); - free(phead); - phead = pnext; - } - free(pvt); -} - -epicsShareFunc size_t epicsShareAPI freeListItemsAvail(void *pvt) -{ - FREELISTPVT *pfl = pvt; - return pfl->nBlocksAvailable; -} - diff --git a/src/libCom/genSubr.c b/src/libCom/genSubr.c deleted file mode 100644 index 3995b30b8..000000000 --- a/src/libCom/genSubr.c +++ /dev/null @@ -1,415 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 03-29-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: - * ----------------- - * .00 03-29-90 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 01-29-92 rac added wildMatch function - * .03 08-11-93 mrk removed ifdef V5_vxWorks - * .04 07-06-94 mrk added ifndef VMS for genShellCommand - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE genSubr.c - some general use routines -* -* DESCRIPTION -* This file contains some routines which are generally useful for -* EPICS programs. Some routines are for SunOS vs. VxWorks -* compatibility. -* -* QUICK REFERENCE -* assert( expression) -* assertAlways( expression) -* char *genMalloc( nBytes) -* void genBufCheck( pBuf) -* void genFree( pBuf) -* void genShellCommand(cmdBuf, resultBuf, resultDim) -* void genSigInit( pHandler) -* int perror( string) -* int wildMatch( string, pattern, ignoreCase) -* -* SEE ALSO -* genDefs.h -*-***************************************************************************/ -#include - -#ifdef vxWorks -# include -# include -# include -# include -# include -#else -# include -# include -# include -#endif - - -/*+/macro********************************************************************* -* NAME assert - check assertion -* -* DESCRIPTION -* Checks to see if an expression is true. If the expression is false, -* an error message is printed and a signal is raised (SIGABRT or, for -* VxWorks, SIGUSR1). -* -* This is actually a macro provided by genDefs.h . If the preprocessor -* symbol NDEBUG is defined, then the expression isn't evaluated or -* checked. -* -* USAGE -* assert(expression); -* assertAlways(expression); (same as assert(), but isn't disabled -* by defining NDEBUG) -* -* RETURNS -* void -* -* NOTES -* 1. Since evaluation of the expression is conditional (depending on -* whether NDEBUG is defined), it is poor practice to use expressions -* which have side effects. -* 2. assertAlways(0) is recommended rather than abort(). -* -*-*/ -/*---------------------------------------------------------------------------- -* assertFail - handle assertion failure -* For SunOS, call abort(). -* For VxWorks, try to deliver a SIGUSR1 signal. If that's not -* possible, generate a bus error. -*---------------------------------------------------------------------------*/ -int -assertFail(fileName, lineNum) -char *fileName; -int lineNum; -{ - (void)fprintf(stderr, "assertFail: in file %s line %d\n", - fileName, lineNum); -#ifdef vxWorks - if (kill(taskIdSelf(), SIGUSR1) == ERROR) { - int *j; - j = (int *)(-1); - j = (int *)(*j); - } - exit(1); -#else - abort(); -#endif - - return (0); -} - -/*+/subr********************************************************************** -* NAME genMalloc - malloc() and free() 'pre-processor' with "guards" -* -* DESCRIPTION -* These routines support catching overwriting a block of memory -* obtained by malloc(). A 'guard' field is added at the beginning -* and end of the block of memory when genMalloc() is called to -* allocate the block. The 'guard' field is checked by genFree(). -* -* genMalloc() works the same as malloc(), returning a pointer to -* the 'usable' part of the memory block. (I.e., the guard fields are -* 'hidden' from the caller.) -* -* genFree() works the same as free(), except it checks to see if -* the guard field has been clobbered. -* -* A third routine, genBufCheck() allows checking at arbitrary times -* (even from dbx) on whether a block has been clobbered. -* -*****************************************************************************/ - -#if 0 /* a simple demonstration of usage */ -main() -{ - int *x; - int i; - - x = (int *)genMalloc(100); - genBufCheck(x); - for (i=0; i<26; i++) - *(x+i) = i; - genFree(x); - - exit(0); -} -#endif - -# define CHK_MALLOC_FILL_PATTERN 1 - -/*---------------------------------------------------------------------------- -* malloc a block with the following layout, with the block and guard -* fields aligned on longword boundaries -* -* longword 0 nLong for block, including this longword and the -* 'guard' longwords -* longword 1 &longword 0 -* user bytes -* longword n &longword 0 -*---------------------------------------------------------------------------*/ -char *genMalloc(nBytes) -int nBytes; -{ - long *ptrL; - int i; - unsigned nLong, sizeC; - - nLong = 3 + (nBytes+sizeof(long)-1)/sizeof(long); - sizeC = nLong * sizeof(long); - ptrL = (long *)malloc(sizeC); - if (ptrL != NULL) { - for (i=0; i -* #include (or for VxWorks) -* -* jmp_buf mySigEnv; -* -* void myHandler(sigNum) -* int sigNum; -* { -* signal(sigNum, SIG_DFL); -* longjmp(mySigEnv, sigNum); -* } -* -* main() -* { -* int sigNum; -* -* genSigInit(myHandler); -* if ((sigNum = setjmp(mySigEnv)) != 0) -* goto sigOccurred; -* . -* . -* exit(0); -* sigOccurred: -* printf("signal %d detected\n", sigNum); -* exit(1); -* } -* -*-*/ -void -genSigInit(handler) -void (* handler)(); /* I pointer to signal handler */ -{ - (void)signal(SIGTERM, handler); /* SunOS plain kill (not -9) */ - (void)signal(SIGQUIT, handler); /* SunOS ^\ */ - (void)signal(SIGINT, handler); /* SunOS ^C */ - (void)signal(SIGILL, handler); /* illegal instruction */ -#ifndef vxWorks - (void)signal(SIGABRT, handler); /* SunOS assert */ -#else - (void)signal(SIGUSR1, handler); /* VxWorks assert */ -#endif - (void)signal(SIGBUS, handler); /* bus error */ - (void)signal(SIGSEGV, handler); /* segmentation violation */ - (void)signal(SIGFPE, handler); /* arithmetic exception */ - (void)signal(SIGPIPE, handler); /* write to disconnected socket */ -} - -int doMatch(); - -/*+/subr********************************************************************** -* NAME wildMatch - do wildcard matching on strings -* -* DESCRIPTION -* Search a text string for a match of a pattern, where the pattern -* can contain wildcard characters. -* -* The wildcard characters and their meanings are: -* ? matches any single character -* * matches any sequence of zero or more characters -* -* RETURNS -* 1 if a match is obtained, or -* 0 -* -*-*/ -int -wildMatch(text, p, ignoreCase) -char *text; /* I the text to be checked */ -char *p; /* I the pattern, possibly with wildcards */ -int ignoreCase; /* I 0,1 to honor,ignore upper/lower case differences */ -{ - char *starP=NULL; /* pointer at beginning of * wildcard */ - char *starText=NULL; /* pointer at beginning of * wildcard */ - int matched; /* char in text matches char in pattern */ - char a, b; - - if (*text == '\0') - return 0; - while (*p != '\0' && *text != '\0') { - switch (*p) { - case '*': - starP = ++p; - if (*p == '\0') - return 1; - starText = text; - break; - default: - matched = (*text == *p || *p == '?') ? 1 : 0; - if (ignoreCase && !matched) { - a = *text; b = *p; - if (isascii(a) && isascii(b) && isalpha(a) && isalpha(b)) { - if (isupper(a)) a = tolower(a); - if (isupper(b)) b = tolower(b); - if (a == b) - matched = 1; - } - } - if (matched) { - text++, p++; - if (*p == '\0') { - if (*text == '\0' || *(p-1) == '*') - return 1; - text = ++starText; - if (starP == NULL) - return 0; - p = starP; - } - } - else if (starP == NULL) - return 0; - else { - text = ++starText; - p = starP; - } - break; - } - } - if (*text == '\0') { - if (*p == '\0') - return 1; - if (*p != '*') - return 0; - if (*(++p) == '\0') - return 1; - } - return 0; -} diff --git a/src/libCom/genTaskSubr.c b/src/libCom/genTaskSubr.c deleted file mode 100644 index df0a3a07e..000000000 --- a/src/libCom/genTaskSubr.c +++ /dev/null @@ -1,348 +0,0 @@ -#if !defined(vxWorks) && !defined(sun) - -/* do nothing if not vxWorks and not sun */ - -#else - -/* $Id$ - * Author: Roger A. Cole - * Date: 02-03-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: - * ----------------- - * .00 02-03-90 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 06-28-91 rac don't do lwp_fpset for sun4 - * .03 08-11-93 mrk removed ifdef V5_vxWorks - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE genTaskSubr.c - SunOS and VxWorks "task support" -* -* DESCRIPTION -* The code in this file supports compatibility routines between -* VxWorks and SunOS. See genTasks.h for a description of the -* capabilities which are available. -* -* BUGS -* o see genTasks.h -* -* SEE ALSO: -* o genTasks.h definitions for using tasks -* -*-***************************************************************************/ -#include -#ifndef vxWorks -# include -#endif - -/*---------------------------------------------------------------------------- -* semTake() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks - void semTake(semId) - SEM_ID semId; - { if (mon_enter(semId) != 0) { - fprintf(stderr, "in semTake, re-entry not supported; goodbye\n"); - assertAlways(0); - } - return; - } -#endif - -/*---------------------------------------------------------------------------- -* semClear() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks - STATUS semClear(semId) - SEM_ID semId; - { - int nestLevel; /* reentrancy level in mon_enter() */ - - nestLevel = mon_cond_enter(semId); - - if (nestLevel < 0) - return ERROR; - else if (nestLevel > 0) { - fprintf(stderr, "in semClear, re-entry not supported; goodbye\n"); - assertAlways(0); - } - else - return OK; - } -#endif -/*---------------------------------------------------------------------------- -* taskSpawn() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks - TASK_ID taskSpawn(name, prio, options, stackSize, entryAddress, - a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) - char *name; - int prio; - int options; - int stackSize; - void (*entryAddress)(); - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; - { - TASK_ID threadId; - - if (lwp_create(&threadId, entryAddress, prio, 0, lwp_newstk(), 10, - a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) == 0) { -#ifndef sun4 - if (options & VX_STDIO) { - if (lwp_libcset(threadId) != 0) { - printf("couldn't do lwp_libcset for %s\n", name); - lwp_perror("taskSpawn"); - assertAlways(0); - } - } - if (options & VX_FP_TASK) { - if (lwp_fpset(threadId) != 0) { - printf("couldn't do lwp_fpset for %s\n", name); - lwp_perror("taskSpawn"); - assertAlways(0); - } - } -#else - ; /* no action for sun4 */ -#endif - } - else { - printf("couldn't do lwp_create for %s\n", name); - lwp_perror("taskSpawn"); - assertAlways(0); - } - - return threadId; - } -#endif - -/*---------------------------------------------------------------------------- -* taskPrioritySet() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks - STATUS taskPrioritySet(tId, prio) - TASK_ID tId; - int prio; - { - if (lwp_setpri(tId, prio) != -1) - return OK; - else - return ERROR; - } -#endif - -/*---------------------------------------------------------------------------- -* taskResume() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks - STATUS taskResume(tId) - TASK_ID tId; - { - if (lwp_resume(tId) == 0) - return OK; - else - return ERROR; - } -#endif - -/*---------------------------------------------------------------------------- -* taskSleep() -*---------------------------------------------------------------------------*/ - -STATUS taskSleep(tId, seconds, usec) -TASK_ID tId; -int seconds; /* seconds to delay */ -int usec; /* micro-seconds to delay */ -{ -#ifndef vxWorks - struct timeval lwpSleep; /* time interval for lwp_sleep */ - - lwpSleep.tv_sec = seconds; - lwpSleep.tv_usec = usec; - lwp_sleep(&lwpSleep); -#else - int ticks; - static int ticksPerSec=0; - static int usecPerTick; - - if (ticksPerSec == 0) { - ticksPerSec = sysClkRateGet(); - usecPerTick = 1000000 / ticksPerSec; - } - - ticks = seconds*ticksPerSec + usec/usecPerTick + 1; - taskDelay(ticks); -#endif - return OK; -} - -/*---------------------------------------------------------------------------- -* taskSuspend() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks - STATUS taskSuspend(tId) - TASK_ID tId; - { - if (lwp_suspend(tId) == 0) - return OK; - else - return ERROR; - } -#endif - -/*---------------------------------------------------------------------------- -* taskDelete() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks - STATUS taskDelete(tId) - TASK_ID tId; - { - if (lwp_destroy(tId) == 0) - return OK; - else - return ERROR; - } -#endif - -/*---------------------------------------------------------------------------- -* lwpThreadStat() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks -lwpThreadStat(msg, ptId) -char *msg; -thread_t *ptId; -{ - int stat; - statvec_t statVec; - int th; - int thCount; - thread_t thVec[20]; - - if (ptId == NULL) - thCount = lwp_enumerate(thVec, 20); - else { - printf("%s:", msg); - thCount = 1; - } - - if (thCount <= 0) - printf("%s: no threads exist\n", msg); - else { - if (ptId == NULL) - printf("%s: %d tasks exist\n", msg, thCount); - for (th=0; ththread_id, ptId->thread_key, - statVec.stat_prio); - } - switch (statVec.stat_blocked.any_kind) { - case NO_TYPE: - printf("not blocked\n"); - break; - case CV_TYPE: - printf("blocked for cv: %#x:%d\n", - statVec.c_id, statVec.c_key); - break; - case MON_TYPE: - printf("blocked for mon: %#x:%d\n", - statVec.m_id, statVec.m_key); - break; - case LWP_TYPE: - printf("blocked for other: %#x:%d\n", - statVec.l_id, statVec.l_key); - break; - default: - printf("unrecognized type\n"); - break; - } - } - } - } -} -#endif - -/*---------------------------------------------------------------------------- -* lwpMonStat() -*---------------------------------------------------------------------------*/ - -#ifndef vxWorks -lwpMonStat(msg) -char *msg; -{ - int mon; - int monCount; - mon_t monVec[20]; - thread_t owner; - thread_t waitVec[20]; - int waiter; - int waiterCount; - - monCount = mon_enumerate(monVec, 20); - if (monCount <= 0) - printf("%s: no monitors exist\n", msg); - else { - printf("%s: %d monitors exist\n", msg, monCount); - for (mon=0; mon -#ifdef vxWorks -#include -#include -#endif -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsPrint.h" -#include "gpHash.h" - -typedef struct gphPvt { - int tableSize; - int nShift; - ELLLIST **paplist; /*pointer to array of pointers to ELLLIST */ -#ifdef vxWorks - FAST_LOCK lock; -#endif -}gphPvt; - - -/*The hash algorithm is the algorithm described in */ -/* Fast Hashing of Variable Length Text Strings, Peter K. Pearson, */ -/* Communications of the ACM, June 1990 */ - -static unsigned char T[256] = { - 39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69, -157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160, -176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77, - 75,107,169,138,195,184, 70, 90, 61,166, 7,244,165,108,219, 51, - 9,139,209, 40, 31,202, 58,179,116, 33,207,146, 76, 60,242,124, -254,197, 80,167,153,145,129,233,132, 48,246, 86,156,177, 36,187, - 45, 1, 96, 18, 19, 62,185,234, 99, 16,218, 95,128,224,123,253, - 42,109, 4,247, 72, 5,151,136, 0,152,148,127,204,133, 17, 14, -182,217, 54,199,119,174, 82, 57,215, 41,114,208,206,110,239, 23, -189, 15, 3, 22,188, 79,113,172, 28, 2,222, 21,251,225,237,105, -102, 32, 56,181,126, 83,230, 53,158, 52, 59,213,118,100, 67,142, -220,170,144,115,205, 26,125,168,249, 66,175, 97,255, 92,229, 91, -214,236,178,243, 46, 44,201,250,135,186,150,221,163,216,162, 43, - 11,101, 34, 37,194, 25, 50, 12, 87,198,173,240,193,171,143,231, -111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238, -134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47 -}; - -#define NSIZES 9 -static int allowSize[NSIZES] = {256,512,1024,2048,4096,8192,16384,32768,65636}; - -static void *myCalloc(size_t nobj,size_t size) -{ - void *p; - - p=calloc(nobj,size); - if(p) return(p); -#ifdef vxWorks - taskSuspend(0); -#else - abort(); -#endif - return(NULL); -} - -static int hash( char *pname,int nShift) -{ - unsigned char h0=0; - unsigned char h1=0; - unsigned short ind0,ind1; - int even = TRUE; - unsigned char c; - - while(*pname) { - c = *pname; - if(even) {h0 = T[h0^c]; even = FALSE;} - else {h1 = T[h1^c]; even = TRUE;} - pname++; - } - ind0 = (unsigned short)h0; - ind1 = (unsigned short)h1; - return((ind1<tableSize = tableSize; - pgphPvt->nShift = nShift; - pgphPvt->paplist = myCalloc(tableSize, sizeof(ELLLIST *)); -#ifdef vxWorks - FASTLOCKINIT(&pgphPvt->lock); -#endif - *ppvt = (void *)pgphPvt; - return; -} - -GPHENTRY * epicsShareAPI gphFind(void *pvt,char *name,void *pvtid) -{ - int hashInd; - gphPvt *pgphPvt = (gphPvt *)pvt; - ELLLIST **paplist; - ELLLIST *gphlist; - GPHENTRY *pgphNode; - - if(pgphPvt==NULL) return(NULL); - paplist = pgphPvt->paplist; - hashInd = hash(name,pgphPvt->nShift); -#ifdef vxWorks - FASTLOCK(&pgphPvt->lock); -#endif - if ((gphlist=paplist[hashInd]) == NULL) { - pgphNode = NULL; - } else { - pgphNode = (GPHENTRY *) ellFirst(gphlist); - } - while(pgphNode) { - if(strcmp(name,(char *)pgphNode->name) == 0) { - if(pvtid==pgphNode->pvtid) break; - } - pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - } -#ifdef vxWorks - FASTUNLOCK(&pgphPvt->lock); -#endif - return(pgphNode); -} - -GPHENTRY * epicsShareAPI gphAdd(void *pvt,char *name,void *pvtid) -{ - int hashInd; - gphPvt *pgphPvt = (gphPvt *)pvt; - ELLLIST **paplist; - ELLLIST *plist; - GPHENTRY *pgphNode; - - if(pgphPvt==NULL) return(NULL); - paplist = pgphPvt->paplist; - hashInd = hash(name,pgphPvt->nShift); -#ifdef vxWorks - FASTLOCK(&pgphPvt->lock); -#endif - if(paplist[hashInd] == NULL) { - paplist[hashInd] = myCalloc(1, sizeof(ELLLIST)); - ellInit(paplist[hashInd]); - } - plist=paplist[hashInd]; - pgphNode = (GPHENTRY *) ellFirst(plist); - while(pgphNode) { - if((strcmp(name,(char *)pgphNode->name) == 0) - &&(pvtid == pgphNode->pvtid)) { -#ifdef vxWorks - FASTUNLOCK(&pgphPvt->lock); -#endif - return(NULL); - } - pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - } - pgphNode = myCalloc(1, (unsigned) sizeof(GPHENTRY)); - pgphNode->name = name; - pgphNode->pvtid = pvtid; - ellAdd(plist, (ELLNODE*)pgphNode); -#ifdef vxWorks - FASTUNLOCK(&pgphPvt->lock); -#endif - return (pgphNode); -} - -void epicsShareAPI gphDelete(void *pvt,char *name,void *pvtid) -{ - int hashInd; - gphPvt *pgphPvt = (gphPvt *)pvt; - ELLLIST **paplist; - ELLLIST *plist = NULL; - GPHENTRY *pgphNode; - - if(pgphPvt==NULL) return; - paplist = pgphPvt->paplist; - hashInd = hash(name,pgphPvt->nShift); -#ifdef vxWorks - FASTLOCK(&pgphPvt->lock); -#endif - if(paplist[hashInd] == NULL) { - pgphNode = NULL; - } else { - plist=paplist[hashInd]; - pgphNode = (GPHENTRY *) ellFirst(plist); - } - while(pgphNode) { - if((strcmp(name,(char *)pgphNode->name) == 0) - &&(pvtid == pgphNode->pvtid)) { - ellDelete(plist, (ELLNODE*)pgphNode); - free((void *)pgphNode); - break; - } - pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - } -#ifdef vxWorks - FASTUNLOCK(&pgphPvt->lock); -#endif - return; -} - -void epicsShareAPI gphFreeMem(void *pvt) -{ - int hashInd; - gphPvt *pgphPvt = (gphPvt *)pvt; - ELLLIST **paplist; - ELLLIST *plist; - GPHENTRY *pgphNode; - GPHENTRY *next;; - - /*caller must ensure that no other thread is using *pvt */ - if(pgphPvt==NULL) return; - paplist = pgphPvt->paplist; - for (hashInd=0; hashIndtableSize; hashInd++) { - if(paplist[hashInd] == NULL) continue; - plist=paplist[hashInd]; - pgphNode = (GPHENTRY *) ellFirst(plist); - while(pgphNode) { - next = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - ellDelete(plist,(ELLNODE*)pgphNode); - free((void *)pgphNode); - pgphNode = next; - } - free((void *)paplist[hashInd]); - } - free((void *)paplist); - free((void *)pgphPvt); -} - -void epicsShareAPI gphDump(void *pvt) -{ - int hashInd; - gphPvt *pgphPvt = (gphPvt *)pvt; - ELLLIST **paplist; - ELLLIST *plist; - GPHENTRY *pgphNode; - int number; - - if(pgphPvt==NULL) return; - paplist = pgphPvt->paplist; - for (hashInd=0; hashIndtableSize; hashInd++) { - if(paplist[hashInd] == NULL) continue; - plist=paplist[hashInd]; - pgphNode = (GPHENTRY *) ellFirst(plist); - printf("\n %3.3hd=%3.3d",hashInd,ellCount(plist)); - number=0; - while(pgphNode) { - printf(" %s %p",pgphNode->name,pgphNode->pvtid); - if(number++ ==2) {number=0;printf("\n ");} - pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - } - } - printf("\n End of General Purpose Hash\n"); -} diff --git a/src/libCom/helpSubr.c b/src/libCom/helpSubr.c deleted file mode 100644 index e1027a3fb..000000000 --- a/src/libCom/helpSubr.c +++ /dev/null @@ -1,285 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 10-17-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: - * ----------------- - * .00 10-17-90 rac initial version - * .01 06-18-90 rac installed in SCCS - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE helpSubr.c - routines to implement embedded help capability -* -* GENERAL DESCRIPTION -* -* QUICK REFERENCE -* #include -* HELP_LIST helpList; -* HELP_TOPIC topic; -* void helpIllegalCommand( pStream, pHelpList, command, keyword ) -* void helpInit( pHelpList ) -* void helpPrintTopics( pStream, pHelpList ) -* void helpTopicAdd( pHelpList, pHelpTopic, helpKeyword, helpText) -* HELP_TOPIC *helpTopicFind( pHelpList, keyword ) -* void helpTopicPrint( pStream, pHelpTopic ) -* -*-***************************************************************************/ -#include -#ifdef vxWorks -# include -# include -#else -# include -#endif -#if 0 /* some test code for checking out functionality */ -main() -{ - HELP_LIST helpList; - HELP_TOPIC helpLegal; - HELP_TOPIC helpLegalAddOn; - HELP_TOPIC helpUsage; - - helpInit(&helpList); - helpTopicAdd(&helpList, &helpLegal, "commands", "\n\ -generic commands are:\n\ - detach\n\ - help [topic]\n\ - quit (or ^D)\n\ - source fileName\n\ -"); - helpTopicAdd(&helpList, &helpUsage, "usage", "\n\ -This is some\n\ -usage information.\n\ -"); - helpTopicAdd(&helpList, &helpLegalAddOn, "commands", "\n\ -program-specific commands are:\n\ - close fileName\n\ - open fileName\n\ -"); - -#if 0 - helpPrintTopics(stdout, &helpList); - helpTopicPrint(stdout, &helpLegal); - helpTopicPrint(stdout, &helpUsage); -#endif - helpIllegalCommand(stdout, &helpList, "xxx", "yyy"); - helpIllegalCommand(stdout, &helpList, "help", "usage"); - helpIllegalCommand(stdout, &helpList, "help", "yyy"); -} -#endif - -/*+/subr********************************************************************** -* NAME helpIllegalCommand - process illegal commands -* -* DESCRIPTION -* This routine accepts a command and a keyword following the command. -* -* If the command is "help", then the keyword is used to search the -* help topics. If a match is found, the information is printed. If -* no match is found, an error message is printed, followed by a list -* of valid topics for more information. -* -* If the command isn't "help", an "illegal command" error message is -* printed. If "commands" is a valid help topic, then that topic is -* also printed. (The assumption is that "commands" is the topic which -* contains a list of legal commands.) -* -* RETURNS -* void -* -*-*/ -void -helpIllegalCommand(pStream, pHelpList, command, keyword) -FILE *pStream; /* I stream (such as stdout or stderr) for prints */ -HELP_LIST *pHelpList; /* I pointer to help list */ -char *command; /* I command */ -char *keyword; /* I topic keyword */ -{ - HELP_TOPIC *pTopic; /* temp pointer to topic */ - - if (strcmp(command, "help") != 0) { - (void)fprintf(pStream, "illegal command: %s\n", command); - if ((pTopic = helpTopicFind(pHelpList, "commands")) != NULL) - helpTopicPrint(pStream, pTopic); - return; - } - if (keyword == NULL || *keyword == '\0') - helpPrintTopics(pStream, pHelpList); - else if ((pTopic = helpTopicFind(pHelpList, keyword)) == NULL) { - (void)fprintf(pStream, "no help information found for: %s\n", keyword); - helpPrintTopics(pStream, pHelpList); - } - else - helpTopicPrint(pStream, pTopic); -} - -/*+/subr********************************************************************** -* NAME helpInit - initialize a help list -* -* DESCRIPTION -* This routine initializes a help list prior to adding topics. -* -* RETURNS -* void -* -*-*/ -void -helpInit(pHelpList) -HELP_LIST *pHelpList; /* IO pointer to help list */ -{ - pHelpList->pHead = NULL; - pHelpList->pTail = NULL; -} - -/*+/subr********************************************************************** -* NAME helpPrintTopics - prints a list of valid topics -* -* DESCRIPTION -* This prints the list of topic keywords for a help list, preceded -* by a short "topics available" message. -* -* RETURNS -* void -* -*-*/ -void -helpPrintTopics(pStream, pHelpList) -FILE *pStream; /* I stream (such as stdout or stderr) for printing */ -HELP_LIST *pHelpList; /* I pointer to help list */ -{ - HELP_TOPIC *pTopic; /* temp pointer to topic */ - - (void)fprintf(pStream, - "You can get help info for the following with: help topic\n"); - pTopic = pHelpList->pHead; - while (pTopic != NULL) { - (void)fprintf(pStream, " %s", pTopic->keyword); - pTopic = pTopic->pNextTopic; - } - (void)fprintf(pStream, "\n\n"); -} - -/*+/subr********************************************************************** -* NAME helpTopicAdd - add a help topic to a help list -* -* DESCRIPTION -* This routine adds a help topic, including a keyword for the topic -* and the textual information, to a help list. If the topic already -* exists on the help list, then the textual information is appended -* to the already existing textual information for the topic. -* -* RETURNS -* void -* -*-*/ -void -helpTopicAdd(pHelpList, pHelpTopic, helpKeyword, helpText) -HELP_LIST *pHelpList; /* IO pointer to help list */ -HELP_TOPIC *pHelpTopic; /* IO pointer to help topic */ -char *helpKeyword; /* I keyword for topic */ -char *helpText; /* I text for topic */ -{ - HELP_TOPIC *pTopicBase; /* base item for an existing topic */ - - if (pHelpList->pHead != NULL && - (pTopicBase = helpTopicFind(pHelpList, helpKeyword)) != NULL) { - - pTopicBase->pLastItem->pNextItem = pHelpTopic; - pHelpTopic->text = helpText; - pHelpTopic->keyword = NULL; - pHelpTopic->pNextTopic = NULL; - pHelpTopic->pNextItem = NULL; - pHelpTopic->pLastItem = NULL; - - return; - } - if (pHelpList->pHead == NULL) - pHelpList->pHead = pHelpTopic; - else - pHelpList->pTail->pNextTopic = pHelpTopic; - - pHelpList->pTail = pHelpTopic; - pHelpTopic->text = helpText; - pHelpTopic->keyword = helpKeyword; - pHelpTopic->pNextTopic = NULL; - pHelpTopic->pNextItem = NULL; - pHelpTopic->pLastItem = pHelpTopic; -} - -/*+/subr********************************************************************** -* NAME helpTopicFind - search a help list for topic -* -* DESCRIPTION -* This routine searches a help list for a topic whose keyword matches -* the desired keyword. -* -* RETURNS -* pointer to topic, or -* NULL if topic wasn't found -* -*-*/ -HELP_TOPIC * -helpTopicFind(pHelpList, keyword) -HELP_LIST *pHelpList; /* I pointer to help list */ -char *keyword; /* I topic keyword */ -{ - HELP_TOPIC *pTopic; /* temp pointer to topic */ - - pTopic = pHelpList->pHead; - while (pTopic != NULL) { - if (strcmp(keyword, pTopic->keyword) == 0) - return pTopic; - pTopic = pTopic->pNextTopic; - } - - return NULL; -} - -/*+/subr********************************************************************** -* NAME helpTopicPrint - prints a help topic -* -* DESCRIPTION -* This routine prints the help information for a help topic. -* -* RETURNS -* void -* -*-*/ -void -helpTopicPrint(pStream, pHelpTopic) -FILE *pStream; /* I stream (such as stdout or stderr) for printing */ -HELP_TOPIC *pHelpTopic; /* I pointer to help topic */ -{ - while (pHelpTopic != NULL) { - (void)fprintf(pStream, "%s", pHelpTopic->text); - pHelpTopic = pHelpTopic->pNextItem; - } - (void)fprintf(pStream, "\n"); -} diff --git a/src/libCom/macLib/macCore.c b/src/libCom/macLib/macCore.c deleted file mode 100644 index a7e47e65f..000000000 --- a/src/libCom/macLib/macCore.c +++ /dev/null @@ -1,784 +0,0 @@ -/* $Id$ - * - * Implementation of core macro substitution library (macLib) - * - * Just about all functionality proposed in tech-talk on 19-Feb-96 has - * been implemented with only minor departures. Missing features are: - * - * 1. All the attribute-setting routines (for setting and getting - * special characters etc) - * - * 2. Error message verbosity control (although a debug level is - * supported) - * - * 3. The macro substitution tool (although the supplied macTest - * program is in fact a simple version of this) - * - * The implementation is fairly unsophisticated and linked lists are - * used to store macro values. Typically there will will be only a - * small number of macros and performance won't be a problem. Special - * measures are taken to avoid unnecessary expansion of macros whose - * definitions reference other macros. Whenever a macro is created, - * modified or deleted, a "dirty" flag is set; this causes a full - * expansion of all macros the next time a macro value is read - * - * See the files README (original specification from tech-talk) and - * NOTES (valid input file for the macTest program) for further - * information - * - * Testing has been primarily under SunOS, but the code has been built - * and macTest -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbmf.h" -#include "macLib.h" - -/* - * Static function prototypes (these static functions provide an low-level - * library operating on macro entries) - */ -static MAC_ENTRY *first ( MAC_HANDLE *handle ); -static MAC_ENTRY *last ( MAC_HANDLE *handle ); -static MAC_ENTRY *next ( MAC_ENTRY *entry ); -static MAC_ENTRY *previous( MAC_ENTRY *entry ); - -static MAC_ENTRY *create( MAC_HANDLE *handle, char *name, long special ); -static MAC_ENTRY *lookup( MAC_HANDLE *handle, char *name, long special ); -static char *rawval( MAC_HANDLE *handle, MAC_ENTRY *entry, char *value ); -static void delete( MAC_HANDLE *handle, MAC_ENTRY *entry ); -static long expand( MAC_HANDLE *handle ); -static void trans ( MAC_HANDLE *handle, MAC_ENTRY *entry, long level, - char *term, char **rawval, char **value, char *valend ); - -static char *Strdup( char *string ); - -/* - * Static variables - */ -static MAC_CHARS macDefaultChars = { - MAC_STARTCHARS, - MAC_LEFTCHARS, - MAC_RIGHTCHARS, - MAC_SEPARCHARS, - MAC_ASSIGNCHARS, - MAC_ESCAPECHARS -}; - -/* - * Create a new macro substitution context and return an opaque handle - * associated with the new context. Also optionally load an initial set - * of macro definitions - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macCreateHandle( - MAC_HANDLE **pHandle, /* address of variable to receive pointer */ - /* to new macro substitution context */ - - char *pairs[] ) /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -{ - MAC_HANDLE *handle; /* pointer to macro substitution context */ - - /* ensure NULL handle pointer is returned on error */ - *pHandle = NULL; - - /* allocate macro substitution context */ - handle = ( MAC_HANDLE * ) dbmfMalloc( sizeof( MAC_HANDLE ) ); - if ( handle == NULL ) { - macErrMessage0( -1, "macCreateHandle: failed to allocate context" ); - return -1; - } - - /* initialize context */ - handle->magic = MAC_MAGIC; - handle->chars = macDefaultChars; - handle->dirty = FALSE; - handle->level = 0; - handle->debug = 0; - handle->suppressWarning = 0; - ellInit( &handle->list ); - - /* if supplied, load macro definitions */ - for ( ; pairs && pairs[0]; pairs += 2 ) { - if ( macPutValue( handle, pairs[0], pairs[1] ) < 0 ) { - dbmfFree( handle ); - return -1; - } - } - - /* set returned handle pointer */ - *pHandle = handle; - - return 0; -} -void epicsShareAPI macSuppressWarning( - MAC_HANDLE *handle, /* opaque handle */ - int falseTrue /*0 means issue, 1 means suppress*/ -) -{ - handle->suppressWarning = falseTrue; -} - -/* - * Expand a string that may contain macro references and return the - * expanded string - * - * This is a very basic and powerful routine. It's basically a wrapper - * around the the translation "engine" trans() - */ -long /* #chars copied, <0 if any macros are */ - /* undefined */ -epicsShareAPI macExpandString( - MAC_HANDLE *handle, /* opaque handle */ - - char *src, /* source string */ - - char *dest, /* destination string */ - - long maxlen ) /* maximum number of characters to copy */ - /* to destination string */ -{ - MAC_ENTRY entry; - char *s, *d; - long length; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - macErrMessage0( -1, "macExpandString: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macExpandString( %s, maxlen = %ld )\n", src, maxlen ); - - /* expand raw values if necessary */ - if ( expand( handle ) < 0 ) - macErrMessage0( -1, "macExpandString: failed to expand raw values" ); - - /* fill in necessary fields in fake macro entry struncture */ - entry.name = ""; - entry.error = FALSE; - - /* expand the string */ - s = src; - d = dest; - *d = '\0'; - trans( handle, &entry, 0, "", &s, &d, d + maxlen ); - - /* return +/- #chars copied depending on successful expansion */ - length = d - dest; - length = ( entry.error ) ? -length : length; - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macExpandString() -> %ld\n", length ); - - return length; -} - -/* - * Define the value of a macro. A NULL value deletes the macro if it - * already existed - */ -long /* length of value */ -epicsShareAPI macPutValue( - MAC_HANDLE *handle, /* opaque handle */ - - char *name, /* macro name */ - - char *value ) /* macro value */ -{ - MAC_ENTRY *entry; /* pointer to this macro's entry structure */ - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - macErrMessage0( -1, "macPutValue: NULL or invalid handle\n" ); - return -1; - } - - if ( handle->debug & 1 ) - epicsPrintf( "macPutValue( %s, %s )\n", name, value ? value : "NULL" ); - - /* handle NULL value case: if name was found, delete entry (may be - several entries at different scoping levels) */ - if ( value == NULL ) { - while ( ( entry = lookup( handle, name, FALSE ) ) != NULL ) - delete( handle, entry ); - return 0; - } - - /* look up macro name */ - entry = lookup( handle, name, FALSE ); - - /* new entry must be created if macro doesn't exist or if it only - exists at a lower scoping level */ - if ( entry == NULL || entry->level < handle->level ) { - entry = create( handle, name, FALSE ); - if ( entry == NULL ) { - macErrMessage2( -1, "macPutValue: failed to create macro %s = %s", - name, value ); - return -1; - } - } - - /* copy raw value */ - if ( rawval( handle, entry, value ) == NULL ) { - macErrMessage2( -1, "macPutValue: failed to copy macro %s = %s", - name, value ) ; - return -1; - } - - /* return length of value */ - return strlen( value ); -} - -/* - * Return the value of a macro - */ -long /* #chars copied (<0 if undefined) */ -epicsShareAPI macGetValue( - MAC_HANDLE *handle, /* opaque handle */ - - char *name, /* macro name or reference */ - - char *value, /* string to receive macro value or name */ - /* argument if macro is undefined */ - - long maxlen ) /* maximum number of characters to copy */ - /* to value */ -{ - MAC_ENTRY *entry; /* pointer to this macro's entry structure */ - long length; /* number of characters returned */ - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - macErrMessage0( -1, "macGetValue: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - epicsPrintf( "macGetValue( %s )\n", name ); - - /* look up macro name */ - entry = lookup( handle, name, FALSE ); - - /* if maxlen <= 0 or VALUE == NULL just return -1 / 0 for undefined / - defined macro */ - if ( maxlen <= 0 || value == NULL ) { - return ( entry == NULL ) ? -1 : 0; - } - - /* if not found, copy name to value and return minus #chars copied */ - if ( entry == NULL ) { - strncpy( value, name, maxlen ); - return ( value[maxlen-1] == '\0' ) ? - (long) strlen( name ) : -maxlen; - } - - /* expand raw values if necessary; if fail (can only fail because of - memory allocation failure), return same as if not found */ - if ( expand( handle ) < 0 ) { - macErrMessage0( -1, "macGetValue: failed to expand raw values" ); - strncpy( value, name, maxlen ); - return ( value[maxlen-1] == '\0' ) ? - (long) strlen( name ) : -maxlen; - } - - /* copy value and return +/- #chars copied depending on successful - expansion */ - strncpy( value, entry->value, maxlen ); - length = ( value[maxlen-1] == '\0' ) ? entry->length : maxlen; - - return ( entry->error ) ? -length : length; -} - -/* - * Free up all storage associated with and delete a macro substitution - * context - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macDeleteHandle( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry, *nextEntry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - macErrMessage0( -1, "macDeleteHandle: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macDeleteHandle()\n" ); - - /* delete all entries */ - for ( entry = first( handle ); entry != NULL; entry = nextEntry ) { - nextEntry = next( entry ); - delete( handle, entry ); - } - - /* clear magic field and free context structure */ - handle->magic = 0; - dbmfFree( handle ); - - return 0; -} - -/* - * Mark the start of a new scoping level - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPushScope( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - macErrMessage0( -1, "macPushScope: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macPushScope()\n" ); - - /* increment scoping level */ - handle->level++; - - /* create new "special" entry of name "" */ - entry = create( handle, "", TRUE ); - if ( entry == NULL ) { - handle->level--; - macErrMessage0( -1, "macPushScope: failed to push scope" ); - return -1; - } - - return 0; -} - -/* - * Pop all macros defined since the last call to macPushScope() - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPopScope( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry, *nextEntry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - macErrMessage0( -1, "macPopScope: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macPopScope()\n" ); - - /* check scoping level isn't already zero */ - if ( handle->level == 0 ) { - macErrMessage0( -1, "macPopScope: no scope to pop" ); - return -1; - } - - /* look up most recent scope entry */ - entry = lookup( handle, "", TRUE ); - if ( entry == NULL ) { - macErrMessage0( -1, "macPopScope: no scope to pop" ); - return -1; - } - - /* delete scope entry and all macros defined since it */ - for ( ; entry != NULL; entry = nextEntry ) { - nextEntry = next( entry ); - delete( handle, entry ); - } - - /* decrement scoping level */ - handle->level--; - - return 0; -} - -/* - * Report macro details to standard output - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macReportMacros( - MAC_HANDLE *handle ) /* opaque handle */ -{ - char *format = "%-1s %-16s %-16s %s\n"; - MAC_ENTRY *entry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - macErrMessage0( -1, "macReportMacros: NULL or invalid handle\n" ); - return -1; - } - - /* expand raw values if necessary; report but ignore failure */ - if ( expand( handle ) < 0 ) - macErrMessage0( -1, "macGetValue: failed to expand raw values" ); - - /* loop through macros, reporting names and values */ - epicsPrintf( format, "e", "name", "rawval", "value" ); - epicsPrintf( format, "-", "----", "------", "-----" ); - for ( entry = first( handle ); entry != NULL; entry = next( entry ) ) { - - /* differentiate between "special" (scope marker) and ordinary - entries */ - if ( entry->special ) - epicsPrintf( format, "s", "----", "------", "-----" ); - else - epicsPrintf( format, entry->error ? "*" : " ", entry->name, - entry->rawval ? entry->rawval : "", - entry->value ? entry->value : ""); - } - - return 0; -} - -/******************** beginning of static functions ********************/ - -/* - * Return pointer to first macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *first( MAC_HANDLE *handle ) -{ - return ( MAC_ENTRY * ) ellFirst( &handle->list ); -} - -/* - * Return pointer to last macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *last( MAC_HANDLE *handle ) -{ - return ( MAC_ENTRY * ) ellLast( &handle->list ); -} - -/* - * Return pointer to next macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *next( MAC_ENTRY *entry ) -{ - return ( MAC_ENTRY * ) ellNext( ( ELLNODE * ) entry ); -} - -/* - * Return pointer to previous macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *previous( MAC_ENTRY *entry ) -{ - return ( MAC_ENTRY * ) ellPrevious( ( ELLNODE * ) entry ); -} - -/* - * Create new macro entry (can assume it doesn't exist) - */ -static MAC_ENTRY *create( MAC_HANDLE *handle, char *name, long special ) -{ - ELLLIST *list = &handle->list; - MAC_ENTRY *entry = ( MAC_ENTRY * ) dbmfMalloc( sizeof( MAC_ENTRY ) ); - - if ( entry != NULL ) { - entry->name = Strdup( name ); - if ( entry->name == NULL ) { - dbmfFree( entry ); - entry = NULL; - } - else { - entry->rawval = NULL; - entry->value = NULL; - entry->length = 0; - entry->error = FALSE; - entry->visited = FALSE; - entry->special = special; - entry->level = handle->level; - - ellAdd( list, ( ELLNODE * ) entry ); - } - } - - return entry; -} - -/* - * Look up macro entry with matching "special" attribute by name - */ -static MAC_ENTRY *lookup( MAC_HANDLE *handle, char *name, long special ) -{ - MAC_ENTRY *entry; - - /* search backwards so scoping works */ - for ( entry = last( handle ); entry != NULL; entry = previous( entry ) ) { - if ( entry->special != special ) - continue; - if ( strcmp( name, entry->name ) == 0 ) - break; - } - - return entry; -} - -/* - * Copy raw value to macro entry - */ -static char *rawval( MAC_HANDLE *handle, MAC_ENTRY *entry, char *value ) -{ - if ( entry->rawval != NULL ) - dbmfFree( entry->rawval ); - entry->rawval = Strdup( value ); - - handle->dirty = TRUE; - - return entry->rawval; -} - -/* - * Delete a macro entry; requires re-expansion of macro values since this - * macro may be referenced by another one - */ -static void delete( MAC_HANDLE *handle, MAC_ENTRY *entry ) -{ - ELLLIST *list = &handle->list; - - ellDelete( list, ( ELLNODE * ) entry ); - - dbmfFree( entry->name ); - if ( entry->rawval != NULL ) - dbmfFree( entry->rawval ); - if ( entry->value != NULL ) - free( entry->value ); - dbmfFree( entry ); - - handle->dirty = TRUE; -} - -/* - * Expand macro definitions (expensive but done very infrequently) - */ -static long expand( MAC_HANDLE *handle ) -{ - MAC_ENTRY *entry; - char *rawval; - char *value; - - if ( !handle->dirty ) - return 0; - - for ( entry = first( handle ); entry != NULL; entry = next( entry ) ) { - - if ( handle->debug & 2 ) - epicsPrintf( "\nexpand %s = %s\n", entry->name, - entry->rawval ? entry->rawval : "" ); - - if ( entry->value == NULL ) { - if ( ( entry->value = malloc( MAC_SIZE + 1 ) ) == NULL ) { - return -1; - } - } - - /* start at level 1 so quotes and escapes will be removed from - expanded value */ - rawval = entry->rawval; - value = entry->value; - *value = '\0'; - entry->error = FALSE; - trans( handle, entry, 1, "", &rawval, &value, entry->value + MAC_SIZE ); - entry->length = value - entry->value; - entry->value[MAC_SIZE] = '\0'; - } - - handle->dirty = FALSE; - - return 0; -} - -/* - * Translate raw macro value (recursive). This is by far the most complicated - * of the macro routines and calls itself recursively both to translate any - * macros referenced in the name and to translate the resulting name - * - * For now, use default special characters - */ -static void trans( MAC_HANDLE *handle, MAC_ENTRY *entry, long level, - char *term, char **rawval, char **value, char *valend ) -{ - char quote; - char *r, *v, *n2, *r2; - char name2[MAC_SIZE + 1]; - long discard; - long macRef; - char *macEnd; - MAC_ENTRY *entry2; - - /* return immediately if raw value is NULL */ - if ( *rawval == NULL ) return; - - /* discard quotes and escapes if level is > 0 (i.e. if these aren't - the user's quotes and escapes) */ - discard = ( level > 0 ); - - /* debug output */ - if ( handle->debug & 2 ) - epicsPrintf( "trans-> level = %ld, maxlen = %4d, discard = %s, " - "rawval = %s\n", level, valend - *value, discard ? "T" : "F", *rawval ); - - /* initially not in quotes */ - quote = 0; - - /* scan characters until hit terminator or end of string */ - for ( r = *rawval, v = *value; strchr( term, *r ) == NULL; r++ ) { - - /* handle quoted characters (quotes are discarded if in name) */ - if ( quote ) { - if ( *r == quote ) { - quote = 0; - if ( discard ) continue; - } - } - else if ( *r == '"' || *r == '\'' ) { - quote = *r; - if ( discard ) continue; - } - - /* macro reference if '$' followed by '(' or '{' */ - macRef = ( *r == '$' && *( r + 1 ) != '\0' && - strchr( "({", *( r + 1 ) ) != NULL ); - - /* if not macro reference (macros are not expanded in single quotes) */ - if ( quote == '\'' || !macRef ) { - - /* handle escaped characters (escape is discarded if in name) */ - if ( *r == '\\' && *( r + 1 ) != '\0' ) { - if ( v < valend && !discard ) *v++ = '\\'; - if ( v < valend ) *v++ = *++r; - } - - /* copy character to output */ - else { - if ( v < valend ) *v++ = *r; - } - - /* ensure string remains properly terminated */ - if ( v < valend ) *v = '\0'; - } - - /* macro reference */ - else { - - /* step over '$(' or '${' */ - r++; - macEnd = ( *r == '(' ) ? ")" : "}"; - r++; - - /* translate name (may contain macro references); truncated - quietly if too long but always guaranteed zero-terminated */ - n2 = name2; - *n2 = '\0'; - trans( handle, entry, level + 1, macEnd, &r, &n2, n2 + MAC_SIZE ); - name2[MAC_SIZE] = '\0'; - - /* look up resultant name; if not there, set error flag and - copy reference */ - if ( ( entry2 = lookup( handle, name2, FALSE ) ) == NULL ) { - if(!handle->suppressWarning) { - entry->error = TRUE; - macErrMessage2( -1, "%s: %s referenced but undefined", - entry->name, name2 ); - } - sprintf( v, "$(%s)", name2 ); v += strlen( v ); - } - - /* check for recursive reference; if so, set error flag and - copy reference */ - else if ( entry2->visited ) { - entry->error = TRUE; - macErrMessage2( -1, "%s: %s referenced recursively", - entry->name, entry2->name ); - sprintf( v, "$(%s)", name2 ); v += strlen( v ); - } - - /* if all expanded values are valid (not "dirty") copy the - value directly */ - else if ( !handle->dirty ) { - strcpy( v, entry2->value ); v += strlen( v ); - } - - /* otherwise, translate raw value */ - else { - r2 = entry2->rawval; - entry2->visited = TRUE; - trans( handle, entry, level + 1, "", &r2, &v, valend ); - entry2->visited = FALSE; - } - } - } - - /* debug output */ - if ( handle->debug & 2 ) - epicsPrintf( "<-trans level = %ld, length = %4d, value = %s\n", - level, v - *value, *value ); - - /* update pointers to next characters to scan in raw value and to fill - in in output value (if at end of input, step back so terminator is - still there to be seen) */ - *rawval = ( *r == '\0' ) ? r - 1 : r; - *value = v; - - return; -} - -/* - * strdup() implementation (because it's not always available) - */ -char *Strdup( char *string ) -{ - char *copy = dbmfMalloc( strlen( string ) + 1 ); - - if ( copy != NULL ) - strcpy( copy, string ); - - return copy; -} - -/* $Log$ - * Revision 1.7 1998/02/20 21:45:16 evans - * Made a large number of changes to epicsShareThings in libCom routines - * to get imports and exports straight on WIN32. Not everything is fixed - * at this time. - * - * Revision 1.6 1997/06/05 18:28:48 mrk - * Allow message about referenced but undefined to be suppressed - * - * Revision 1.5 1997/05/01 19:57:32 jhill - * updated dll keywords - * - * Revision 1.4 1997/04/30 19:10:04 mrk - * Fix long memory free list problem - * - * Revision 1.3 1996/11/02 02:05:24 jhill - * %d => %ld - * - * Revision 1.2 1996/09/16 21:07:10 jhill - * fixed warnings - * - * Revision 1.1 1996/07/10 14:49:48 mrk - * added macLib - * - * Revision 1.9 1996/06/26 09:43:14 wlupton - * first released version - * - */ diff --git a/src/libCom/macLib/macLib.h b/src/libCom/macLib/macLib.h deleted file mode 100644 index a3cdc08aa..000000000 --- a/src/libCom/macLib/macLib.h +++ /dev/null @@ -1,225 +0,0 @@ -/* $Id$ - * - * Definitions for macro substitution library (macLib) - * - * William Lupton, W. M. Keck Observatory - */ - -/* - * EPICS include files needed by this file - */ -#include "ellLib.h" -#include "epicsPrint.h" -#include "errMdef.h" -#include "shareLib.h" - -/* - * Standard FALSE and TRUE macros - */ -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -/* - * Magic number for validating context. - */ -#define MAC_MAGIC 0xbadcafe /* ...sells sub-standard coffee? */ - -/* - * Maximum size of macro name or value string (simpler to make fixed) - */ -#define MAC_SIZE 256 - -/* - * Macros passing __FILE__ and __LINE__ to what will be macErrPrintf() - */ -#define macErrMessage0( _status, _format ) \ - errPrintf( _status, __FILE__, __LINE__, _format ) - -#define macErrMessage1( _status, _format, _arg1 ) \ - errPrintf( _status, __FILE__, __LINE__, _format, _arg1 ) - -#define macErrMessage2( _status, _format, _arg1, _arg2 ) \ - errPrintf( _status, __FILE__, __LINE__, _format, _arg1, _arg2 ) - -#define macErrMessage3( _status, _format, _arg1, _arg2, _arg3 ) \ - errPrintf( _status, __FILE__, __LINE__, _format, _arg1, _arg2, _arg3 ) - -/* - * Special characters - */ -#define MAC_STARTCHARS "$" /* characters that indicate macro ref */ -#define MAC_LEFTCHARS "{(" /* characters to left of macro name */ -#define MAC_RIGHTCHARS "})" /* characters to right of macro name */ -#define MAC_SEPARCHARS "," /* characters separating macro defns */ -#define MAC_ASSIGNCHARS "=" /* characters denoting values assignment */ -#define MAC_ESCAPECHARS "\\" /* characters escaping the next char */ - -typedef struct { - char *start; - char *left; - char *right; - char *separ; - char *assign; - char *escape; -} MAC_CHARS; - -/* - * Macro substitution context. One of these contexts is allocated each time - * macCreateHandle() is called - */ -typedef struct { - long magic; /* magic number (used for authentication) */ - MAC_CHARS chars; /* special characters */ - long dirty; /* values need expanding from raw values? */ - long level; /* scoping level */ - long debug; /* debugging level */ - ELLLIST list; /* macro name / value list */ - int suppressWarning;/*suppress warning messages*/ -} MAC_HANDLE; - -/* - * Entry in linked list of macro definitions - */ -typedef struct mac_entry { - ELLNODE node; /* prev and next pointers */ - char *name; /* macro name */ - char *rawval; /* raw (unexpanded) value */ - char *value; /* expanded macro value */ - long length; /* length of value */ - long error; /* error expanding value? */ - long visited; /* ever been visited? */ - long special; /* special (internal) entry? */ - long level; /* scoping level */ -} MAC_ENTRY; - -/* - * Function prototypes (core library) - */ -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macCreateHandle( - MAC_HANDLE **handle, /* address of variable to receive pointer */ - /* to new macro substitution context */ - - char *pairs[] /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -); - -epicsShareFunc void -epicsShareAPI macSuppressWarning( - MAC_HANDLE *handle, /* opaque handle */ - - int falseTrue /*0 means ussue, 1 means suppress*/ -); - -epicsShareFunc long /* #chars copied, <0 if any macros are */ - /* undefined */ -epicsShareAPI macExpandString( - MAC_HANDLE *handle, /* opaque handle */ - - char *src, /* source string */ - - char *dest, /* destination string */ - - long maxlen /* maximum number of characters to copy */ - /* to destination string */ -); - - -epicsShareFunc long /* length of value */ -epicsShareAPI macPutValue( - MAC_HANDLE *handle, /* opaque handle */ - - char *name, /* macro name */ - - char *value /* macro value */ -); - -epicsShareFunc long /* #chars copied (<0 if undefined) */ -epicsShareAPI macGetValue( - MAC_HANDLE *handle, /* opaque handle */ - - char *name, /* macro name or reference */ - - char *value, /* string to receive macro value or name */ - /* argument if macro is undefined */ - - long maxlen /* maximum number of characters to copy */ - /* to value */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macDeleteHandle( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPushScope( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPopScope( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macReportMacros( - MAC_HANDLE *handle /* opaque handle */ -); - -/* - * Function prototypes (utility library) - */ -epicsShareFunc long /* #defns encountered; <0 = ERROR */ -epicsShareAPI macParseDefns( - MAC_HANDLE *handle, /* opaque handle; can be NULL if default */ - /* special characters are to be used */ - - char *defns, /* macro definitions in "a=xxx,b=yyy" */ - /* format */ - - char **pairs[] /* address of variable to receive pointer */ - /* to NULL-terminated array of {name, */ - /* value} pair strings; all storage is */ - /* allocated contiguously */ -); - -epicsShareFunc long /* #macros defined; <0 = ERROR */ -epicsShareAPI macInstallMacros( - MAC_HANDLE *handle, /* opaque handle */ - - char *pairs[] /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -); - -/* $Log$ - * Revision 1.5 1998/02/20 21:45:17 evans - * Made a large number of changes to epicsShareThings in libCom routines - * to get imports and exports straight on WIN32. Not everything is fixed - * at this time. - * - * Revision 1.4 1997/06/05 18:28:49 mrk - * Allow message about referenced but undefined to be suppressed - * - * Revision 1.3 1997/05/01 19:57:34 jhill - * updated dll keywords - * - * Revision 1.2 1996/09/16 21:07:10 jhill - * fixed warnings - * - * Revision 1.1 1996/07/10 14:49:51 mrk - * added macLib - * - * Revision 1.8 1996/06/26 09:43:16 wlupton - * first released version - * - */ diff --git a/src/libCom/macLib/macLibNOTES b/src/libCom/macLib/macLibNOTES deleted file mode 100644 index d0a396215..000000000 --- a/src/libCom/macLib/macLibNOTES +++ /dev/null @@ -1,160 +0,0 @@ -# $Id$ -# -# Test input file for macTest filter, doubling as notes on usage of the -# macro library. Some special strings at start of line are supported: -# -# 1. '#' indicates a comment and is ignored -# -# 2. '%set' is followed by "a=b, c=d" style macro definitions which are -# passed through macParseDefs() and macInstallMacros() -# -# 3. '%push' pushes a scoping level by calling macPushScope() -# -# 4. '%pop' pops a scoping level by calling macPopScope() -# -# 5. '%report' reports macro definitions by calling macReportMacros() -# -# 6. all other lines are expanded by callins macExpandString() -# -introduction ------------- - -See the README file for the library specification and see the header -comments of macCore.c (the core library) for notes on what has been -implemented. - -This file contains tutorial information and examples. It's the -best documentation that there is. - - -simple examples ---------------- - -To define the a, b, c and d macros to be 1, 2, 3 and 4 (note optional -white space is ignored around '=' and ',' characters): - -%set a=1, b=2, c = 3 , d = 4 - -These macros can be dereferenced using '$(xxx)' or '${xxx}' notation: -a = $(a), b = $(b), c = ${c}, d = ${d}. - -Macro values can reference other macros in an arbitrarily complex way. -The only current restrictions are that a macro name or value cannot -exceed 256 characters in length. This restriction could fairly easily -be lifted. - -Here's an example: - -%set x = ${$(y$(z))} - -If this is expanded now: $(x), it won't work because the other macros -aren't defined yet. So: - -%set cash=lucre, ywork=cash, z=work - -Now expansion yields "$(x)" (work -> ywork -> cash -> lucre). - -One can inadvertently set up circular references. For example: - -%set mac1=$(mac2), mac2=$(mac3), mac3=$(mac1) - -An attempt to dereference mac1 gives $(mac1). When a macro expansion -fails, the translation that failed is replaced with the text that could -not be expanded. - -You can get a report of current macro definitions by doing -%report - -The '*' character in the first column indicates a problem expanding that -macro. We'll get rid of these problem macros: -%set mac1, mac2, mac3 - -You can also push a new scoping level by doing -%push - -and pop back to it by doing -%pop - -For example: -%set level = 0 -%push -%set level = 1 -%push -%set level = 2 -%push -%set level = 3 -%report -Level is $(level) -%pop -Level is $(level) -%pop -Level is $(level) -%pop -Level is $(level) -%pop -(That last error was deliberate) - - -quote and escape handling -------------------------- - -Both single and double quotes are supported, as are escapes. Some of the -implications are quite subtle and some of the design choices made may not -meet with universal approval. The basic idea is that a string in which -macro references have been expanded should look like the source string -apart from the where macros have been expanded. This implies that quote -and escape characters should not be removed from the string. - -Single and double quotes are different in that (as in most shells), -macros are substituted within double quotes but not within single -quotes. Back quotes are not special characters. Missing quotes at the -end of a string are automatically and quietly supplied. - -We've already seen some examples but what happens here: $(x)? -Should not that have been expanded? Why wasn't it? The answer is given -later on. As a clue, this is: $(x). This isn't: $(x)! - -Characters may be escaped by preceding them with a \ (back slash). -Escapes work even within quotes, which is more like C than most shells. -Thus, '\'' works, and it doesn't with the C shell. - -Quotes and escapes can also be used in "a=b, c=d" style assignments -but they are not part of macro names. For example: - -%set \= = equal, \' = quote - -defines macros called "=" and "'", not "\=" and "\'". To reference -these macros, "$(=)" ('$(=)') works because "=" is not special in -this context. However the quote must be escaped because quotes are -always special, as in "$(\')" ('$(\')'). - - -miscellaneous notes -------------------- - -In the "a=b, c=d" strings that are parsed by macParseDefns(), a macro -can be set to an empty value by putting nothing after the equals -sign, as in - -%set empty = -resulting in empty = "$(empty)". Omitting the equal sign gives the -macro a NULL rather than empty value (with the result that the macro -is deleted since this is how macPutValue() interprets a NULL value), so - -%set empty -deletes the empty macro, as can be seen when we try to de-reference -it: $(empty). - -The only special characters in these "a=b, c=d" strings are "=", "," -and white space surrounding these characters (plus quotes and escapes -of course). This means that - -%set fred 2 -actually sets a macro called "fred 2" to a NULL value (i.e. it deletes -it if it existed). This is probably wrong and the space should be -taken as an implicit '='. However, to do this and still to support -ignored white space around '=' and ',' characters is a bigger change -than I am prepared to make at present. - -What was the problem expanding "$(x)" before? It was single quotes -from words like "wasn't"! Is this a problem or a feature? diff --git a/src/libCom/macLib/macLibREADME b/src/libCom/macLib/macLibREADME deleted file mode 100644 index ac0598539..000000000 --- a/src/libCom/macLib/macLibREADME +++ /dev/null @@ -1,294 +0,0 @@ -README file for etc/macLib directory ------------------------------------- - -This directory contains all files necessary to build and test the -EPICS macro library macLib. The specification for this library -appears later in this file. - -Files in this release are: - --rw-r--r-- 1 wlupton 141 Sep 22 1995 Makefile --rw-r--r-- 1 wlupton 522 Jun 23 20:42 Makefile.Unix --rw-r--r-- 1 wlupton 473 Jun 23 20:43 Makefile.Vx - --rw-r--r-- 1 wlupton 5052 Jun 25 23:17 NOTES --rw-r--r-- 1 wlupton 10429 Jun 25 23:34 README - --rw-r--r-- 1 wlupton 20158 Jun 25 23:40 macCore.c --rw-r--r-- 1 wlupton 5056 Jun 25 21:33 macLib.h --rw-r--r-- 1 wlupton 2050 Jun 25 23:18 macTest.c --rw-r--r-- 1 wlupton 7307 Jun 25 23:13 macUtil.c - -25-Jun-96, William Lupton (wlupton@keck.hawaii.edu), CVS tag: macLib-1-0 ------------------------------------------------------------------------- - -first release - ------------------------------------------------------------------------- - -This is the original final specification for the EPICS macro library: - -From wlupton Mon Feb 19 14:10:08 1996 -To: tech-talk@aps.anl.gov -Subject: Re: macro substitution -Content-Length: 9716 -X-Lines: 251 -Status: RO - -Dear all, - - Here's yet another proposal for the macro library. There has been some -private discussion between myself, Jim and Marty, and I hope that this -is nearly final (or final enough to be implemented). After all the -discussion, the actual implementation is going to be a breeze! - - The biggest changes are a move a way from the "filesystem-like" -routine names and a reduction in the emphasis placed on the standalone -tool. - - I'm afraid there are still a few minor issues to be resolved but -probably nothing that can't wait for an alpha release. - - William - ------------------------------------------------------------------------- - -1. Macro substitution library ------------------------------ - -This library could be used directly by applications which need to -support macro substitution. It will be implemented on all platforms. - -1.1 Core library ----------------- - -The core library provides a minimal set of basic operations. Some -utility routines, described later, use core routines to provide a more -convenient interface for some purposes. - -a) long macCreateHandle( MAC_HANDLE **handle, char *pairs[] ); - void macSuppressWarning(MAC_HANDLE *handle,int falseTrue); - - Creates a new macro substitution context and returns an opaque handle - to that context. An application can, if it desires, have several - active contexts, although most will not. - - If desired, an initial set of macro definitions may be loaded - ("pairs" is set to NULL to avoid this). The definitions are in the - "standard" pairs format, as described under macParseDefns(). - - Note that MAC_HANDLE is a typedef for the context structure. The - opaque handle is of type "MAC_HANDLE *", which is a pointer to the - context structure. The memory for this context is allocated by this - routine. - - macSuppressWarning can be called to suppress the marning message - when macExpandString cant expand a macro. A non zero value will - suppress the messages. - - -b) long macGetXxxx( MAC_HANDLE *handle, ); - long macPutXxxx( MAC_HANDLE *handle, ); - - These routines replace the earlier-proposed macIoctl(). "Xxxx" is the - name of the attribute in question. An initial list (which can grow) - might be: - - Attribute default value - --------- ------------- - ErrRoutine errPrintf - Verbose TRUE - - StartChars "$" - LeftChars "{(" - RightChars "})" - SeparChars "," - AssignChars "=" - - A NULL handle can be used to set or get global values (used by - macParseDefns()). - -c) long macGetValue ( MAC_HANDLE *handle, char *name, - char *value, long maxlen ); - - Returns up to maxlen characters of the value of macro "name". "value" - will be zero-terminated if the length of the value is less than - maxlen. The function value will be the number of characters copied to - "value" (see below for behavior if the macro is undefined). If maxlen - is zero, no characters will be copied to "value" (which can be NULL) - and the call can be used to check whether the macro is defined. Note - that truncation of the value is therefore not reported. Is this a - problem? - - If the macro is undefined, the macro reference will be returned in - the value string (if permitted by maxlen) and the function value will - be _minus_ the number of characters copied. Note that treatment of - maxlen is intended to be consistent with what people are used to with - strncpy(). - - "name" can either be just the macro name or can have the syntax of a - macro reference (e.g. it can be "fred" or "$(fred)"). In the latter - case, any characters after the logical end of the macro reference - will be ignored (this is to ease expansion of a string which may - contain many macro references), but no means of returning the number - of characters scanned in "name" is provided. [It may prove expedient - to make macGetValue() simpler and provide a separate routine with - more parameters which returns this information.] - - If the name or value contains a macro reference then the reference - will be expanded recursively. This expansion will detect a direct or - indirect self reference. - - Macro references begin with a "$" immediately followed by either a - "(" or a "{" character. The reference is terminated by the matching - ")" or "}" character. These characters can be changed via - macPut{Start,Left,Right}Chars() above. - -d) long macPutValue( MAC_HANDLE *handle, char *name, char *value ); - - Sets the value of the macro "name". If "value" is NULL, undefines - "name" (it's not an error if "name" was already undefined). Macros - referenced by "value" need not be defined at this point. - - The function value is the length of the value. - -e) long macDeleteHandle( MAC_HANDLE *handle ); - - Marks a handle invalid, and frees all storage associated with it. - - Note that this does not free any strings into which macro values have - been returned. Macro values are always returned into strings which - were pre-allocated by the caller. - -f) long macPushScope( MAC_HANDLE *handle ); - - Marks the start of a new scoping level such that all definitions made - up until the next macPopScope() call will be lost on macPopScope() - and those current at macPushScope() will be re-instated. - - May not be implemented first time round. - -g) long macPopScope( MAC_HANDLE *handle ); - - See above. - -h) Error handling - - These routines conform to 0 (=OK) for success, -1 (=ERROR) for - failure, and small positive values for extra info. I contravened this - for macGetValue() and macExpandString() because I felt that it was - worth returning information both on success / failure and on value - length. - - Errors are reported using an errPrintf()-compatible routine. - - A "verbose" variable will control error reporting. - - -1.2 Utility library -------------------- - -These are convenience functions. If other useful functions emerge during -implementation, the list may grow. - -a) macParseDefns( char *defns, char **pairs[] ); - - This takes a set of macro definitions in "a=xxx,b=yyy" format and - converts them into an array of pointers to character strings which - are, in order, "first name", "first value", "second name", "second - value" etc. The array is terminated with two NULL pointers and all - storage is allocated contiguously so that it can be freed with a - single call to free(). - - This routine is independent of any handle and provides a generally - useful service which may be used elsewhere. Any macro references in - values are not expanded at this point since the referenced macros may - be defined or redefined before the macro actually has to be - translated. - - Shell-style escapes and quotes are supported, as are things like - "A=B,B=$(C$(A)),CA=CA,CB=CB" (sets B to "CB"). White space is - significant within values but ignored elsewhere (i.e. surrounding "=" - and "," characters). - - Probably noone will ever want to, but the special meanings of "$", - "{", "}", "(", ")", "=" and "," can all be changed via macPutXxxx() - calls. This routine does not have a handle argument, so they must be - changed globally for it to use the new definitions. Should it have a - handle argument? This makes it more of a pain to use but guarantees - that there will be no conflicts. I think it should really. - - The function value is the number of definitions encountered, or -1 if - the supplied string is invalid. - -b) long macInstallMacros( MAC_HANDLE *handle, char *pairs[] ); - - This takes an array of pairs as defined above and installs them as - definitions by calling macPutValue(). The pairs array is terminated - by a NULL pointer. - - The function value is the number of macros defined. - -c) long macExpandString( MAC_HANDLE *handle, char *src, - char *dest, long maxlen ); - - This operates on a string which may contain macro references. It - parses the string looking for such references and passes them to - macGetValue() for translation. It returns the expanded string in the - supplied argument. - - The function value is similar to that of macGetValue(). Its absolute - value is the number of characters copied. If negative, at least one - undefined macro has been left unexpanded. - -d) long macReportMacros( MAC_HANDLE *handle ); - - This reports details of current definitions to standard output (or - standard error?). It's purely for debugging purposes. - - -2. Macro substitution tool --------------------------- - -This section is hardly changed from the previous version. The library will -be implemented first. - -A "macsub" (or "mactool"?) application will be written which would use the -above library and use a command like: - -macsub a=b,c=d e=f -Iaaa -Ibbb - -to parse a file like: - -# comment -%include filename -%xxx = ppp -%yyy = $(xxx) - - -There will also be options to read and write specified files, control the -comment character, control the command prefix, change the macro substitution -characters etc. - -Syntax will be a loose subset of corresponding shell syntax. - -The use of a command prefix should be optional and perhaps it should default -to an empty string. However there will be cases where the file in question -has a syntax over which we have no control, which may include assignments, -"set" commands, "define" commands etc. This is why I proposed a command -prefix, which might be an arbitrary string such as "macro " or might just -be "%" as in the above example. - -The tool can also support the following syntax (or perhaps some equivalent -syntax which will sit more easily inside a file that may have a completely -different syntax from it?): - -file gizmo_database.db -{ - instance1{ pre=part1,parm=big, alarm_limit=20 } - instance2{ pre=part2,parm=medium,alarm_limit=30 } -} - -as an implied multiple include of "gizmo_database.db" with the specified -macro definitions for each include (here's a good application for -macPushScope() and macPopScope() actually). diff --git a/src/libCom/macLib/macUtil.c b/src/libCom/macLib/macUtil.c deleted file mode 100644 index d30be577b..000000000 --- a/src/libCom/macLib/macUtil.c +++ /dev/null @@ -1,282 +0,0 @@ -/* $Id$ - * - * Implementation of utility macro substitution library (macLib) - * - * William Lupton, W. M. Keck Observatory - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "macLib.h" - -/* - * Parse macros definitions in "a=xxx,b=yyy" format and convert them to - * a contiguously allocated array pointers to names and values, and the - * name and value strings, terminated with two NULL pointers. Quotes - * and escapes are honored but only removed from macro names (not - * values) - * - * Doesn't yet use handle (so uses default special characters) - */ -long /* #defns encountered; <0 = ERROR */ -epicsShareAPI macParseDefns( - MAC_HANDLE *handle, /* opaque handle; can be NULL if default */ - /* special characters are to be used */ - - char *defns, /* macro definitions in "a=xxx,b=yyy" */ - /* format */ - - char **pairs[] ) /* address of variable to receive pointer */ - /* to NULL-terminated array of {name, */ - /* value} pair strings; all storage is */ - /* allocated contiguously */ -{ - long i; - long num; - long quote; - long escape; - long nbytes; - char **ptr; - char **end; - long *del; - char *memCp, **memCpp; - char *c, *s, *d, **p; - enum { preName, inName, preValue, inValue } state; - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macParseDefns( %s )\n", defns ); - - /* allocate temporary pointer arrays; in worst case they need to have - as many entries as the length of the defns string */ - ptr = ( char ** ) malloc( strlen( defns ) * sizeof( char * ) ); - end = ( char ** ) malloc( strlen( defns ) * sizeof( char * ) ); - del = ( long * ) malloc( strlen( defns ) * sizeof( long ) ); - if ( ptr == NULL || end == NULL || del == NULL ) goto error; - - /* go through definitions, noting pointers to starts and ends of macro - names and values; honor quotes and escapes; ignore white space - around assignment and separator characters */ - num = 0; - del[0] = FALSE; - quote = 0; - state = preName; - for ( c = defns; *c != '\0'; c++ ) { - - /* handle quotes */ - if ( quote ) - quote = ( *c == quote ) ? 0 : quote; - else if ( *c == '\'' || *c == '"' ) - quote = *c; - - /* handle escapes (pointer incremented below) */ - escape = ( *c == '\\' && *( c + 1 ) != '\0' ); - - switch ( state ) { - case preName: - if ( !quote && !escape && ( isspace( *c ) || *c == ',' ) ) break; - ptr[num] = c; - state = inName; - /* fall through (may be empty name) */ - - case inName: - if ( quote || escape || ( *c != '=' && *c != ',' ) ) break; - end[num] = c; - while ( end[num] > ptr[num] && isspace( *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - state = preValue; - if ( *c != ',' ) break; - del[num] = TRUE; - /* fall through (','; will delete) */ - - case preValue: - if ( !quote && !escape && isspace( *c ) ) break; - ptr[num] = c; - state = inValue; - /* fall through (may be empty value) */ - - case inValue: - if ( quote || escape || *c != ',' ) break; - end[num] = c; - while ( end[num] > ptr[num] && isspace( *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - state = preName; - break; - } - - /* if this was escape, increment pointer now (couldn't do - before because could have ignored escape at start of name - or value) */ - if ( escape ) c++; - } - - /* tidy up from state at end of string */ - switch ( state ) { - case preName: - break; - case inName: - end[num] = c; - while ( end[num] > ptr[num] && isspace( *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = TRUE; - case preValue: - ptr[num] = c; - case inValue: - end[num] = c; - while ( end[num] > ptr[num] && isspace( *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - } - - /* debug output */ - if ( handle != NULL && handle->debug & 4 ) - for ( i = 0; i < num; i += 2 ) - printf( "[%ld] %.*s = [%ld] %.*s (%s) (%s)\n", - (long) (end[i+0] - ptr[i+0]), (int) (end[i+0] - ptr[i+0]), ptr[i+0], - (long) (end[i+1] - ptr[i+1]), (int) (end[i+1] - ptr[i+1]), ptr[i+1], - del[i+0] ? "del" : "nodel", - del[i+1] ? "del" : "nodel" ); - - /* calculate how much memory to allocate: pointers followed by - strings */ - nbytes = ( num + 2 ) * sizeof( char * ); - for ( i = 0; i < num; i++ ) - nbytes += end[i] - ptr[i] + 1; - - /* allocate memory and set returned pairs pointer */ - memCp = malloc( nbytes ); - if ( memCp == NULL ) goto error; - memCpp = ( char ** ) memCp; - *pairs = memCpp; - - /* copy pointers and strings (memCpp accesses the pointer section - and memCp accesses the string section) */ - memCp += ( num + 2 ) * sizeof( char * ); - for ( i = 0; i < num; i++ ) { - - /* if no '=' followed the name, macro will be deleted */ - if ( del[i] ) - *memCpp++ = NULL; - else - *memCpp++ = memCp; - - /* copy value regardless of the above */ - strncpy( memCp, ptr[i], end[i] - ptr[i] ); - memCp += end[i] - ptr[i]; - *memCp++ = '\0'; - } - - /* add two NULL pointers */ - *memCpp++ = NULL; - *memCpp++ = NULL; - - /* remove quotes and escapes from names in place (unlike values, they - will not be re-parsed) */ - for ( p = *pairs; *p != NULL; p += 2 ) { - quote = 0; - for ( s = d = *p; *s != '\0'; s++ ) { - - /* quotes are not copied */ - if ( quote ) { - if ( *s == quote ) { - quote = 0; - continue; - } - } - else if ( *s == '\'' || *s == '"' ) { - quote = *s; - continue; - } - - /* escapes are not copied but next character is */ - if ( *s == '\\' && *( s + 1 ) != '\0' ) - s++; - - /* others are copied */ - *d++ = *s; - } - - /* need to terminate destination */ - *d++ = '\0'; - } - - /* free workspace */ - free( ptr ); - free( end ); - free( ( char * ) del ); - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macParseDefns() -> %ld\n", num / 2 ); - - /* success exit; return number of definitions */ - return num / 2; - - /* error exit */ -error: - macErrMessage0( -1, "macParseDefns: failed to allocate memory" ); - if ( ptr != NULL ) free( ptr ); - if ( end != NULL ) free( end ); - if ( del != NULL ) free( ( char * ) del ); - *pairs = NULL; - return -1; -} - -/* - * Install an array of name / value pairs as macro definitions. The - * array should have an even number of elements followed by at least - * one (preferably two) NULL pointers - */ -long /* #macros defined; <0 = ERROR */ -epicsShareAPI macInstallMacros( - MAC_HANDLE *handle, /* opaque handle */ - - char *pairs[] ) /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -{ - long n; - char **p; - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macInstallMacros( %s, %s, ... )\n", - pairs && pairs[0] ? pairs[0] : "NULL", - pairs && pairs[1] ? pairs[1] : "NULL" ); - - /* go through array defining macros */ - for ( n = 0, p = pairs; p != NULL && p[0] != NULL; n++, p += 2 ) { - if ( macPutValue( handle, p[0], p[1] ) < 0 ) - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macInstallMacros() -> %ld\n", n ); - - /* return number of macros defined */ - return n; -} - -/* $Log$ - * Revision 1.2 1996/09/16 21:07:11 jhill - * fixed warnings - * - * Revision 1.1 1996/07/10 14:49:55 mrk - * added macLib - * - * Revision 1.6 1996/06/26 09:43:19 wlupton - * first released version - * - */ diff --git a/src/libCom/misc/aToIPAddr.c b/src/libCom/misc/aToIPAddr.c deleted file mode 100644 index 6784470f9..000000000 --- a/src/libCom/misc/aToIPAddr.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * rational replacement for inet_addr() - * - * author: Jeff Hill - */ -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "bsdSocketResource.h" - -#ifndef LOCAL -#define LOCAL static -#endif - -#ifndef NELEMENTS -#define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) -#endif /*NELEMENTS*/ - -LOCAL int initIPAddr (struct in_addr ipAddr, unsigned short port, struct sockaddr_in *pIP); -LOCAL int addrArrayToUL (const long *pAddr, unsigned nElements, struct in_addr *pIpAddr); - -/* - * rational replacement for inet_addr() - * which allows the limited broadcast address - * 255.255.255.255, allows the user - * to specify a port number, and allows also a - * named host to be specified. - * - * Sets the port number to "defaultPort" only if - * "pAddrString" does not contain an addres of the form - * "n.n.n.n:p" - */ -epicsShareFunc int epicsShareAPI - aToIPAddr(const char *pAddrString, unsigned short defaultPort, struct sockaddr_in *pIP) -{ - int status; - long addr[4]; - char hostName[512]; /* !! change n elements here requires change in format below !! */ - int port; - struct in_addr ina; - - /* - * traditional dotted ip addres - */ - status = sscanf (pAddrString, "%li.%li.%li.%li:%i", - addr, addr+1u, addr+2u, addr+3u, &port); - if (status>=4) { - if (addrArrayToUL (addr, NELEMENTS(addr), &ina)<0) { - return -1; - } - if (status==4) { - port = defaultPort; - } - if (port<0 || port>USHRT_MAX) { - return -1; - } - return initIPAddr (ina, (unsigned short) port, pIP); - } - - /* - * IP address as a raw number - */ - status = sscanf (pAddrString, "%li:%i", addr, &port); - if (status>=1) { - if (*addr<0x0 && *addr>0xffffffff) { - return -1; - } - if (status==1) { - port = defaultPort; - } - if (port<0 || port>USHRT_MAX) { - return -1; - } - ina.s_addr = htonl ( ((unsigned long)*addr) ); - return initIPAddr (ina, (unsigned short)port, pIP); - } - - /* - * check for a valid host name before giving up - */ - status = sscanf (pAddrString, "%511s:%i", hostName, &port); - if (status>=1) { - if (status==1) { - port = defaultPort; - } - if (port<0 || port>USHRT_MAX) { - return -1; - } - status = hostToIPAddr (hostName, &ina); - if (status==0) { - return initIPAddr (ina, (unsigned short)port, pIP); - } - } - - /* - * none of the above - return indicating failure - */ - return -1; -} - -/* - * initIPAddr() - * !! ipAddr should be passed in in network byte order !! - * !! port is passed in in host byte order !! - */ -LOCAL int initIPAddr (struct in_addr ipAddr, unsigned short port, struct sockaddr_in *pIP) -{ - memset (pIP, '\0', sizeof(*pIP)); - pIP->sin_family = AF_INET; - pIP->sin_port = htons(port); - pIP->sin_addr = ipAddr; - return 0; -} - -/* - * addrArrayToUL() - */ -LOCAL int addrArrayToUL (const long *pAddr, unsigned nElements, struct in_addr *pIpAddr) -{ - unsigned i; - unsigned long addr = 0ul; - - for (i=0u; i0xff) { - return -1; - } - addr <<= 8; - addr |= (unsigned long) pAddr[i]; - } - pIpAddr->s_addr = htonl (addr); - - return 0; -} diff --git a/src/libCom/misc/adjustment.c b/src/libCom/misc/adjustment.c deleted file mode 100644 index 4fc623d01..000000000 --- a/src/libCom/misc/adjustment.c +++ /dev/null @@ -1,69 +0,0 @@ -/* src/libCom/adjustment.c */ - -/* Author: Peregrine McGehee Date: 21NOV1997 */ -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ - -/* - * - * Modification Log: - * ----------------- - * .01 11-21-97 pmm Initial Implementation - */ - -#ifdef vxWorks -#include -#include -#include "fast_lock.h" -#endif - -#include -#include -#include - -/* Up to now epicsShareThings have been declared as imports - * (Appropriate for other stuff) - * After setting the following they will be declared as exports - * (Appropriate for what we implenment) - */ -#define epicsExportSharedSymbols -#include "adjustment.h" - -epicsShareFunc size_t epicsShareAPI adjustToWorstCaseAlignment(size_t size) -{ - int align_size, adjust; - struct test_long_word { char c; long lw; }; - struct test_double { char c; double d; }; - struct test_ptr { char c; void *p; }; - int test_long_size = sizeof(struct test_long_word) - sizeof(long); - int test_double_size = sizeof(struct test_double) - sizeof(double); - int test_ptr_size = sizeof(struct test_ptr) - sizeof(void *); - size_t adjusted_size = size; - - /* - * Use Jeff's alignment tests to determine worst case of long, - * double or pointer alignment requirements. - */ - align_size = test_long_size > test_ptr_size ? - test_long_size : test_ptr_size; - - align_size = align_size > test_double_size ? - align_size : test_double_size; - - /* - * Increase the size to fit worst case alignment if not already - * properly aligned. - */ - adjust = align_size - size%align_size; - if (adjust != align_size) adjusted_size += adjust; - - return (adjusted_size); -} diff --git a/src/libCom/misc/adjustment.h b/src/libCom/misc/adjustment.h deleted file mode 100644 index ad7c13c14..000000000 --- a/src/libCom/misc/adjustment.h +++ /dev/null @@ -1,19 +0,0 @@ -/* src/libCom/adjustment.h */ - -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ -#ifndef INCadjustmenth -#define INCadjustmenth -#include "shareLib.h" -epicsShareFunc size_t epicsShareAPI adjustToWorstCaseAlignment(size_t size); - -#endif /*INCadjustmenth*/ - diff --git a/src/libCom/misc/createSoftLinks.sh b/src/libCom/misc/createSoftLinks.sh deleted file mode 100644 index 4693bacd6..000000000 --- a/src/libCom/misc/createSoftLinks.sh +++ /dev/null @@ -1,12 +0,0 @@ -#! /bin/sh -# createSoftLinks.sh -# $Id$ - -# Tailored script to create local softlinks releative to this directory -# the name createSoftLinks.sh is a key and must not be changed. If the -# release tool sccsGet finds a file by the name of (createSoftLinks.sh), -# after it has retrieved any out-of-date SCCS files, it invokes the -# script to create the defined softlinks - -/bin/rm -f epicsVersion.h -ln -s ../version/epicsVersion.h epicsVersion.h diff --git a/src/libCom/misc/dbDefs.h b/src/libCom/misc/dbDefs.h deleted file mode 100644 index 6cb8e010d..000000000 --- a/src/libCom/misc/dbDefs.h +++ /dev/null @@ -1,125 +0,0 @@ -/* $Id$ - * - * 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 mm-dd-yy iii Comment - * .02 12-03-91 rcz defines from vxWorks.h for Unix - * .03 12-03-91 rcz added define PVNAME_STRINGSZ - * .04 05-22-92 mrk cleanup - * .05 07-22-93 mrk Cleanup defs for NO and YES - * .06 08-11-93 joh included errMdef.h - */ - -#ifndef INCdbDefsh -#define INCdbDefsh 1 - -#if defined(NULL) -#undef NULL -#endif -#define NULL 0 - -#if defined(NO) -#undef NO -#endif -#define NO 0 - -#if defined(YES) -#undef YES -#endif -#define YES 1 - -#if defined(TRUE) -#undef TRUE -#endif -#define TRUE 1 - -#if defined(FALSE) -#undef FALSE -#endif -#define FALSE 0 - -#ifndef OK -#define OK 0 -#endif -#ifndef ERROR -#define ERROR (-1) -#endif -#ifndef NONE -#define NONE (-1) /* for times when NULL won't do */ -#endif - -#ifndef NELEMENTS -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) -#endif - -#ifndef max -#define max(x, y) (((x) < (y)) ? (y) : (x)) -#endif -#ifndef min -#define min(x, y) (((x) < (y)) ? (x) : (y)) -#endif - -#ifndef OFFSET -#define OFFSET(structure, member) /* byte offset of member in structure*/\ - ((int) &(((structure *) 0) -> member)) -#endif - -/* FLDNAME_SZ must be 4 */ -#define PVNAME_STRINGSZ 29 /* includes NULL terminator for PVNAME_SZ */ -#define PVNAME_SZ (PVNAME_STRINGSZ - 1) /*Process Variable Name Size */ -#define FLDNAME_SZ 4 /*Field Name Size */ - -#define DB_MAX_CHOICES 30 - -#define SUPERVISORY 0 -#define CLOSED_LOOP 1 - -#define NTO1FIRST 0 -#define NTO1LOW 1 -#define NTO1HIGH 2 -#define NTO1AVE 3 - -#ifdef vxWorks -#define vxTicksPerSecond (sysClkRateGet()) /*clock ticks per second*/ -#include -#endif - -#include "errMdef.h" -#include "epicsTypes.h" - -#ifdef __STDC__ -int coreRelease(void); -int iocLogInit(void); -int rsrv_init(void); -#else -int coreRelease(); -int iocLogInit(); -int rsrv_init(); -#endif /*__STDC__*/ - -#endif /* INCdbDefsh */ diff --git a/src/libCom/misc/epicsString.c b/src/libCom/misc/epicsString.c deleted file mode 100644 index 2ed3d8f33..000000000 --- a/src/libCom/misc/epicsString.c +++ /dev/null @@ -1,84 +0,0 @@ -/*epicsString.c*/ -/*Authors: Jun-ichi Odagiri and Marty Kraimer*/ -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ - -#include -#include -#include -#include -#include -#include -int dbTranslateEscape(char *to, const char *from) -{ - const char *pfrom = from; - char *pto = to; - char c; - int nto=0; - - while( (c = *pfrom++ ) ){ - if(c=='\\') { - switch( *pfrom ){ - case 'a': pfrom++; *pto++ = '\a' ; nto++; break; - case 'b': pfrom++; *pto++ = '\b' ; nto++; break; - case 'f': pfrom++; *pto++ = '\f' ; nto++; break; - case 'n': pfrom++; *pto++ = '\n' ; nto++; break; - case 'r': pfrom++; *pto++ = '\r' ; nto++; break; - case 't': pfrom++; *pto++ = '\t' ; nto++; break; - case 'v': pfrom++; *pto++ = '\v' ; nto++; break; - case '\\': pfrom++; *pto++ = '\\' ; nto++; break; - case '\?': pfrom++; *pto++ = '\?' ; nto++; break; - case '\'': pfrom++; *pto++ = '\'' ; nto++; break; - case '\"': pfrom++; *pto++ = '\"' ; nto++; break; - case '0' :case '1' :case '2' :case '3' : - case '4' :case '5' :case '6' :case '7' : - { - int i; - char strval[4] = {0,0,0,0}; - int ival; - unsigned char *pchar; - - for(i=0; i<3; i++) { - if((*pfrom < '0') || (*pfrom > '7')) break; - strval[i] = *pfrom++; - } - sscanf(strval,"%o",&ival); - pchar = (unsigned char *)(pto++); nto++; - *pchar = (unsigned char)(ival); - } - break; - case 'x' : - { - int i; - char strval[3] = {0,0,0}; - int ival; - unsigned char *pchar; - - pfrom++; /*skip the x*/ - for(i=0; i<2; i++) { - if(!isxdigit(*pfrom)) break; - strval[i] = *pfrom++; - } - sscanf(strval,"%x",&ival); - pchar = (unsigned char *)(pto++); nto++; - *pchar = (unsigned char)(ival); - } - break; - default: - *pto++ = *pfrom++; - } - } else { - *pto++ = c; nto++; - } - } - *pto = '\0'; /*NOTE that nto does not have to be incremented*/ - return(nto); -} diff --git a/src/libCom/misc/epicsString.h b/src/libCom/misc/epicsString.h deleted file mode 100644 index 0b6489459..000000000 --- a/src/libCom/misc/epicsString.h +++ /dev/null @@ -1,28 +0,0 @@ -/*epicsString.h*/ -/*Authors: Jun-ichi Odagiri and Marty Kraimer*/ -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ - -/* int dbTranslateEscape(char *s,const char *ct); - * - * copies ct to s while substituting escape sequences - * returns the length of the resultant string (may contain nulls) -*/ - -#ifdef __cplusplus -extern "C" { -#endif -int dbTranslateEscape(char *s,const char *ct); - -#ifdef __cplusplus -} -#endif - diff --git a/src/libCom/misc/epicsTypes.h b/src/libCom/misc/epicsTypes.h deleted file mode 100644 index 345234ae6..000000000 --- a/src/libCom/misc/epicsTypes.h +++ /dev/null @@ -1,255 +0,0 @@ -/* $Id */ - -/* - * Author: Jeff Hill - * Date: 5-95 - * - * 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: - * ----------------- - * $Log$ - * Revision 1.3 1997/04/10 20:00:40 jhill - * VMS changes - * - * Revision 1.2 1996/06/20 16:27:33 jhill - * eliminated sbufs - * - * Revision 1.1 1996/01/25 21:38:48 mrk - * moved files from /base/include - * - * Revision 1.7 1995/12/19 19:46:44 jhill - * added epicsStatus typedef - * - * Revision 1.6 1995/09/29 21:41:41 jhill - * added use of sbufs - * - */ - -#ifndef INCepicsTypesh -#define INCepicsTypesh 1 - -#include - -#ifndef stringOf -# ifdef __STDC__ -# define stringOf(TOKEN) #TOKEN -# else -# define stringOf(TOKEN) "TOKEN" -# endif -#endif - -typedef enum { - epicsFalse=0, - epicsTrue=1 } epicsBoolean; - -/* - * Architecture Independent Data Types - * (so far this is sufficient for all archs we have ported to) - */ -typedef char epicsInt8; -typedef unsigned char epicsUInt8; -typedef short epicsInt16; -typedef unsigned short epicsUInt16; -typedef epicsUInt16 epicsEnum16; -typedef int epicsInt32; -typedef unsigned epicsUInt32; -typedef float epicsFloat32; -typedef double epicsFloat64; -typedef unsigned long epicsIndex; -typedef epicsInt32 epicsStatus; - -typedef struct { - unsigned length; - char *pString; -}epicsString; - -/* - * !! Dont use this - it may vanish in the future !! - * - * Provided only for backwards compatibility with - * db_access.h - * - */ -#define MAX_STRING_SIZE 40 -typedef char epicsOldString[MAX_STRING_SIZE]; - -/* - * union of all types - * - * Strings included here as pointers only so that we support - * large string types. - * - * Arrays included here as pointers because large arrays will - * not fit in this union. - */ -typedef union epics_any{ - epicsInt8 int8; - epicsUInt8 uInt8; - epicsInt16 int16; - epicsUInt16 uInt16; - epicsEnum16 enum16; - epicsInt32 int32; - epicsUInt32 uInt32; - epicsFloat32 float32; - epicsFloat64 float64; - epicsString string; -}epicsAny; - -/* - * Corresponding Type Codes - * (this enum must start at zero) - * - * !! Update epicsTypeToDBR_XXXX[] and DBR_XXXXToEpicsType - * in db_access.h if you edit this enum !! - */ -typedef enum { - epicsInt8T, - epicsUInt8T, - epicsInt16T, - epicsUInt16T, - epicsEnum16T, - epicsInt32T, - epicsUInt32T, - epicsFloat32T, - epicsFloat64T, - epicsStringT, - epicsOldStringT -}epicsType; -#define firstEpicsType epicsInt8T -#define lastEpicsType epicsOldStringT -#define validEpicsType(x) ((x>=firstEpicsType) && (x<=lastEpicsType)) -#define invalidEpicsType(x) ((xlastEpicsType)) - - -/* - * The enumeration "epicsType" is an index to this array - * of type name strings. - */ -#ifdef epicsTypesGLOBAL -epicsShareDef READONLY char *epicsTypeNames [lastEpicsType+1] = { - "epicsInt8", - "epicsUInt8", - "epicsInt16", - "epicsUInt16", - "epicsEnum16", - "epicsInt32", - "epicsUInt32", - "epicsFloat32", - "epicsFloat64", - "epicsString", - "epicsOldString", -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern READONLY char *epicsTypeNames [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -/* - * The enumeration "epicsType" is an index to this array - * of type code name strings. - */ -#ifdef epicsTypesGLOBAL -epicsShareDef READONLY char *epicsTypeCodeNames [lastEpicsType+1] = { - "epicsInt8T", - "epicsUInt8T", - "epicsInt16T", - "epicsUInt16T", - "epicsEnum16T", - "epicsInt32T", - "epicsUInt32T", - "epicsFloat32T", - "epicsFloat64T", - "epicsStringT", - "epicsOldStringT", -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern READONLY char *epicsTypeCodeNames [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -#ifdef epicsTypesGLOBAL -epicsShareDef READONLY unsigned epicsTypeSizes [lastEpicsType+1] = { - sizeof (epicsInt8), - sizeof (epicsUInt8), - sizeof (epicsInt16), - sizeof (epicsUInt16), - sizeof (epicsEnum16), - sizeof (epicsInt32), - sizeof (epicsUInt32), - sizeof (epicsFloat32), - sizeof (epicsFloat64), - sizeof (epicsString), - sizeof (epicsOldString), -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern READONLY unsigned epicsTypeSizes [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -/* - * The enumeration "epicsType" is an index to this array - * of type class identifiers. - */ -typedef enum { - epicsIntC, - epicsUIntC, - epicsEnumC, - epicsFloatC, - epicsStringC, - epicsOldStringC} epicsTypeClass; -#ifdef epicsTypesGLOBAL -epicsShareDef READONLY epicsTypeClass epicsTypeClasses [lastEpicsType+1] = { - epicsIntC, - epicsUIntC, - epicsIntC, - epicsUIntC, - epicsEnumC, - epicsIntC, - epicsUIntC, - epicsFloatC, - epicsFloatC, - epicsStringC, - epicsOldStringC - }; -#else /* epicsTypesGLOBAL */ -epicsShareExtern READONLY epicsTypeClass epicsTypeClasses [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - - -#ifdef epicsTypesGLOBAL -epicsShareDef READONLY char *epicsTypeAnyFieldName [lastEpicsType+1] = { - "int8", - "uInt8", - "int16", - "uInt16", - "enum16", - "int32", - "uInt32", - "float32", - "float64", - "string", - "", /* Old Style Strings will not be in epicsAny type */ - }; -#else /* epicsTypesGLOBAL */ -epicsShareExtern READONLY char *epicsTypeAnyFieldName [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -#endif /* INCepicsTypesh */ - diff --git a/src/libCom/misc/gsd_sync_defs.h b/src/libCom/misc/gsd_sync_defs.h deleted file mode 100644 index 7f66c4233..000000000 --- a/src/libCom/misc/gsd_sync_defs.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef INCgsd_sync_defsh -#define INCgsd_sync_defsh -/* $Id$ - * Author: Gale Slentz - * Date: 09-18-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 09-18-90 ges initial version - * - */ -/*+/mod*********************************************************************** -* TITLE gsd_sync_defs.h - defines for gsd_sync.c -* -* DESCRIPTION -* Contains the definitions that a user of gsd_sync.c -* (for silo of synchronous data) would need to use. -* -*-***************************************************************************/ -#define PREVIOUS_SYNC_DATA 0 -#define NEXTSET_SYNC_DATA 1 -#define USEC_TIME_OUT 100 /* struct timeval's timeout 100usecs */ -#define VOID void - -struct gsd_sync_data { - char *pName; /* ptr to channel name string */ - chid pChid; /* Channel Access id */ - chtype time_type; /* DBR_TIME_xxxx type specifier for data */ - int count; /* element count */ - int svalid; /* valid data flag */ - VOID *pSdata; /* ptr to DBR_TIME_XXXX structure */ -}; - -#endif /* INCgsd_sync_defsh */ diff --git a/src/libCom/misc/makeEpicsVersion.pl b/src/libCom/misc/makeEpicsVersion.pl deleted file mode 100644 index 4502c6482..000000000 --- a/src/libCom/misc/makeEpicsVersion.pl +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl -# - -print "Building epicsVersion.h from CONFIG_BASE_VERSION\n"; - -die unless $#ARGV==0; - -open VARS, $ARGV[0] or die "Cannot get variables from $ARGV[0]"; - -while () -{ - if (/EPICS_VERSION=(.*)/) { $ver = $1; } - if (/EPICS_REVISION=(.*)/) { $rev = $1; } - if (/EPICS_MODIFICATION=(.*)/) { $mod = $1; } - if (/EPICS_UPDATE_NAME=(.*)/) { $upd_name = $1; } - if (/EPICS_UPDATE_LEVEL=(.*)/) { $upd_level = $1; } - if (/CVS_DATE="\\(.*)"/) { $cvs_date = $1; } -} - -$ver_str = "$ver.$rev.$mod.$upd_name.$upd_level"; - -print "Found EPICS Version $ver_str\n"; - -open OUT, ">epicsVersion.h"; - -print OUT "#define BASE_VERSION $ver\n"; -print OUT "#define BASE_REVISION $rev\n"; -print OUT "#define BASE_MODIFICATION $mod\n"; -print OUT "#define BASE_UPDATE_NAME $upd_name\n"; -print OUT "#define BASE_UPDATE_LEVEL $upd_level\n"; -print OUT "#define BASE_VERSION_STRING \"EPICS Version $ver_str\"\n"; -print OUT "#define epicsReleaseVersion \"@(#)Version R$ver_str $cvs_date\"\n"; - -# EPICS_* defs are only for backward compatibility. -# They will be removed at some future date. -print OUT "#define EPICS_VERSION $ver\n"; -print OUT "#define EPICS_REVISION $rev\n"; -print OUT "#define EPICS_MODIFICATION $mod\n"; -print OUT "#define EPICS_UPDATE_NAME $upd_name\n"; -print OUT "#define EPICS_UPDATE_LEVEL $upd_level\n"; -print OUT "#define EPICS_VERSION_STRING \"EPICS Version $ver_str\"\n"; - -close OUT; - - diff --git a/src/libCom/misc/shareLib.h b/src/libCom/misc/shareLib.h deleted file mode 100644 index c74ee5ede..000000000 --- a/src/libCom/misc/shareLib.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Use compiler specific key words to set up shareable library - * external symbols and entry points - * - * Right now this is only necessary for WIN32 DLL, and to a lesser extent VAXC. - * The approach should be general enough for future systems, however. - * - * - * USAGE: - * - * In header files, declare variables, classes and functions - * to be __exported__ like this: - * - * epicsShareFunc int epicsShareAPI - * a_func (int arg); function prototype - * or - * epicsShareFunc int epicsShareAPIV - * a_func (int arg, ...); variable args function prototype - * (using either ... or va_list) - * epicsShareExtern int a_var; reference variable - * (reference declaration) - * epicsShareDef int a_var= 4; create variable instance - * (definition declaration) - * class epicsShareClass a_class; reference a class - * - * Usually the epicsShare... macros expand to - * "import this from a DLL" (on WIN32, on Unix it's a NOOP) - * - * In the implementation file, however, you write: - * - * #include - * #include - * #define epicsExportSharedSymbols - * ! no more includes specifying routines outside this DLLs from here on ! - * #include - * #include - * #include - * - * The point is: define epicsExportSharedSymbols exactly and only - * right before you include the prototypes for what you implement! - * Then include shareLib.h again because this is where they get changed. - * This time the epicsShare... macros expand to - * "export this from the DLL that we are building". (again only on WIN32) - * - * NOTE: - * If what_I_implement_in_this_file.h includes header files for routines that - * are not implemented in the DLL, then you will need to force these - * header files to be included before setting epicsExportSharedSymbols, - * including shareLib.h, and including what_I_implement_in_this_file.h. Since - * all well written header files have "ifdef" guards against multiple inclusion - * this is only a matter of "preincluding" the headers for these DLL - * imports before epicsExportSharedSymbols is defined. This - * is admittedly a bit of a mess, but is fortunately only the concern of - * persons who are adding routines to a library, and will have no impact - * on persons using routines out of a library. - * - * 8-22-96 -kuk- - */ - -#undef epicsShareExtern -#undef epicsShareDef -#undef epicsShareClass -#undef epicsShareFunc -#undef epicsShareAPI -#undef epicsShareAPIV -#undef READONLY - -/* - * if its WIN32 and it isnt the Cygnus GNU environment - * (I am assuming Borlund and other MS Vis C++ competitors - * support these MS VisC++ defacto standard keywords???? If not - * then we should just switch on defined(_MSC_VER) here) - * - * Also check for "EPICS_DLL_NO" not defined so that we will not use these - * keywords if it is an object library build of base under WIN32. - */ -#if defined(_WIN32) && !defined(__CYGWIN32__) - -# if defined(epicsExportSharedSymbols) -# if defined(EPICS_DLL_NO) /* this indicates that we are not building a DLL */ -# define epicsShareExtern extern -# define epicsShareClass -# define epicsShareFunc -# else -# define epicsShareExtern extern __declspec(dllexport) -# define epicsShareClass __declspec(dllexport) -# define epicsShareFunc __declspec(dllexport) -# endif -# else -# if defined(_DLL) /* this indicates that we are being compiled to call a DLL */ -# define epicsShareExtern extern __declspec(dllimport) -# define epicsShareClass __declspec(dllimport) -# define epicsShareFunc __declspec(dllimport) -# else -# define epicsShareExtern extern -# define epicsShareClass -# define epicsShareFunc -# endif -# endif - /* - * Subroutine removes arguments - * (Bill does not allow __stdcall to be next to - * __declspec(xxxx)) - */ -# define epicsShareAPI __stdcall - /* - * Variable args functions cannot be __stdcall - * Use this for variable args functions - * (Those using either ... or va_list arguments) - */ -# define epicsShareAPIV __cdecl -# if defined(EPICS_DLL_NO) /* this indicates that we are not building a DLL */ -# define epicsShareDef -# else -# define epicsShareDef __declspec(dllexport) -# endif -# define READONLY const -/* - * if its the old VAX C Compiler (not DEC C) - */ -#elif defined(VAXC) - - /* - * VAXC creates FORTRAN common blocks when - * we use "extern int fred"/"int fred=4". Therefore, - * the initialization is not loaded unless we - * call a function in that object module. - * - * DEC CXX does not have this problem. - * We suspect (but do not know) that DEC C - * also does not have this problem. - */ -# define epicsShareExtern globalref -# define epicsShareDef globaldef -# define READONLY const -# define epicsShareClass -# define epicsShareFunc -# define epicsShareAPI -# define epicsShareAPIV - -#else - -/* else => no import/export specifiers */ - -# define epicsShareExtern extern -# define epicsShareAPI -# define epicsShareAPIV -# define epicsShareClass -# define epicsShareDef - -# define epicsShareFunc -# if defined(__STDC__) -# define READONLY const -# else -# define READONLY -# endif - -#endif - diff --git a/src/libCom/misc/truncateFile.c b/src/libCom/misc/truncateFile.c deleted file mode 100644 index 3aef99694..000000000 --- a/src/libCom/misc/truncateFile.c +++ /dev/null @@ -1,128 +0,0 @@ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "truncateFile.h" - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -/* - * truncate to specified size (we dont use truncate() - * because it is not portable) - */ -epicsShareFunc enum TF_RETURN epicsShareAPI truncateFile (const char *pFileName, unsigned size) -{ - char tmpName[L_tmpnam]; - long filePos; - char *pTmpFN; - FILE *pFile; - FILE *ptmp; - int status; - int c; - unsigned charNo; - - /* - * see cast of size to long below - */ - if (size>LONG_MAX) { - return TF_ERROR; - } - - pFile = fopen(pFileName, "r"); - if (!pFile) { - fprintf (stderr, - "File access problems to `%s' because `%s'\n", - pFileName, - strerror(errno)); - return TF_ERROR; - } - - /* - * This is not required under UNIX but does appear - * to be required under WIN32. - */ - status = fseek (pFile, 0L, SEEK_END); - if (status!=TF_OK) { - fclose (pFile); - return TF_ERROR; - } - - filePos = ftell(pFile); - if (filePos <= (long) size) { - fclose (pFile); - return TF_OK; - } - - pTmpFN = tmpnam (tmpName); - if (!pTmpFN) { - fprintf (stderr,"Unable to create tmp file name?\n"); - fclose (pFile); - return TF_ERROR; - } - - ptmp = fopen (pTmpFN, "w"); - if (!ptmp) { - fprintf (stderr, - "File access problems to `%s' because `%s'\n", - pTmpFN, - strerror(errno)); - fclose (pFile); - return TF_ERROR; - } - rewind (pFile); - charNo = 0u; - while (charNo -#include -#include -#include - -/* - * OS dependent includes - */ -#ifdef vxWorks -#include -#include -#include -#include -#endif - -#ifndef LOCAL -#define LOCAL static -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/* - * mprintf header file - */ -#include - -#ifdef vxWorks - typedef struct { - FILE **pppFileList[3]; - SEM_ID sem; - }osDepen; -#else - typedef struct { - FILE **pppFileList[2]; - }osDepen; -#endif - - -typedef struct mprintfContext { - int (*pPrintfISR) (char *pFormat, va_list pvar); - void (*pInit) (struct mprintfContext *pCtx); - void (*pPrintThreadName) (struct mprintfContext *pCtx, FILE *pfile); - void (*pMutexLock) (struct mprintfContext *pCtx); - void (*pMutexUnlock) (struct mprintfContext *pCtx); - FILE ***pppFileList; - osDepen os; - int initComplete; -}mpc; - -LOCAL int vmprintfISR (char *pFormat, va_list pvar); -LOCAL void mprintfInit (mpc *pCtx); -LOCAL void printThreadName (mpc *pCtx, FILE *pfile); -LOCAL void mprintfMutexLock (mpc *pCtx); -LOCAL void mprintfMutexUnlock (mpc *pCtx); - -#ifdef vxWorks - LOCAL FILE *stdoutRef; - extern FILE *iocLogFile; - LOCAL mpc ctx = { - vmprintfISR, - mprintfInit, - printThreadName, - mprintfMutexLock, - mprintfMutexUnlock, - ctx.os.pppFileList, - {&stdoutRef, &iocLogFile, NULL} - }; -#else - LOCAL FILE *stdoutRef; - LOCAL mpc ctx = { - vmprintfISR, - mprintfInit, - printThreadName, - mprintfMutexLock, - mprintfMutexUnlock, - ctx.os.pppFileList, - {&stdoutRef, NULL} - }; -#endif - -LOCAL mpc *pCtx = &ctx; - - -/* - * mprintf () - */ -int mprintf (char *pFormat, ...) -{ - va_list pvar; - - va_start (pvar, pFormat); - - return vmprintf (pFormat, pvar); -} - - -/* - * vmprintf () - */ -int vmprintf (char *pFormat, va_list pvar) -{ - int status; - FILE ***pppFile; - - status = (*pCtx->pPrintfISR) (pFormat, pvar); - if (status) { - return 0; - } - - if (!pCtx->initComplete) { - (*pCtx->pInit) (pCtx); - assert (pCtx->initComplete); - } - - (*pCtx->pMutexLock) (pCtx); - for (pppFile = pCtx->pppFileList; *pppFile; pppFile++){ - FILE *pFile; - - pFile = **pppFile; - - if (pFile) { - (*pCtx->pPrintThreadName) (pCtx, pFile); - vfprintf ( - pFile, - pFormat, - pvar); - fflush (pFile); - } - } - (*pCtx->pMutexUnlock) (pCtx); - - return 0; -} - - - -/* - * mprintfInit () - */ -#ifdef vxWorks -LOCAL void mprintfInit (mpc *pCtx) -{ - pCtx->os.sem = semMCreate ( - SEM_Q_PRIORITY | - SEM_DELETE_SAFE | - SEM_INVERSION_SAFE); - if (pCtx->os.sem == NULL) { - return; - } - - stdoutRef = stdout; - - pCtx->initComplete = TRUE; -} -#else -LOCAL void mprintfInit (mpc *pCtx) -{ - stdoutRef = stdout; - - pCtx->initComplete = TRUE; -} -#endif - - -/* - * mprintfMutexLock () - */ -#ifdef vxWorks -LOCAL void mprintfMutexLock (mpc *pCtx) -{ - int status; - - status = semTake (pCtx->os.sem, WAIT_FOREVER); - assert (status == OK); -} -#else -LOCAL void mprintfMutexLock (mpc *pCtx) -{ - return; -} -#endif - - -/* - * mprintfMutexUnlock () - */ -#ifdef vxWorks -LOCAL void mprintfMutexUnlock (mpc *pCtx) -{ - int status; - - status = semGive (pCtx->os.sem); - assert (status == OK); -} -#else -LOCAL void mprintfMutexUnlock (mpc *pCtx) -{ - return; -} -#endif - -#if defined(vxWorks) -LOCAL int vmprintfISR (char *pFormat, va_list pvar) -{ - unsigned i; - int status; - int logMsgArgs[6]; - - if (!INT_CONTEXT()) { - return FALSE; - } - - va_start (pvar, pFormat); - for (i=0; i - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -/*#include -#include */ -#include -#include -#include -#include -#include -#include /* close() and others */ - - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_close(S) close(S) -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#define FD_IN_FDSET(FD) ((FD) -#if defined(MULTINET) && defined(__cplusplus) - struct iovec; -#endif - -#include -#include -#include -#if defined(UCX) /* GeG 09-DEC-1992 */ -# include -# include -# include -# include -#elif defined(MULTINET) -# if defined(__DECCXX) -# define __DECC 1 -# define __DECC_VER 999999999 -# include -# include -# undef __DECC -# undef __DECC_VER -# else -# include -# include -# endif -# if defined(__cplusplus) - struct ifaddr; - struct mbuf; -# endif -# include -# include -# include -# include -# include -#endif - -/* - * MULTINET defines none of these (if not using C++) - */ -#if defined(MULTINET) && defined(MULTINET_NO_PROTOTYPES) -int gettimeofday (struct timeval *tp, struct timezone *tzp); -int gethostname (char *name, int namelen); -int accept (int socket, struct sockaddr *addr, int *addrlen); -int getpeername (int socket, struct sockaddr *name, int *namelen); -int connect (int socket, struct sockaddr *name, int namelen); -int setsockopt (int socket, int level, int optname, - char *optval, int optlen); -int sendto (int socket, const char *buf, int len, - int flags, struct sockaddr *to, int tolen); -int select (int width, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout); - -int bind (int socket, struct sockaddr *name, int namelen); -int send (int socket, const char *buf, int len, int flags); -int recv (int socket, char *buf, int len, int flags); -int getsockopt (int socket, int level, int optname, - char *optval, int *optlen); -int recvfrom (int socket, char *buf, int len, - int flags, struct sockaddr *from, int *fromlen); -int getsockname (int socket, struct sockaddr *name, int *namelen); -int listen (int socket, int backlog); -int shutdown (int socket, int how); -int socket (int domain, int type, int protocol); - -#endif /* defined(MULTINET) && defined(MULTINET_NO_PROTOTYPES) */ - -void bzero (char *b, int length); -#ifdef MULTINET -# include - int gettimeofday (struct timeval *tp, ...); -#else - char * inet_ntoa (struct in_addr in); - unsigned long inet_addr (const char *); -#endif - -#if 0 -struct hostent { - char *h_name; /* official name of host */ - char **h_aliases; /* alias list */ - int h_addrtype; /* host address type */ - int h_length; /* length of address */ - char **h_addr_list; /* list of addresses from name server */ -#define h_addr h_addr_list[0] /* address, for backward compatiblity */ -}; -struct hostent *gethostbyaddr(char *addr, int len, int type); -#endif - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -/* - * (the VAXC runtime lib has its own close - */ -#if defined(WINTCP) /* Wallangong */ -# define socket_close(S) netclose(S) -# define socket_ioctl(A,B,C) ioctl(A,B,C) -#endif -#if defined(UCX) /* GeG 09-DEC-1992 */ -# define socket_close(S) close(S) -# define socket_ioctl(A,B,C) ioctl(A,B,C) -#endif -typedef int osiSockIoctl_t; - -#if defined(WINTCP) /* Wallangong */ - extern int uerrno; -# define SOCKERRNO uerrno -#elif defined(MULTINET) -# define SOCKERRNO socket_errno -#else -# define SOCKERRNO errno /* UCX and others? */ -#endif - -/* - * !! this is no doubt incorrect !! - * (error messages will be confusing until - * this is fixed) - */ -#define SOCKERRSTR (strerror(SOCKERRNO)) - -#define MAXHOSTNAMELEN 75 - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE - -/* - * Under MULTINET FD_SETSIZE does not apply - * (can only guess about the others) - */ -#ifdef MULTINET -# define FD_IN_FDSET(FD) (1) -#else -# define FD_IN_FDSET(FD) ((FD)=0) -#endif - -#endif /*osiSockH*/ - diff --git a/src/libCom/osi/os/VMS/ucx.h b/src/libCom/osi/os/VMS/ucx.h deleted file mode 100644 index f28ab6ac9..000000000 --- a/src/libCom/osi/os/VMS/ucx.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * U C X . H - * UNIX ioctl structures and defines used for VAX/UCX - * Author: Gerhard Grygiel (GeG) - * - * GeG 09-DEC-1992 initial edit - * CJM 13-Jul-1994 add fd_set etc for R3.12 - * CJM 09-Dec-1994 define fd_set etc. so it will compile for - * both DEC C and Vax C - * CJM 19-Nov-1995 use memset instead of bzero following advice - * from Jeff Hill and add a definition of struct - * timezone to support gettimeofday - * - */ -#ifndef _UCX_H_ -#define _UCX_H_ -#ifdef UCX - -#define IFF_UP 0x1 /* interface is up */ -#define IFF_BROADCAST 0x2 /* broadcast address valid */ -#define IFF_LOOPBACK 0x8 /* is a loopback net */ -#define IFF_POINTOPOINT 0x10 /* interface is point to point */ -/* - * Interface request structure used for socket - * ioctl's. All interface ioctl's must have parameter - * definitions which begin with ifr_name. The - * remainder may be interface specific. - */ -struct ifreq { -#define IFNAMSIZ 16 - char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - union { - struct sockaddr ifru_addr; - struct sockaddr ifru_dstaddr; - struct sockaddr ifru_broadaddr; - short ifru_flags; - int ifru_metric; - caddr_t ifru_data; - } ifr_ifru; -#define ifr_addr ifr_ifru.ifru_addr /* address */ -#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ -#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ -#define ifr_flags ifr_ifru.ifru_flags /* flags */ -#define ifr_metric ifr_ifru.ifru_metric /* metric */ -#define ifr_data ifr_ifru.ifru_data /* for use by interface */ -}; - -/* Structure used in SIOCGIFCONF request. - * Used to retrieve interface configuration - * for machine (useful for programs which - * must know all networks accessible). - */ -struct ifconf { - int ifc_len; /* size of associated buffer */ - union { - caddr_t ifcu_buf; - struct ifreq *ifcu_req; - } ifc_ifcu; -#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ -#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ -}; - -#ifndef NBBY -#define NBBY 8 -#endif - -#ifndef FD_SETSIZE -#define FD_SETSIZE 256 -#endif - -typedef long fd_mask ; -#define NFDBITS (sizeof (fd_mask) * NBBY ) /* bits per mask */ -#ifndef howmany -#define howmany(x, y) (((x)+((y)-1))/(y)) -#endif - -/* - * Both DEC C and VAX C only allow 32 fd's at once - */ -typedef int fd_set ; - -#define FD_SET(n, p) (*(p) |= (1 << ((n) % NFDBITS))) -#define FD_CLR(n, p) (*(p) &= ~(1 << ((n) % NFDBITS))) -#define FD_ISSET(n, p) (*(p) & (1 << ((n) % NFDBITS))) -#define FD_ZERO(p) memset((char *)(p), 0, sizeof (*(p))) - -#include -#define IO$_RECEIVE (IO$_WRITEVBLK) - -struct timezone { - int tz_minuteswest ; /* minutes west of Greenwich */ - int tz_dsttime ; /* type of dst correction */ -}; - -#define TWOPOWER32 4294967296.0 -#define TWOPOWER31 2147483648.0 -#define UNIX_EPOCH_AS_MJD 40587.0 -#endif -#endif - diff --git a/src/libCom/osi/os/WIN32/dllmain.cpp b/src/libCom/osi/os/WIN32/dllmain.cpp deleted file mode 100644 index 510fe22cb..000000000 --- a/src/libCom/osi/os/WIN32/dllmain.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * dllmain.c - * - * WIN32 specific initialisation for the Com library, - * based on Chris Timossi's base/src/ca/windows_depend.c, - * especially initializing: - * ositime - * - * 8-2-96 -kuk- - * - * 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 - * - * Lawrence Berkley National Laboratory - * - * Modification Log: - * ----------------- - */ - -#include -#include - -#include "epicsVersion.h" -#define epicsExportSharedSymbols -#include "bsdSocketResource.h" - -#ifndef _WIN32 -#error This source is specific to WIN32 -#endif - -extern int init_osi_time (); -extern int exit_osi_time (); - -#if !defined(EPICS_DLL_NO) -BOOL WINAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) -{ - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - if (!bsdSockAttach()) - return FALSE; - if (init_osi_time ()) - return FALSE; -# ifdef _DEBUG - fprintf(stderr, "Process attached to Com.dll version %s\n", EPICS_VERSION_STRING); -# endif - break; - - case DLL_PROCESS_DETACH: - bsdSockRelease(); - exit_osi_time (); -# ifdef _DEBUG - fprintf(stderr, "Process detached from Com.dll version %s\n", EPICS_VERSION_STRING); -# endif - break; - } - - return TRUE; -} -#endif - diff --git a/src/libCom/osi/os/WIN32/getopt.c b/src/libCom/osi/os/WIN32/getopt.c deleted file mode 100644 index 8feee574f..000000000 --- a/src/libCom/osi/os/WIN32/getopt.c +++ /dev/null @@ -1,736 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* NOTE!!! AIX requires this to be the first thing in the file. - Do not put ANYTHING before it! */ -#if !defined (__GNUC__) && defined (_AIX) - #pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef _MSC_VER -#include -#else -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not __GNUC__ */ -#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__)))) -#include -#else -#ifndef _AIX -char *alloca (); -#endif -#endif /* alloca.h */ -#endif -#endif /* not __GNUC__ */ - -#if !__STDC__ && !defined(const) && IN_GCC -#define const -#endif - -/* This tells Alpha OSF/1 not to define a getopt prototype in . */ -#ifndef _NO_PROTO -#define _NO_PROTO -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#undef alloca -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -#include -#else /* Not GNU C library. */ -#define __alloca alloca -#endif /* GNU C library. */ - -/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a - long-named option. Because this is not POSIX.2 compliant, it is - being phased out. */ -/* #define GETOPT_COMPAT */ - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#define epicsExportSharedSymbols -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -epicsShareDef char *optarg = 0; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* XXX 1003.2 says this must be 1 before any call. */ -epicsShareDef int optind = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -epicsShareDef int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -epicsShareDef int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return EOF with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -#include -#define my_index strchr -#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) -#else - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -char *getenv (); - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -static void -my_bcopy (from, to, size) - const char *from; - char *to; - int size; -{ - int i; - for (i = 0; i < size; i++) - to[i] = from[i]; -} -#endif /* GNU C library. */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange (argv) - char **argv; -{ - int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); - char **temp = (char **) __alloca (nonopts_size); - - /* Interchange the two blocks of data in ARGV. */ - - my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size); - my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt], - (optind - last_nonopt) * sizeof (char *)); - my_bcopy ((char *) temp, - (char *) &argv[first_nonopt + optind - last_nonopt], - nonopts_size); - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns `EOF'. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - int option_index; - - optarg = 0; - - /* Initialize the internal data when the first call is made. - Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - if (optind == 0) - { - first_nonopt = last_nonopt = optind = 1; - - nextchar = NULL; - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (getenv ("POSIXLY_CORRECT") != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - } - - if (nextchar == NULL || *nextchar == '\0') - { - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Now skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc - && (argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - optind++; - last_nonopt = optind; - } - - /* Special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if ((argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - { - if (ordering == REQUIRE_ORDER) - return EOF; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Start decoding its characters. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - if (longopts != NULL - && ((argv[optind][0] == '-' - && (argv[optind][1] == '-' || long_only)) -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - )) - { - const struct option *p; - char *s = nextchar; - int exact = 0; - int ambig = 0; - const struct option *pfound = NULL; - int indfound; - - while (*s && *s != '=') - s++; - - /* Test all options for either exact match or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; - p++, option_index++) - if (!strncmp (p->name, nextchar, s - nextchar)) - { - if (s - nextchar == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*s) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = s + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - return '?'; - } - } - - /* Look at and handle the next option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { -#if 0 - if (c < 040 || c >= 0177) - fprintf (stderr, "%s: unrecognized option, character code 0%o\n", - argv[0], c); - else - fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); -#else - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); -#endif - } - optopt = c; - return '?'; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = 0; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { -#if 0 - fprintf (stderr, "%s: option `-%c' requires an argument\n", - argv[0], c); -#else - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - argv[0], c); -#endif - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int epicsShareAPI -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/src/libCom/osi/os/WIN32/getopt.h b/src/libCom/osi/os/WIN32/getopt.h deleted file mode 100644 index 04c076a91..000000000 --- a/src/libCom/osi/os/WIN32/getopt.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -epicsShareExtern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -epicsShareExtern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -epicsShareExtern int opterr; - -/* Set to an option character which was unrecognized. */ - -epicsShareExtern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if __STDC__ -#if defined(__GNU_LIBRARY__) -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -epicsShareFunc extern int epicsShareAPI - getopt (int argc, char *const *argv, const char *shortopts); -#else /* not __GNU_LIBRARY__ */ -epicsShareFunc extern int epicsShareAPI getopt (); -#endif /* not __GNU_LIBRARY__ */ -epicsShareFunc extern int epicsShareAPI - getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -epicsShareFunc extern int - epicsShareAPI getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -epicsShareFunc extern int epicsShareAPI getopt (); -epicsShareFunc extern int epicsShareAPI getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* not __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/src/libCom/osi/os/WIN32/osdSock.h b/src/libCom/osi/os/WIN32/osdSock.h deleted file mode 100644 index f301e6b73..000000000 --- a/src/libCom/osi/os/WIN32/osdSock.h +++ /dev/null @@ -1,46 +0,0 @@ - - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#ifdef __cplusplus -} -#endif - -#define SOCKERRNO WSAGetLastError() -#define SOCKERRSTR getLastWSAErrorAsString() - -#define socket_close(S) closesocket(S) -#define socket_ioctl(A,B,C) ioctlsocket(A,B,C) -typedef u_long FAR osiSockIoctl_t; - -#define MAXHOSTNAMELEN 75 -#define IPPORT_USERRESERVED 5000U - -#define SOCK_EWOULDBLOCK WSAEWOULDBLOCK -#define SOCK_ENOBUFS WSAENOBUFS -#define SOCK_ECONNRESET WSAECONNRESET -#define SOCK_ETIMEDOUT WSAETIMEDOUT -#define SOCK_EADDRINUSE WSAEADDRINUSE -#define SOCK_ECONNREFUSED WSAECONNREFUSED -#define SOCK_ECONNABORTED WSAECONNABORTED -#define SOCK_EINPROGRESS WSAEINPROGRESS -#define SOCK_EISCONN WSAEISCONN -#define SOCK_EALREADY WSAEALREADY -#define SOCK_EINVAL WSAEINVAL -#define SOCK_EINTR WSAEINTR -#define SOCK_EPIPE EPIPE - -/* - * Under WIN32, FD_SETSIZE is the max. number of sockets, - * not the max. fd value that you use in select(). - * - * Therefore, it is difficult to detemine if any given - * fd can be used with FD_SET(), FD_CLR(), and FD_ISSET(). - */ -#define FD_IN_FDSET(FD) (1) diff --git a/src/libCom/osi/os/WIN32/osdTime.cpp b/src/libCom/osi/os/WIN32/osdTime.cpp deleted file mode 100644 index dd2586c61..000000000 --- a/src/libCom/osi/os/WIN32/osdTime.cpp +++ /dev/null @@ -1,108 +0,0 @@ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include - -static long offset_time_s = 0; /* time diff (sec) from 1990 when EPICS started */ -static LARGE_INTEGER time_prev, time_freq; - -/* - * init_osi_time has to be called before using the timer, - * exit_osi_time has to be called in balance. - */ -int init_osi_time () -{ - if (offset_time_s == 0) { - /* - * initialize elapsed time counters - * - * All CPUs running win32 currently have HR - * counters (Intel and Mips processors do) - */ - if (QueryPerformanceCounter (&time_prev)==0) { - return 1; - } - if (QueryPerformanceFrequency (&time_freq)==0) { - return 1; - } - offset_time_s = (long)time(NULL) - - (long)(time_prev.QuadPart/time_freq.QuadPart); - } - - return 0; -} - -int exit_osi_time () -{ - offset_time_s = 0; - - return 0; -} - - -// -// osiTime::getCurrent () -// -osiTime osiTime::getCurrent () -{ - LARGE_INTEGER time_cur, time_sec, time_remainder; - unsigned long sec, nsec; - - /* - * this allows the code to work when it is in an object - * library (in addition to inside a dll) - */ - if (offset_time_s==0) { - init_osi_time(); - } - - /* - * dont need to check status since it was checked once - * during initialization to see if the CPU has HR - * counters (Intel and Mips processors do) - */ - QueryPerformanceCounter (&time_cur); - if (time_prev.QuadPart > time_cur.QuadPart) { /* must have been a timer roll-over */ - double offset; - /* - * must have been a timer roll-over - * It takes 9.223372036855e+18/time_freq sec - * to roll over this counter (time_freq is 1193182 - * sec on my system). This is currently about 245118 years. - * - * attempt to add number of seconds in a 64 bit integer - * in case the timer resolution improves - */ - offset = pow(2.0, 63.0)-1.0/time_freq.QuadPart; - if (offset<=LONG_MAX-offset_time_s) { - offset_time_s += (long) offset; - } - else { - /* - * this problem cant be fixed, but hopefully will never occurr - */ - fprintf (stderr, "%s.%d Timer overflowed\n", __FILE__, __LINE__); - return osiTime (0, 0); - } - } - time_sec.QuadPart = time_cur.QuadPart / time_freq.QuadPart; - time_remainder.QuadPart = time_cur.QuadPart % time_freq.QuadPart; - if (time_sec.QuadPart > LONG_MAX-offset_time_s) { - /* - * this problem cant be fixed, but hopefully will never occurr - */ - fprintf (stderr, "%s.%d Timer value larger than storage\n", __FILE__, __LINE__); - return osiTime (0, 0); - } - - /* add time (sec) since 1970 */ - sec = offset_time_s + (long)time_sec.QuadPart; - nsec = (long)((time_remainder.QuadPart*1000000000)/time_freq.QuadPart); - - time_prev = time_cur; - - return osiTime (sec, nsec); -} diff --git a/src/libCom/osi/os/WIN32/osiFileName.h b/src/libCom/osi/os/WIN32/osiFileName.h deleted file mode 100644 index 404983167..000000000 --- a/src/libCom/osi/os/WIN32/osiFileName.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#define OSI_PATH_LIST_SEPARATOR ";" -#define OSI_PATH_SEPARATOR "\\" - -#endif /* osiFileNameH */ \ No newline at end of file diff --git a/src/libCom/osi/os/alpha/osdSock.h b/src/libCom/osi/os/alpha/osdSock.h deleted file mode 100644 index db836d04f..000000000 --- a/src/libCom/osi/os/alpha/osdSock.h +++ /dev/null @@ -1,65 +0,0 @@ - -/* - * alpha specific socket include - */ - -#ifndef osiSockH -#define osiSockH - -#ifdef __cplusplus -extern "C" { -struct ifafilt; -#endif - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -/* #include */ -/* #include */ -#include -#include -#include -#include -#include -#include /* close() and others */ - -/* - * as far as I can tell there is no header file for these - */ -int gethostname(char *name, int namelen); -int sethostname(char *name, int namelen); - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define SOCKERRSTR (strerror(errno)) -#define socket_close(S) close(S) -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE - -#endif /*osiSockH*/ - diff --git a/src/libCom/osi/os/alpha/osiFileName.h b/src/libCom/osi/os/alpha/osiFileName.h deleted file mode 100644 index 55bb589a2..000000000 --- a/src/libCom/osi/os/alpha/osiFileName.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ \ No newline at end of file diff --git a/src/libCom/osi/os/cygwin32/osdSock.h b/src/libCom/osi/os/cygwin32/osdSock.h deleted file mode 100644 index 9bb3c8c0c..000000000 --- a/src/libCom/osi/os/cygwin32/osdSock.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * cygwin32 specific include - */ - - -#ifndef osiSockH -#define osiSockH - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -/* - * as far as I can tell there is no header file for these - */ -int gethostname(char *name, int namelen); -int sethostname(char *name, int namelen); - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define SOCKERRSTR (strerror(errno)) -#define socket_close(S) close(S) -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define IOC_OUT 0x40000000 /* copy out parameters */ -#define IOC_IN 0x80000000 /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) - -#define _IOWR(x, y, t) \ - (IOC_INOUT|((((int)sizeof (t))&IOCPARM_MASK)<<16)|(x<<8)|y) - -/* Used by ca/if_depends.c */ -#define SIOCGIFDSTADDR _IOWR('i', 15, struct ifreq) /* get p-p address */ -#define SIOCGIFADDR _IOWR('i', 13, struct ifreq) /* get ifnet address */ - -/* Used by ca/if_depends.c db/drvTS.c dbtools/BSlib.c */ -#define SIOCGIFBRDADDR _IOWR('i', 23, struct ifreq) /* get broadcast addr */ - - -/* Used by ca/if_depends.c ca/ucx.h */ -#define IFF_POINTOPOINT 0x10 - -/* Used by ca/iocinf.c */ -#define SO_SNDBUF 0x1001 /* send buffer size */ -#define SO_RCVBUF 0x1002 /* receive buffer size */ - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE - -#endif /*osiSockH*/ - diff --git a/src/libCom/osi/os/cygwin32/osiFileName.h b/src/libCom/osi/os/cygwin32/osiFileName.h deleted file mode 100644 index 0268e0f40..000000000 --- a/src/libCom/osi/os/cygwin32/osiFileName.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#define OSI_PATH_LIST_SEPARATOR ";" -#define OSI_PATH_SEPARATOR "\\" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/hpux/osdSock.h b/src/libCom/osi/os/hpux/osdSock.h deleted file mode 100644 index 791d002fa..000000000 --- a/src/libCom/osi/os/hpux/osdSock.h +++ /dev/null @@ -1,67 +0,0 @@ - -/* - * Solaris specifif socket include - */ - -#ifndef osiSockH -#define osiSockH - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -/* -#include -#include -*/ -#include -#include -#include -#include -#include -#include /* close() and others */ - -/* - * as far as I can tell there is no header file for these - */ -/* -int gethostname(char *name, int namelen); -int sethostname(char *name, int namelen); -*/ -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define SOCKERRSTR (strerror(errno)) -#define socket_close(S) close(S) -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE - -#endif /*osiSockH*/ - diff --git a/src/libCom/osi/os/hpux/osiFileName.h b/src/libCom/osi/os/hpux/osiFileName.h deleted file mode 100644 index 55bb589a2..000000000 --- a/src/libCom/osi/os/hpux/osiFileName.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ \ No newline at end of file diff --git a/src/libCom/osi/os/sgi/osdSock.h b/src/libCom/osi/os/sgi/osdSock.h deleted file mode 100644 index 73e9631fd..000000000 --- a/src/libCom/osi/os/sgi/osdSock.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* - * SGI specific socket include - */ - -#ifndef osiSockH -#define osiSockH - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -/* #include */ -/* #include */ -#include -#include -#include -#include -#include -#include /* close() and others */ - -/* - * as far as I can tell there is no header file for these - */ -/* int gethostname(char *name, int namelen); */ -/* int sethostname(char *name, int namelen); */ - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define SOCKERRSTR (strerror(errno)) -#define socket_close(S) close(S) -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE - -#endif /*osiSockH*/ - diff --git a/src/libCom/osi/os/sgi/osiFileName.h b/src/libCom/osi/os/sgi/osiFileName.h deleted file mode 100644 index 55bb589a2..000000000 --- a/src/libCom/osi/os/sgi/osiFileName.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ \ No newline at end of file diff --git a/src/libCom/osi/os/solaris/osdSock.h b/src/libCom/osi/os/solaris/osdSock.h deleted file mode 100644 index 55f1a7c5e..000000000 --- a/src/libCom/osi/os/solaris/osdSock.h +++ /dev/null @@ -1,75 +0,0 @@ - -/* - * Solaris specific socket include - * - * Under solaris if we dont define _POSIX_C_SOURCE or _XOPEN_SOURCE - * then none of the POSIX stuff (such as signals) can be used - * with cc -v. However if one of _POSIX_C_SOURCE or _XOPEN_SOURCE - * are defined then we cant use the socket library. Therefore I - * have been adding the following in order to use POSIX signals - * and also sockets on solaris with cc -v. What a pain.... - * - * #ifdef SOLARIS - * #define __EXTENSIONS__ - * #endif - */ - -#ifndef osiSockH -#define osiSockH - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - -/* - * as far as I can tell there is no header file for these - */ -int gethostname(char *name, int namelen); -int sethostname(char *name, int namelen); - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define SOCKERRSTR (strerror(errno)) -#define socket_close(S) close(S) -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE - -#endif /*osiSockH*/ - diff --git a/src/libCom/osi/os/solaris/osiFileName.h b/src/libCom/osi/os/solaris/osiFileName.h deleted file mode 100644 index 60e0a20da..000000000 --- a/src/libCom/osi/os/solaris/osiFileName.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/sun4/osdSock.h b/src/libCom/osi/os/sun4/osdSock.h deleted file mode 100644 index 317e690a3..000000000 --- a/src/libCom/osi/os/sun4/osdSock.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * sunos 4 specific socket include - */ - -#ifndef osiSockH -#define osiSockH - -/* - * done in two ifdef steps so that we will remain compatible with - * traditional C - */ - -#ifdef __cplusplus -extern "C" { -#define OSISOCK_ANSI_FUNC_PROTO -#endif - -#ifdef __STDC__ -#define OSISOCK_ANSI_FUNC_PROTO -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef OSISOCK_ANSI_FUNC_PROTO -int ioctl (int fd, int req, ...); -int close (int fd); -int gettimeofday (struct timeval *tp, struct timezone *tzp); -int gethostname (char *name, int namelen); -#endif - -/* - * sun's CC defines at least a few of these under sunos4 - * ( but acc does not !? ) - */ -#if defined(__SUNPRO_CC) -# include -# include -#else -# ifdef OSISOCK_ANSI_FUNC_PROTO - int listen (int socket, int backlog); - int accept (int socket, struct sockaddr *addr, int *addrlen); - int shutdown (int socket, int how); - int getpeername (int socket, struct sockaddr *name, int *namelen); - int connect (int socket, struct sockaddr *name, int namelen); - int setsockopt (int socket, int level, int optname, - char *optval, int optlen); - void bzero (char *b, int length); - int sendto (int socket, const char *buf, int len, - int flags, struct sockaddr *to, int tolen); - int select (int width, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout); - - int bind (int socket, struct sockaddr *name, int namelen); - int send (int socket, const char *buf, int len, int flags); - int recv (int socket, char *buf, int len, int flags); - int getsockopt (int socket, int level, int optname, - char *optval, int *optlen); - int socket (int domain, int type, int protocol); - int recvfrom (int socket, char *buf, int len, - int flags, struct sockaddr *from, int *fromlen); - int getsockname (int socket, struct sockaddr *name, int *namelen); - - /* - * from /usr/include/arpa/inet.h - * (which under sunos4 does not include arguments for C++) - * (__SUNPRO_CC supplies this file but g++ does not supply - * an ansi protottype) - */ - unsigned long inet_addr (const char *); - char * inet_ntoa (struct in_addr in); - - /* - * from /usr/include/netdb.h - * (which under sunos4 does not include arguments for C++) - * (__SUNPRO_CC supplies an updated version of this file but g++ does not) - */ - struct hostent { - char *h_name; /* official name of host */ - char **h_aliases; /* alias list */ - int h_addrtype; /* host address type */ - int h_length; /* length of address */ - char **h_addr_list; /* list of addresses from name server */ - # define h_addr h_addr_list[0] /* address, for backward compatiblity */ - }; - struct hostent *gethostbyaddr(char *addr, int len, int type); - struct hostent *gethostnyname(const char *name); -# endif /* ifdef OSISOCK_ANSI_FUNC_PROTO */ -#endif /* !defined(__SUNPRO_CC) */ - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define SOCKERRSTR (strerror(errno)) -#define socket_close(S) close(S) -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE - -#endif /*osiSockH*/ - diff --git a/src/libCom/osi/os/sun4/osiFileName.h b/src/libCom/osi/os/sun4/osiFileName.h deleted file mode 100644 index 60e0a20da..000000000 --- a/src/libCom/osi/os/sun4/osiFileName.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/vxWorks/osdSock.h b/src/libCom/osi/os/vxWorks/osdSock.h deleted file mode 100644 index 196f93d50..000000000 --- a/src/libCom/osi/os/vxWorks/osdSock.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * vxWorks specific socket include - */ - -#ifndef osiSockH -#define osiSockH - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define SOCKERRSTR (strerror(SOCKERRNO)) -#define socket_close(S) close(S) -/* - * it is quite lame on WRS's part to assume that - * a ptr is always the same as an int - */ -#define socket_ioctl(A,B,C) ioctl(A,B,(int)C) -typedef int osiSockIoctl_t; - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7F000001 -#endif - -#endif /*osiSockH*/ - - diff --git a/src/libCom/osi/os/vxWorks/osiFileName.h b/src/libCom/osi/os/vxWorks/osiFileName.h deleted file mode 100644 index 55bb589a2..000000000 --- a/src/libCom/osi/os/vxWorks/osiFileName.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ \ No newline at end of file diff --git a/src/libCom/sydSubr.c b/src/libCom/sydSubr.c deleted file mode 100644 index 10d1295db..000000000 --- a/src/libCom/sydSubr.c +++ /dev/null @@ -1,4069 +0,0 @@ -/* @(#)sydSubr.c 1.18 2/23/93 - * Author: Roger A. Cole - * Date: 12-04-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1990-93, 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: - * ----------------- - * .00 12-04-90 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 06-19-91 rac replace with - * .03 08-15-91 rac update documentation; add args to sydChanOpen; - * enhance for use by ordinary users - * .04 09-11-91 rac for CA, report "noData" if ts==0; add more - * documentation - * .05 09-22-91 rac add sydInputFetch; add trigger routines; - * handle asynchronous ca_search - * .06 10-21-91 rac set the reference time stamp for the first - * sample which is stored; better handle long - * lines in printing; fold channel names when - * printing; put EGU in channel structure; - * put EGU in export file; support time stamp - * rounding; args changed for: sydSampleSetPrint; - * sydSamplePrint; sydInputStoreInSet; - * .07 11-02-91 rac add sydSampleWriteSSF, sydSampleSetWriteSSF - * .08 12-08-91 rac fix alignment for printing of channel names - * .09 01-20-92 rac add a code for VALID_ALARM and handle - * invalid values properly - * .10 02-04-92 rac allow multiple chanOpen for same name - * .11 02-18-92 rac finally handle array channels on print and export; - * add an export column for text time stamp - * .12 02-26-92 rac move timestamp rounding to the individual read - * routines, using a new routine here; add sydSetAttr - * and default deadband - * .13 03-23-92 rac set default monitor to use ADEL deadband - * .14 03-31-92 rac install a kludge to cope with 0 timestamps from EPICS; - * add attributes for calling a user CA monitor routine; - * add a "set-wide" connect flag and a "set-wide" flag - * for "waiting for graphics info"; generalize routines - * for copying buffers; use exponential format for - * exporting and printing tiny numbers; add support - * for mean and standard deviation; add capability to - * restrict range of interest to a subset of the samples; - * put a blank line in export file following snapshot; - * for .RVAL channels, set prec=0, EGU="counts" - * .15 08-25-92 rac fix bugs in exporting for restricted time range; - * fix sydSamplePrint to put a separator in front of - * the no data message; add better handling for SSF - * files with missing data; added a routine to prepare - * a channel for a new retrieval; discontinue use of - * special malloc routines - * .16 09-30-92 rac discard samples with earlier time stamps than the most - * recent sample; - * .17 01-05-93 rac add some documentation regarding the handling of - * samples with SYD_B_MISSING status; fix a bug for - * the handling of SYD_B_MISSING samples; add an - * option for exporting only means; fix a bug in - * sydInputReset where last buffer didn't get discarded; - * .18 03-22-93 changed VALID_ALARM to INVALID_ALARM - thanks - * .19 04-19-94 mrk removed static from sydSamplePrintStats - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert checking - * -DDEBUG compile various debug code - */ - - - - -#if 0 /* allow comments within the module heading */ -/* /*+/mod*********************************************************************** -/* * TITLE sydSubr.c - synchronous data routines -/* * -/* * DESCRIPTION -/* * These routines support: -/* * o defining a set of channels for which synchronous samples are -/* * to be acquired -/* * o checking to see if a synchronous sample is available -/* * o acquiring the next synchronous sample or a specified number -/* * of synchronous samples -/* * o storing the most recently acquired synchronous sample at the -/* * end of the set of synchronous samples -/* * o printing a particular synchronous sample or all samples in -/* * a synchronous sample set -/* * -/* * Sample acquisition can be from one of: -/* * o archiver `sample set' file -/* * o archiver `by channel' file -/* * o Channel Access -/* * -/* * sydPlot.c contains routines which support plotting a synchronous -/* * sample set. -/* * -/* * QUICK REFERENCE -/* * -/* * #include /* some general use definitions */ -/* * #include /* definitions for database related items */ -/* * #include /* structures for synchronous data routines */ -/* * -/* * SYD_SPEC *pSspec; /* pointer to synchronous set spec */ -/* * SYD_CHAN *pSChan; /* pointer to synchronous channel descriptor */ -/* * -/* * long sydChanClose( pSspec, pSChan ) -/* * SYD_CHAN *sydChanFind( pSspec, chanName ) -/* * long sydChanOpen( pSspec, >ppSChan, chanName, sync, pArg, trig) -/* * sync = SYD_SY_{NONF,FILLED} -/* * long sydChanPrep( pSspec, pSChan ) -/* * long sydClose( pSspec ) -/* * void sydCopyGr( >pDest, pSrc, srcDbrType ) -/* * void sydCopyVal( >pDest, pSrc, count, srcDbrType ) -/* * long sydFileInfo( pSspec, out ) -/* * long sydInputFetch( pSspec ) -/* * long sydInputGet( pSspec, >pMoreFlag ) -/* * void sydInputReset( pSspec ) -/* * void sydInputResetKeepNewest(pSspec ) -/* * void sydInputResetSampled(pSspec ) -/* * void sydInputStoreInSet( pSspec, ignorePartial ) -/* * long sydInputSync( pSspec ) -/* * long sydMonitorStart( pSspec ) -/* * long sydMonitorStop( pSspec ) -/* * long sydOpenCA( >ppSspec, NULL ) -/* * long sydOpenCF( >ppSspec, filePath ) -/* * long sydOpenSSF( >ppSspec, filePath ) -/* * long sydPosition( pSspec, pStamp ) -/* * long sydSampleExport( pSspec, out, fmtFlag, hdrFlag, sampNum) -/* * long sydSampleExportStats(pSspec, out, snapNum ) -/* * long sydSamplePrint( pSspec, out, fmtFlag, hdrFlag, -/* * nCol, colWidth, sampNum) -/* * long sydSamplePrintStats( pSspec, out, fmtFlag, hdrFlag, -/* * nCol, colWidth, snapNum) -/* * long sydSampleWriteSSF( pSspec, pFile, progDesc, sampDesc, sampNum) -/* * -/* * long sydSampleSetAlloc( pSspec, reqCount ) -/* * long sydSampleSetExport( pSspec, out, fmtFlag ) -/* * long sydSampleSetFree( pSspec ) -/* * long sydSampleSetGet( pSspec ) -/* * long sydSampleSetPrint( pSspec, out, fmtFlag, nCol, colWidth ) -/* * long sydSampleSetRestrict(pSspec, pTsBegin, pTsEnd ) -/* * long sydSampleSetStats( pSspec ) -/* * long sydSampleSetWriteSSF(pSspec, pFile, progDesc, sampDesc ) -/* * long sydSetAttr( pSspec, attr, value, pArg ) -/* * SYD_ATTR_DEADBAND, 0, {"ADEL" or "MDEL"} -/* * SYD_ATTR_MON_FN, 0, function -/* * SYD_ATTR_USE_STATS, 1, NULL -/* * SYD_ATTR_USE_MEANS, 1, NULL -/* * -/* * long sydTest( pSspec ) -/* * long sydTestAddFromText( pSspec, text ) -/* * long sydTestClose( pSspec ) -/* * int sydValAsDbl( pSChan, sampNum, pDbl ) -/* * -/* * BUGS -/* * o error detection and handling isn't "leakproof" -/* * o for retrieving from sample set files, if all the channels in the -/* * set are missing for two snapshots in a row, EOF is reported -/* * -/* * DESCRIPTION, continued -/* * -/* * o special terms -/* * -/* * synchronous sample--is a set of values, one for each channel, -/* * with the same time stamp for each -/* * -/* * synchronous sample set--is a set of synchronous samples, in order -/* * by time stamp. This frequently will be referred to as a -/* * synchronous set. -/* * -/* * synchronous channel descriptor--is the information about one -/* * of the channels for which synchronous data is to be acquired -/* * -/* * synchronous set specification--is the set of information describing -/* * how synchronous samples are to be acquired, and which channels -/* * are to be used -/* * -/* * o synchronous set specification -/* * -/* * A program can have one or more synchronous set specifications at the -/* * same time. Each is created with an "open" and destroyed with a -/* * "close". The "open" returns a pointer which is used in all -/* * subsequent operations with the "sync set spec". -/* * -/* * There are several routines available for opening a sync set spec; the -/* * one which is used determines where samples will be obtained. Most -/* * other sydXxx routines are independent of which source is being used. -/* * See sydOpen for more details. -/* * -/* * o synchronous channel descriptor -/* * -/* * After a sync set spec has been opened, one or more channels will -/* * be added to it with calls to sydChanOpen. When a channel is opened, -/* * it must be specified whether the channel will be treated as "filled" -/* * or as "synchronous". This distinction comes into play while samples -/* * are being acquired (see below). -/* * -/* * The value for a channel might be a scalar, as for a thermocouple, -/* * or an array, as for a digitized waveform. Most of the discussion -/* * which follows makes no distinction between the two kinds of values. -/* * -/* * When a channel is no longer wanted as part of a sync set spec, the -/* * sydChanClose call can be used to remove it. (The sydClose call -/* * automatically closes all channels in a sync set spec.) -/* * -/* * o acquiring synchronous samples -/* * -/* * Each channel is treated as having a stream of time-stamped values. -/* * When sydInputGet is called, the earliest time stamp for all the -/* * channels is found--this is the time stamp for the sample. Each -/* * channel which has a value with that time stamp is placed in the -/* * sample. If no samples have yet been recieved for a channel, then -/* * the channel is flagged as "missing" in the sample. The action taken -/* * when there is no value for a channel depends on how the channel was -/* * opened. -/* * -/* * If the sydChanOpen call specified SYD_SY_FILLED, then when the channel -/* * has no value at the chosen time stamp the most recent prior value is -/* * placed into the sample. This implements the assumption that the -/* * channel's value has remained constant. -/* * -/* * Specifying SYD_SY_NONF in the sydChanOpen call inhibits "filling in" -/* * a value in the sample when a channel has no value at the chosen -/* * time stamp. In this case, the channel will be flagged as "missing" -/* * in the sample. -/* * -/* * If data acquisition is from Channel Access, then some additional -/* * details come into play. The result is to compensate for possible -/* * network delays in transmitting data, which means that the calling -/* * program may occasionally receive a "no data now" status. In that -/* * case, the calling program is expected to try again later to see -/* * if additional data have been received. -/* * -/* * o accessing data for a sample -/* * -/* * o accessing data for a sample set -/* * -/* * EXAMPLE -/* * -/* * #include -/* * #include -/* * #include -/* * #include -/* * -/* * main() -/* * { -/* * SYD_SPEC *pSspec; /* pointer to sync set spec */ -/* * SYD_CHAN *pSchanBase; /* pointer to sync chan desc for POWER:BASE */ -/* * SYD_CHAN *pSchanLag; /* pointer to sync chan desc for POWER:LAG30 */ -/* * long stat; /* status return */ -/* * int i; -/* * int moreFlag; /* 1 if more samples waiting */ -/* * float sumBase, sumLag;/* sums for the two channels */ -/* * char timeText[28]; /* text for time stamp */ -/* * int chanStat; /* input status for channel */ -/* * -/* * /*--------------------------------------------------------------------------- -/* * * open the synchronous sample set specification and add the channels -/* * * to it -/* * *--------------------------------------------------------------------------*/ -/* * stat = sydOpenCA(&pSspec, NULL); -/* * if (stat != S_syd_OK) { -/* * printf("couldn't open sync set spec\n"); -/* * exit(1); -/* * } -/* * stat = sydChanOpen(pSspec, &pSchanBase, "rai_2000", SYD_SY_FILLED,NULL,0); -/* * if (stat != S_syd_OK) { -/* * printf("couldn't open POWER:BASE\n"); -/* * exit(1); -/* * } -/* * stat = sydChanOpen(pSspec, &pSchanLag, "rao_2000", SYD_SY_FILLED,NULL,0); -/* * if (stat != S_syd_OK) { -/* * printf("couldn't open POWER:LAG30\n"); -/* * exit(1); -/* * } -/* * /*--------------------------------------------------------------------------- -/* * * now get 100 synchronous samples and accumulate a running sum for -/* * * each channel. Since this example program is using Channel Access, -/* * * it loops on sydInputGet until a status of S_syd_noDataNow is -/* * * received; when retrieving from an archive file, such a loop wouldn't -/* * * be used. -/* * *--------------------------------------------------------------------------*/ -/* * sumBase = sumLag = 0.; -/* * i = 0; -/* * while (i < 100) { -/* * ca_pend_event(.1); /* allow Channel Access to get values */ -/* * stat = sydInputGet(pSspec, &moreFlag); /* see if any were obtained */ -/* * while (stat == S_syd_OK || stat == S_syd_partial) { -/* * i++; -/* * tsStampToText(&SydInputTs(pSspec), TS_TEXT_MMDDYY, timeText); -/* * printf("sample at %s more:%d--", timeText, moreFlag); -/* * chanStat = SydInputStatus(pSchanBase); -/* * if (chanStat != SYD_B_EOF && chanStat != SYD_B_MISSING) { -/* * sumBase += SydInputValAsFloat(pSchanBase); -/* * printf("%s= %f ", SydChanName(pSchanBase), -/* * SydInputValAsFloat(pSchanBase)); -/* * SydInputMarkAsSampled(pSchanBase); -/* * } -/* * chanStat = SydInputStatus(pSchanLag); -/* * if (chanStat != SYD_B_EOF && chanStat != SYD_B_MISSING) { -/* * sumLag += SydInputValAsFloat(pSchanLag); -/* * printf("%s= %f ", SydChanName(pSchanLag), -/* * SydInputValAsFloat(pSchanLag)); -/* * SydInputMarkAsSampled(pSchanLag); -/* * } -/* * printf("\n"); -/* * stat = sydInputGet(pSspec, &moreFlag); -/* * } -/* * } -/* * printf("sumBase= %f sumLag= %f\n", sumBase, sumLag); -/* * } -/* *-***************************************************************************/ -/****/ -#endif /* allow comments within the module heading */ - -#include -#define SYD_PRIVATE -#define SYD_PRIVATE_DATA -#include -#include -#ifndef INC_tsDefs_h -# include -#endif -#ifndef INCLcadefh -# include -#endif - -#ifdef vxWorks -# include -# include /* for O_RDWR and O_RDONLY definitions */ -# include -# include -#else -# include -# include /* for O_RDWR and O_RDONLY definitions */ -# include -# include -# include -#endif - -#define PRE_FL 1 -#define POST_FL 2 -#define SHOW_AR 4 -#define USE_QUO 8 -#define ENF_WID 16 -static void sydSamplePrint1(); -static void sydSamplePrintVal(); -static void sydChanFreeArrays(); -static void sydInputGetIn(); -long sydSampleSetAlloc(); -long sydSampleSetFree(); - - -#if SYD_SUBR_TEST -main() -{ - SYD_SPEC *pSspec; /* pointer to sync set spec */ - SYD_CHAN *pSchanBase; /* pointer to sync chan desc for POWER:BASE */ - SYD_CHAN *pSchanLag; /* pointer to sync chan desc for POWER:LAG30 */ - long stat; /* status return */ - int i; - int moreFlag; /* 1 if more samples waiting */ - float sumBase, sumLag;/* sums for the two channels */ - char timeText[28]; /* text for time stamp */ - int chanStat; /* input status for channel */ - int beg, end; - TS_STAMP begTs, endTs; - char begText[28], endText[28]; - -/*----------------------------------------------------------------------------- -* open the synchronous sample set specification and add the channels -* to it -*----------------------------------------------------------------------------*/ - stat = sydOpenCA(&pSspec, NULL); - if (stat != S_syd_OK) { - printf("couldn't open sync set spec\n"); - exit(1); - } - stat = sydChanOpen(pSspec, &pSchanBase, "gva_2000", SYD_SY_FILLED,NULL,0); - if (stat != S_syd_OK && stat != S_syd_chanNotConn) { - printf("couldn't open gva_2000\n"); - exit(1); - } - stat = sydChanOpen(pSspec, &pSchanLag, "gva_2001", SYD_SY_FILLED,NULL,0); - if (stat != S_syd_OK && stat != S_syd_chanNotConn) { - printf("couldn't open gva_2001\n"); - exit(1); - } -#if 0 -/*----------------------------------------------------------------------------- -* now get 50 synchronous samples and accumulate a running sum for -* each channel. Since this example program is using Channel Access, -* it loops on sydInputGet until a status of S_syd_noDataNow is -* received; when retrieving from an archive file, such a loop wouldn't -* be used. -*----------------------------------------------------------------------------*/ - sumBase = sumLag = 0.; - i = 0; - while (i < 20) { - ca_pend_event(.1); /* allow Channel Access to get values */ - stat = sydInputGet(pSspec, &moreFlag); /* see if any were obtained */ - while (stat == S_syd_OK || stat == S_syd_partial) { - i++; - tsStampToText(&SydInputTs(pSspec), TS_TEXT_MMDDYY, timeText); - printf("sample at %s more:%d--", timeText, moreFlag); - chanStat = SydInputStatus(pSchanBase); - if (chanStat != SYD_B_EOF && chanStat != SYD_B_MISSING) { - sumBase += SydInputValAsFloat(pSchanBase); - printf("%s= %f ", SydChanName(pSchanBase), - SydInputValAsFloat(pSchanBase)); - SydInputMarkAsSampled(pSchanBase); - } - chanStat = SydInputStatus(pSchanLag); - if (chanStat != SYD_B_EOF && chanStat != SYD_B_MISSING) { - sumLag += SydInputValAsFloat(pSchanLag); - printf("%s= %f ", SydChanName(pSchanLag), - SydInputValAsFloat(pSchanLag)); - SydInputMarkAsSampled(pSchanLag); - } - printf("\n"); - stat = sydInputGet(pSspec, &moreFlag); - } - } - printf("sumBase= %f sumLag= %f\n", sumBase, sumLag); -#endif - printf("checking connections\n"); - for (i=0; i<20; i++) { - if (pSchanBase->discon || pSchanLag->discon) - ca_pend_event(.1); - else - break; - } - if (pSchanBase->discon || pSchanLag->discon) { - printf("at least one channel isn't connected\n"); - exit(1); - } - printf("getting samples to store--storing all\n"); - stat = sydSampleSetAlloc(pSspec, 50); - assert(stat == S_syd_OK); - for (i=0; i<20; ) { - ca_pend_event(.1); - stat = sydInputGet(pSspec, &moreFlag); /* see if any were obtained */ - while (stat == S_syd_OK || stat == S_syd_partial) { - sydInputStoreInSet(pSspec, 0); - printf("."); - fflush(stdout); - i++; - stat = sydInputGet(pSspec, &moreFlag); - } - } - printf("\n"); - stat = sydSampleSetPrint(pSspec, stdout, 0, 5, 10); - assert(stat == S_syd_OK); - beg = 5; - end = 15; - begTs = pSspec->pTimeStamp[beg]; - begTs.nsec = 0; - endTs = pSspec->pTimeStamp[end]; - endTs.nsec = 999000000; - tsStampToText(&begTs, TS_TEXT_MMDDYY, begText); - tsStampToText(&endTs, TS_TEXT_MMDDYY, endText); - printf("range: %s to %s\n", begText, endText); - stat = sydSampleSetRestrict(pSspec, &begTs, &endTs); - assert(stat == S_syd_OK); - stat = sydSampleSetPrint(pSspec, stdout, 0, 5, 10); - assert(stat == S_syd_OK); - - printf("getting samples to store--storing if gva_200 > 4.5\n"); - stat = sydSampleSetAlloc(pSspec, 50); - assert(stat == S_syd_OK); - stat = sydTestAddFromText(pSspec, "if gva_2000 > 4.5"); - assert(stat == S_syd_OK); - for (i=0; i<20; ) { - ca_pend_event(.1); - stat = sydInputGet(pSspec, &moreFlag); /* see if any were obtained */ - while (stat == S_syd_OK || stat == S_syd_partial) { - sydInputStoreInSet(pSspec, 0); - printf("."); - fflush(stdout); - i++; - stat = sydInputGet(pSspec, &moreFlag); - } - } - printf("\n"); - stat = sydSampleSetPrint(pSspec, stdout, 0, 5, 10); - assert(stat == S_syd_OK); -} -#endif - -/*+/subr********************************************************************** -* NAME sydChanClose - delete a channel from a synchronous set spec -* -* DESCRIPTION -* This routine deletes a channel from a synchronous set spec. The -* other channels in the set aren't affected, and their data is -* preserved. -* -* RETURNS -* S_syd_OK -* -* SEE ALSO -* sydOpen, sydChanOpen, sydChanFind -* sydInputGet -* -*-*/ -long -sydChanClose(pSspec, pSChan) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -SYD_CHAN *pSChan; /* I pointer to synchronous channel descriptor */ -{ - int i; - - assert(pSspec != NULL); - assert(pSChan != NULL); - - if (pSspec->pFunc != NULL) - (void)(pSspec->pFunc)(pSspec, pSChan, SYD_FC_CLOSE, NULL); - for (i=0; inInBufs; i++) { - if (pSChan->pInBuf[i] != NULL) - free((char *)pSChan->pInBuf[i]); - } - sydChanFreeArrays(pSChan); - - pSspec->chanCount--; - DoubleListRemove(pSChan, pSspec->pChanHead, pSspec->pChanTail); - if (pSChan->testChan) { - free((char *)pSspec->pAccept); - pSspec->pAccept = NULL; - } - free((char *)pSChan); - - return S_syd_OK; -} -/*+/subr********************************************************************** -* NAME sydChanFreeArrays -* -*-*/ -static void -sydChanFreeArrays(pSChan) -SYD_CHAN *pSChan; -{ - if (pSChan->pData != NULL) { - free((char *)pSChan->pData); - pSChan->pData = NULL; - } - if (pSChan->pDataAlStat != NULL) { - free((char *)pSChan->pDataAlStat); - pSChan->pDataAlStat = NULL; - } - if (pSChan->pDataAlSev != NULL) { - free((char *)pSChan->pDataAlSev); - pSChan->pDataAlSev = NULL; - } - if (pSChan->pDataCodeL != NULL) { - free((char *)pSChan->pDataCodeL); - pSChan->pDataCodeL = NULL; - } - if (pSChan->pDataCodeR != NULL) { - free((char *)pSChan->pDataCodeR); - pSChan->pDataCodeR = NULL; - } - if (pSChan->pFlags != NULL) { - free((char *)pSChan->pFlags); - pSChan->pFlags = NULL; - } - if (pSChan->pStats != NULL) { - free((char *)pSChan->pStats); - pSChan->pStats = NULL; - } -} - -/*+/subr********************************************************************** -* NAME sydChanFind - find a channel in a synchronous set spec -* -* DESCRIPTION -* This routine finds a channel in a synchronous set spec. This can -* be useful in detecting duplications in channel name. -* -* RETURNS -* SYD_CHAN * for channel, if found, or -* NULL -* -*-*/ -SYD_CHAN * -sydChanFind(pSspec, chanName) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -char *chanName; /* I channel name to find in synchronous set spec */ -{ - SYD_CHAN *pSChan; /* pointer to channel descriptor */ - - assert(pSspec != NULL); - assert(chanName != NULL); - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (strcmp(pSChan->name, chanName) == 0) - break; - } - - return pSChan; -} - -/*+/subr********************************************************************** -* NAME sydChanOpen - add a channel to a synchronous set spec -* -* DESCRIPTION -* This routine opens a channel and adds it to the end of a synchronous -* set spec. -* -* Several data channels with the same name can be opened. (If -* retrieving from Channel Access, each will have its own monitor -* to the IOC. If the caller has his own monitor handler, monitoring -* doesn't actually begin until sydMonitorStart is called.) -* -* A channel can also be specified as a `test' channel, to be used -* by sydTest to check a value-related condition. Only one test -* channel can be specified for a sync set spec. -* -* RETURNS -* S_syd_OK, or -* S_syd_noMem no memory for adding channel to set -* S_syd_chanNotConn channel not connected to Channel Access (this -* isn't treated as an error condition--the -* channel is open and added to sync set spec) -* S_syd_chanNotFound channel not found -* S_syd_ERROR test channel specified, but there is already -* a test channel with that name -* -* BUGS -* o always places channel at end of list -* o data are always acquired using the native type of the channel, -* rather than caller-specified type -* o .RVAL channels are always treated as unsigned -* -* SEE ALSO -* sydOpen, sydChanClose, sydSetAttr -* sydInputGet, sydMonitorStart -* sydTest -* -* MACROS -* These macros extract fields from the synchronous channel structure -* created by sydChanOpen. By using these macros, the programmer -* can avoid the need to look inside the sample structures. -* -* Each macro takes as an argument a pointer to a synchronous -* channel structure, as returned by sydChanOpen or sydChanFind. -* -* SydChanArrayCount(pSChan) obtain the array count (1 for scalar) -* SydChanDbfType(pSChan) obtain the channel type. This will -* be one of the DBF_XXX types. -* SydChanDbrType(pSChan) obtain the value type. This will -* be one of the DBR_XXX types. -* SydChanName(pSChan) obtain the channel's name. -* SydChanEGU(pSChan) obtain the channel's engineering -* units text (if channel doesn't have EGU, this will be "none") -* -* Additional macros are described under sydInputGet. -* -* NOTES -* 1. For channels in AR sample set data files, SYD_SY_NONF is forced, -* without comment. -* 2. DBF_ENUM channels are flagged as SYD_ST_STEP; all other channels -* are flagged as SYD_ST_SMOOTH. -* 3. For retrievals from Channel Access, the usual return status will -* be S_syd_chanNotConn. To force the connection attempt to completion, -* the caller can call ca_pend_event following the call to this routine. -* If SydChanDbfType(pSChan) is TYPENOTCONN following the ca_pend_event, -* then the caller can assume the channel isn't presently connectable. -* 4. For retrievals from Channel Access, the deadband which will be -* used is determined by the SYD_ATTR_DEADBAND attribute. By default, -* the ADEL deadband is used. -* 5. For retrievals from Channel Access with a caller-specified monitor -* handler, the caller must call sydMonitorStart once for the sync set -* spec in order to get a monitor started. -* 6. For .RVAL channels, PREC is set to 0 and EGU is set to "counts". -* Special processing is done for printing, plotting, exporting, and -* statistics computing--the value is treated as unsigned. -* -* EXAMPLE -* -*-*/ -long -sydChanOpen(pSspec, ppSChan, chanName, sync, pArg, test) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -SYD_CHAN **ppSChan; /* O pointer to sync channel pointer; or NULL */ -char *chanName; /* I channel name (.VAL assumed if field omitted) */ -enum sydChanSync sync; /* I sync/non-sync; SYD_SY_NONF or SYD_SY_FILLED */ -void *pArg; /* I pointer to struct needed to init, or NULL */ -int test; /* I 0,1 if this is data,test channel */ -{ - long retStat=S_syd_OK;/* return status to caller */ - long stat; /* status return from calls */ - SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ - enum sydChanStep step; /* step type: SYD_ST_STEP or SYD_ST_CONTIN */ - int i; - int new=1; - - assert(pSspec != NULL); - assert(strlen(chanName) > 0); - assert(strlen(chanName) < db_name_dim); - - if (ppSChan != NULL) - *ppSChan = NULL; - -/*----------------------------------------------------------------------------- -* allocate and initialize an empty synchronous channel structure. If this -* channel has already been opened as a data or test channel, then the -* previously used structure is used. -*----------------------------------------------------------------------------*/ - if ((pSChan = sydChanFind(pSspec, chanName)) != NULL) { - if (pSChan->testChan) { - if (test) - return S_syd_ERROR; - if (pSChan->dataChan == 0) - new = 0; - } - else - new = 0; - } - if (new) { - pSChan = (SYD_CHAN *)malloc(sizeof(SYD_CHAN)); - if (pSChan == NULL) - return S_syd_noMem; - DoubleListAppend(pSChan, pSspec->pChanHead, pSspec->pChanTail); - pSspec->chanCount++; - pSChan->pSspec = pSspec; - pSChan->pHandle = NULL; - pSChan->evid = NULL; - pSChan->nInBufs = pSspec->nInBufs; - for (i=0; inInBufs; i++) { - pSChan->inStatus[i] = SYD_B_EMPTY; - pSChan->pInBuf[i] = NULL; - } - pSChan->firstInBuf = pSChan->lastInBuf = pSChan->sampInBuf = -1; - pSChan->minDataVal = pSChan->maxDataVal = 0.; - pSChan->minMaxNeedInit = 1; - pSChan->restrictMinDataVal = pSChan->restrictMaxDataVal = 0.; - strcpy(pSChan->name, chanName); - strcpy(pSChan->label, chanName); - strcat(pSChan->label, " not conn"); - strcpy(pSChan->EGU, "none"); - pSChan->sync = sync; - pSChan->isRVAL = 0; - pSChan->pData = NULL; - pSChan->pDataAlStat = pSChan->pDataAlSev = NULL; - pSChan->pDataCodeL = pSChan->pDataCodeR = NULL; - pSChan->pFlags = NULL; - pSChan->conn = 0; - pSChan->discon = 1; - pSChan->dataChan = test?0:1; - pSChan->pArg = NULL; - pSChan->pStats = NULL; - } - if (pArg != NULL && pSChan->pArg == NULL) - pSChan->pArg = pArg; - pSChan->testChan = test; - -/*----------------------------------------------------------------------------- -* "open" the "source" for the data for the channel. This will provide -* information about how large the buffers need to be. If retrieval is -* from Channel Access, the buffer allocation, etc., will be deferred if -* the connection isn't complete. -*----------------------------------------------------------------------------*/ - if (new) { - stat = (pSspec->pFunc)(pSspec, pSChan, SYD_FC_OPEN, pArg); - if (stat == S_syd_OK) { - stat = sydChanOpen1(pSspec, pSChan); - if (stat == S_syd_OK) - stat = sydChanOpenGR(pSChan); - } - else if (stat == S_syd_chanNotConn && pSspec->type == SYD_TY_CA) { - if (ppSChan != NULL) - *ppSChan = pSChan; - } - - if (stat != S_syd_OK && stat != S_syd_chanNotConn) { - (void)sydChanClose(pSspec, pSChan); - return stat; - } - retStat = stat; - } - - if (ppSChan != NULL) - *ppSChan = pSChan; - - return retStat; -} - -/*+/internal****************************************************************** -* NAME sydChanOpen1 - open completion, after connect is complete -* -*-*/ -long -sydChanOpen1(pSspec, pSChan) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -SYD_CHAN *pSChan; /* I sync channel pointer */ -{ - int i; - long retStat=S_syd_OK; - - assert(pSspec != NULL); - assert(pSChan != NULL); - - pSChan->conn = 1; - pSChan->discon = 0; - -/*----------------------------------------------------------------------------- -* allocate the required number of input buffers -* set either SMOOTH or STEP for the channel -*----------------------------------------------------------------------------*/ - for (i=0; inInBufs; i++) { - pSChan->pInBuf[i] = (union db_access_val *)malloc( - dbr_size_n(pSChan->dbrType, pSChan->elCount)); - if (pSChan->pInBuf[i] == NULL) { - (void)sydChanClose(pSspec, pSChan); - retStat = S_syd_noMem; - } - } - return retStat; -} - -/*+/internal****************************************************************** -* NAME sydChanOpenGR - handle graphics info at open time, connect done -* -* DESCRIPTION -* Sets prec, EGU, and label. If the channel is a .RVAL channel, -* prec is set to 0 and EGU is set to `counts'. -* -* `isRVAL' is set for .RVAL channels. -* `step' is set to SYD_ST_SMOOTH, or _STEP for ENUM channels -* -*-*/ -long -sydChanOpenGR(pSChan) -SYD_CHAN *pSChan; /* I sync channel pointer */ -{ - char *pC; - - if (pSChan->dbrType != DBR_TIME_ENUM) - pSChan->step = SYD_ST_SMOOTH; - else - pSChan->step = SYD_ST_STEP; - if ((pC = strrchr(pSChan->name, '.')) != NULL && - strcmp(pC, ".RVAL") == 0) { - pSChan->precision = 0; - strcpy(pSChan->EGU, "counts"); - pSChan->isRVAL = 1; - } - else if (pSChan->dbrType == DBR_TIME_FLOAT) { - pSChan->precision = pSChan->grBuf.gfltval.precision; - strcpy(pSChan->EGU, pSChan->grBuf.gfltval.units); - } - else if (pSChan->dbrType == DBR_TIME_SHORT) { - pSChan->precision = 0; - strcpy(pSChan->EGU, pSChan->grBuf.gshrtval.units); - } - else if (pSChan->dbrType == DBR_TIME_DOUBLE) { - pSChan->precision = pSChan->grBuf.gdblval.precision; - strcpy(pSChan->EGU, pSChan->grBuf.gdblval.units); - } - else if (pSChan->dbrType == DBR_TIME_LONG) { - pSChan->precision = 0; - strcpy(pSChan->EGU, pSChan->grBuf.glngval.units); - } - else if (pSChan->dbrType == DBR_TIME_CHAR) { - pSChan->precision = 0; - strcpy(pSChan->EGU, pSChan->grBuf.gchrval.units); - } - else if (pSChan->dbrType == DBR_TIME_ENUM) { - pSChan->precision = -1; - strcpy(pSChan->EGU, " "); - } - else { - pSChan->precision = 0; - strcpy(pSChan->EGU, " "); - } - sprintf(pSChan->label, "%s %s", pSChan->name, pSChan->EGU); - if (pSChan->dbrType != DBR_TIME_ENUM && pSChan->isRVAL == 0) { - if (pSChan->precision > 10 || pSChan->precision <= 0) - pSChan->precision = 3; - } - - if (*pSChan->EGU == ' ' || strlen(pSChan->EGU) == 0) - strcpy(pSChan->EGU, "none"); - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydChanPrep - prepare a channel for a new retrieval -* -* DESCRIPTION -* This routine initializes a channel structure in preparation for -* a new retrieval. -* -* RETURNS -* S_syd_OK -* -* SEE ALSO -* sydSampleSetGet, sydInputGet, sydInputStoreInSet -* -*-*/ -long -sydChanPrep(pSspec, pSChan) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -SYD_CHAN *pSChan; /* I pointer to synchronous channel descriptor */ -{ - int i; - - assert(pSspec != NULL); - assert(pSChan != NULL); - - pSChan->minDataVal = pSChan->maxDataVal = 0.; - pSChan->minMaxNeedInit = 1; - pSChan->restrictMinDataVal = pSChan->restrictMaxDataVal = 0.; -} - -/*+/subr********************************************************************** -* NAME sydClose - close a synchronous set spec -* -* DESCRIPTION -* This routine closes a synchronous set spec, closing channels, etc., -* wrapping up the retrieval "source", and then free()'s the data -* structures associated with the set. -* -* RETURNS -* S_syd_OK, or -* other status codes if an error occurs -* -* BUGS -* o the `wrapup' call should do the free, since the free must -* match the malloc--if this routine is compiled with DEBUG and -* the routine which did the malloc (e.g., sydSubrCA) is compiled -* without it, then the free here will complain. -* -* SEE ALSO -* sydOpen -* -* EXAMPLE -* -*-*/ -long -sydClose(pSspec) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -{ - long retStat=S_syd_OK;/* return status to caller */ - long stat; - - assert(pSspec != NULL); - - while (pSspec->pChanHead != NULL) { - if (sydChanClose(pSspec, pSspec->pChanHead) != S_syd_OK) - (void)printf("sydClose: error closing channel\n"); - } - - sydSampleSetFree(pSspec); - - stat = (pSspec->pFunc)(pSspec, NULL, SYD_FC_WRAPUP, NULL); - if (stat != S_syd_OK) - retStat = stat; - - free((char *)pSspec); - return retStat; -} - -/*+/subr********************************************************************** -* NAME sydCopyGr -* -* DESCRIPTION -* Copies the graphics information from the Channel Access buffer into -* the caller's buffer. The CA buffer must be a DBR_GR type; the -* caller's buffer is assumed to be the same type. -* -*-*/ -void -sydCopyGr(pDest, pSrc, srcDbrType) -void *pDest; /* O pointer to buffer to receive graphics info */ -void *pSrc; /* I pointer to buffer holding graphics info */ -chtype srcDbrType; /* I DBR_xxx type of the source buffer */ -{ -#define U_DB union db_access_val * - if (srcDbrType == DBR_GR_FLOAT) { - ((U_DB)pDest)->gfltval = ((U_DB)pSrc)->gfltval; - ((U_DB)pDest)->gfltval.units[7] = '\0'; - } - else if (srcDbrType == DBR_GR_SHORT) { - ((U_DB)pDest)->gshrtval = ((U_DB)pSrc)->gshrtval; - ((U_DB)pDest)->gshrtval.units[7] = '\0'; - } - else if (srcDbrType == DBR_GR_DOUBLE) { - ((U_DB)pDest)->gdblval = ((U_DB)pSrc)->gdblval; - ((U_DB)pDest)->gdblval.units[7] = '\0'; - } - else if (srcDbrType == DBR_GR_LONG) { - ((U_DB)pDest)->glngval = ((U_DB)pSrc)->glngval; - ((U_DB)pDest)->glngval.units[7] = '\0'; - } - else if (srcDbrType == DBR_GR_STRING) - ((U_DB)pDest)->gstrval = ((U_DB)pSrc)->gstrval; - else if (srcDbrType == DBR_GR_ENUM) - ((U_DB)pDest)->genmval = ((U_DB)pSrc)->genmval; - else if (srcDbrType == DBR_GR_CHAR) { - ((U_DB)pDest)->gchrval = ((U_DB)pSrc)->gchrval; - ((U_DB)pDest)->gchrval.units[7] = '\0'; - } - else - assertAlways(0); -} - -/*+/subr********************************************************************** -* NAME sydCopyVal - copy channel value -* -* DESCRIPTION -* Copies the value from the Channel Access buffer into the caller's -* buffer. The CA buffer can be any valid DBR_xxx type; the caller's -* buffer is assumed to be the corresponding DBF_xxx type--i.e., with -* room only for the value, and not the status, time stamp, etc. -* -*-*/ -void -sydCopyVal(pDest, pSrc, count, srcDbrType) -void *pDest; /* O pointer to buffer to receive value */ -void *pSrc; /* I pointer to buffer holding value */ -int count; /* I array element count */ -chtype srcDbrType; /* I DBR_xxx type of the source buffer */ -{ - int i; - - if (dbr_type_is_FLOAT(srcDbrType)) { - float *pD=(float *)pDest; - float *pS=(float *)dbr_value_ptr(pSrc, srcDbrType); - for (i=0; ipFunc)(pSspec, NULL, SYD_FC_FILEINFO, outStream); - if (stat != S_syd_OK) - retStat = S_syd_ERROR; - return retStat; -} - -/*+/subr********************************************************************** -* NAME sydInputGet - get the next synchronous sample -* -* DESCRIPTION -* This routine acquires the next sample for the channels in the -* synchronous set spec. For retrievals from Channel Access when -* the caller is using his own monitor handler, calling this -* routine does nothing and isn't necessary. -* -* The desired time stamp for the `next sample' is determined by -* searching forward from the time of the previous sample. Among the -* channels in the synchronous set spec, the one which changes soonest -* is the one whose time stamp is used for the next sample. Values are -* handled on either a "non-filled" or a "filled" basis. -* -* For "filled" channels, it is assumed that if a change isn't -* detected in a channel's value, then the present value (i.e., the -* value at the desired time stamp) must be the same as it was when -* it last changed. If there is no data at the desired time stamp for -* one or more of the channels, then the return status will be -* S_syd_partial. There is no data for a "filled" channel -* if the desired time stamp is prior to the first value for the -* channel or if the desired time stamp is after the last value in -* the file for the channel. -* -* For "non-filled" channels, it is assumed that if there is no value -* for the desired time stamp then the channel has missing data at -* that time; in this case the return status will be S_syd_partial. -* -* When retrieving from Channel Access, the situation is slightly more -* complicated. Since there may be an unpredictable delay in receiving -* a monitored value for a channel, values are buffered prior to -* assembling a synchronous sample. If one or more channels don't -* have a value for the time stamp, it may be because appropriate data -* haven't arrived yet. If this is the case, and if no other channels -* are about to overflow their buffers, then a return status of -* S_syd_noDataNow is generated. When S_syd_noDataNow is returned, the -* caller should try again later. Because of the nature of acquiring -* data using Channel Access monitors, it is recommended that this -* routine be called repeatedly until a status of S_syd_noDataNow is -* returned, and then check periodically until more data are available. -* The caller must periodically call ca_pend_event in order to allow -* Channel Access to give data to the sydXxx routines. -* -* There are two main ways of dealing with samples obtained from this -* routine--use the other sydXxx routines to manipulate it or access -* it directly for manipulation by user code. The first case is -* the simplest, and would probably use sydSampleSetGet rather than -* this routine. The second alternative is described in more detail -* below. -* -* The status of the sample for a channel is obtained with the -* SydInputStatus macro; several cases may be encountered: -* o status is SYD_B_FULL, SYD_B_RESTART, or SYD_B_SAMPLED; the -* buffer contains valid sample data. Once the caller has dealt -* with the sample, THE CALLER MUST call SydInputMarkAsSampled!!! -* o status is SYD_B_MISSING or SYD_B_EOF; no data is available -* o statuses of SYD_B_SNAP_BEGIN, SYD_B_SNAP_SINGLE, and -* SYD_B_SNAP_END can also occur; these can be treated as synonyms -* of SYD_B_FULL. -* -* RETURNS -* S_syd_OK all channels are present in sample -* S_syd_partial some channels are missing from sample; -* such channels will have .sampInBuf of -1 -* or else buffer status will be SYD_B_EOF -* or SYD_B_MISSING -* S_syd_noDataNow for Channel Access retrievals, a sample -* isn't available now; try later -* S_syd_EOF end of file--no more samples available -* -* BUGS -* o should get and report actual number of bytes from the read -* o for AR sample set files, if all channels are missing for 2 -* successive samples, EOF is reported, even though file isn't at end -* -* SEE ALSO -* sydChanOpen, sydSamplePrint, sydInputStoreInSet, sydSampleSetGet -* -* MACROS -* These macros extract fields from input buffers produced by sydInputGet. -* By using these macros, the programmer can avoid the need to look -* inside the sample structures. -* -* Each macro takes as an argument a pointer to a synchronous sample -* channel structure, as returned by sydChanOpen or sydChanFind. -* -* The SydInputValAsXxx macros must not be called if the value -* returned by SydInputStatus is SYD_B_MISSING or SYD_B_EOF. -* -* SydInputStatus(pSChan) obtain the input sample status for a -* channel. This will be one of the SYD_B_XXX values. -* SydInputTs(pSspec) obtain time stamp of the input -* sample. (Note that this uses the sample spec, not the -* channel pointer.) -* SydInputMarkAsSampled(pSChan) set the input sample status to -* SYD_B_SAMPLED -* -* Access the input value for a channel, following sydInputGet (these -* macros don't do any conversion--the one that is used must match -* the type of the input value) -* SydInputValAsFloat(pSChan) returns a float -* SydInputValAsDouble(pSChan) returns a double -* SydInputValAsShort(pSChan) returns a short -* SydInputValAsLong(pSChan) returns a long -* SydInputValAsChar(pSChan) returns a char -* SydInputValAsString(pSChan) returns a string (i.e., char *) -* SydInputValAsVoidPtr(pSChan) returns a void * pointer to -* value (useful for array channels) -* -* Additional macros are described under sydChanOpen. -* -* NOTES -* 1. The `more flag' is for use only with Channel Access. It serves as -* a hint that another call to sydInputGet will be successful. This -* is useful for programs which want to throw away all but the most -* recent sample if they fall behind. The technique with such -* programs is to repeatedly call sydInputGet until the return status -* is S_syd_noDataNow, and process only those cases in which the -* `more flag' is returned as zero. (SydInputMarkAsSampled must -* be called for the skipped samples, as well as for those which -* are processed.) It may be interesting to note that a zero value -* doesn't guarantee that the next call will result in a status of -* S_syd_noDataNow. -* 2. A sample for a channel can have a valid time stamp and still have -* a status of SYD_B_MISSING. The main way this happens is when -* reading a `sample set' file. -* -* EXAMPLE -* Get the next sample, then print the values and statuses for the -* channels. If Channel Access has queued up several values from the -* IOC, then several samples will probably be processed. This example -* ignores the differences between SYD_B_FULL, SYD_B_RESTART, and -* SYD_B_SAMPLED. -* -* SYD_CHAN *pSChan1, *pSChan2, ...; pointers to channel structures -* int status; -* float value; -* char timeText[28]; -* int moreFlag; -* -* ca_pend_event(.1); -* stat = sydInputGet(pSspec, &moreFlag); -* while (stat == S_syd_OK || stat == S_syd_partial) { -* tsStampToText(&SydInputTs(pSspec), TS_TEXT_MMDDYY, timeText); -* printf("sample time stamp is %s\n", timeText); -* if (stat == S_syd_partial) -* printf("one or more channels don't have data\n"); -* status = SydInputStatus(pSChan1); -* if (status == SYD_B_MISSING || status == SYD_B_EOF) -* printf("%s has missing data\n", pSChan1->name); -* else { -* value = SydInputValAsFloat(pSChan1); -* printf("%s value is: %f\n", value); -* SydInputMarkAsSampled(pSChan1); -* } -* -* stat = sydInputGet(pSspec, &moreFlag); try for another sample -* } -* -*-*/ -long -sydInputGet(pSspec, pMoreFlag) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -int *pMoreFlag; /* O pointer to flag or NULL; a return value of 1 - indicates more data is available; 0 indicates - uncertainty about whether more is available */ -{ - long retStat=S_syd_OK;/* return status to caller */ - long stat; /* status return from calls */ - int readIndx; /* select buffer to use for read */ - SYD_CHAN *pSChan; /* pointer to channel in Sspec */ - double refDiff; /* difference from reference time */ - TS_STAMP nextTs; /* time stamp for next sample */ - int i, i1, i2, j, now=0, later=0; - int moreFlag=1; /* assume there's more; reset if not */ - enum sydBStatus inStatus_i, inStatus_i1, inStatus_i2; - int full_i, full_i1, full_i2; - - assert(pSspec != NULL); - assert(pSspec->pChanHead != NULL); - - nextTs.secPastEpoch = 0; - nextTs.nsec = 0; - pSspec->eofCount = 0; - -#define BUFiTS pSChan->pInBuf[i]->tstrval.stamp -#define BUFi1TS pSChan->pInBuf[i1]->tstrval.stamp - -/*----------------------------------------------------------------------------- -* try to get at least two "available" buffers of input data -*----------------------------------------------------------------------------*/ - sydInputGetIn(pSspec); - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { -/*----------------------------------------------------------------------------- -* with two buffers of data, determine if this channel can contribute to -* the time stamp for the sample. It can potentially contribute if: -* o .firstInBuf is SYD_B_FULL or SYD_B_RESTART or SYD_B_MISSING, or -* o .firstInBUf is SYD_B_SAMPLED and the next buffer is SYD_B_FULL -* -* For SYD_TY_CA, some buffer checks are performed. If a channel is -* about to lose data (because buffer is nearly full), then the `now' -* flag is set to force generating a partial sample. If a channel has -* no data, then the `later' flag is set to gently request returning a -* status of S_syd_noDataNow; this is also done if the channel has only -* one value and its status is SYD_B_SAMPLED. -* -* the time stamp for the sample is the smallest time stamp of all -* the channels which can contribute. If no SYD_B_FULL or SYD_B_RESTART or -* SYD_B_MISSING buffers are available, then .nextTs will be 0 . -*----------------------------------------------------------------------------*/ - i = pSChan->firstInBuf; - inStatus_i = pSChan->inStatus[i]; - full_i = inStatus_i == SYD_B_FULL || inStatus_i == SYD_B_RESTART || - inStatus_i == SYD_B_SNAP_BEGIN || - inStatus_i == SYD_B_SNAP_SINGLE || inStatus_i == SYD_B_SNAP_END; - i1 = NEXT_INBUF(pSChan, i); - inStatus_i1 = pSChan->inStatus[i1]; - full_i1 = inStatus_i1 == SYD_B_FULL || inStatus_i1 == SYD_B_RESTART || - inStatus_i1 == SYD_B_SNAP_BEGIN || - inStatus_i1 == SYD_B_SNAP_SINGLE || inStatus_i1 == SYD_B_SNAP_END; - if (i < 0) - later = 1; - else if (full_i) { - if (pSspec->type == SYD_TY_CA) { - j = pSChan->lastInBuf; - if (j < pSChan->firstInBuf) - j += pSChan->nInBufs; - if (pSChan->nInBufs - (j - pSChan->firstInBuf +1) < 3) - now = 1; /* 3 or fewer empty slots left */ - } - if (nextTs.secPastEpoch == 0 || TsCmpStampsLT(&BUFiTS, &nextTs)) - nextTs = BUFiTS; - } - else if (inStatus_i == SYD_B_MISSING) { - if (TsCmpStampsLT(&BUFiTS, &nextTs)) - nextTs = BUFiTS; - } - else if (full_i1) { - if (pSspec->type == SYD_TY_CA) { - j = pSChan->lastInBuf; - if (j < pSChan->firstInBuf) - j += pSChan->nInBufs; - if (pSChan->nInBufs - (j - pSChan->firstInBuf +1) < 3) - now = 1; /* 3 or fewer empty slots left */ - } - if (nextTs.secPastEpoch == 0 || TsCmpStampsLT(&BUFi1TS, &nextTs)) - nextTs = BUFi1TS; - } - else if (inStatus_i1 == SYD_B_MISSING) { - if (TsCmpStampsLT(&BUFi1TS, &nextTs)) - nextTs = BUFi1TS; - } - else if (i == pSChan->lastInBuf && inStatus_i == SYD_B_SAMPLED) { - later = 1; - } - else - later = 1; - } - -/*---------------------------------------------------------------------------- -* now that we have as much info as possible to play with, figure out how -* to put together a sample to return to the caller. If no data at all -* are available, just return an EOF notification (or, for SYD_TY_CA, give -* a noDataNow notification). -*----------------------------------------------------------------------------*/ - if (pSspec->type == SYD_TY_CA && now == 0 && later == 1) { - return S_syd_noDataNow; - } - if (nextTs.secPastEpoch == 0) - if (pSspec->type != SYD_TY_CA) - return S_syd_EOF; - else - return S_syd_noDataNow; - - if (pSspec->refTs.secPastEpoch == 0 || pSspec->sampleCount == 0) { -/*---------------------------------------------------------------------------- -* It is necessary to initialize the reference time stamp in the Sspec -* descriptor. The reference time stamp starts on a one second boundary. -*----------------------------------------------------------------------------*/ - pSspec->refTs.secPastEpoch = nextTs.secPastEpoch; - pSspec->refTs.nsec = 0; - pSspec->restrictRefTs = pSspec->refTs; - } - -/*---------------------------------------------------------------------------- -* A channel may be included in the sample if either its oldest or its -* second oldest buffer has a valid time stamp. A buffer will have a -* valid time stamp if its status is SYD_B_FULL, SYD_B_RESTART, or -* SYD_B_MISSING. -* -* The oldest buffer is included in the sample a) if its time stamp is -* <= to the retrieval time stamp; or b) if its time stamp is less -* than the retrieval time stamp and the second oldest buffer isn't -* eligible to include in the sample. If the oldest buffer IS included, -* the sample status will be `partial' if the buffer status is either -* SYD_B_MISSING or SYD_B_EOF. If a previously sampled value is used for -* the current sample, then .reused is set to 1 . -* -* If the oldest buffer isn't included in the sample, then the second -* oldest buffer will be included if its time stamp is <= to the retrieval -* time stamp. If the second oldest buffer is included in the sample, -* then the oldest buffer is flagged as empty. -* -* For Channel Access retrievals, the moreFlag will be reset if: -* o a channel doesn't contribute to the sample; or -* o a channel doesn't have one more SYD_B_FULL buffer -*----------------------------------------------------------------------------*/ - - pSspec->priorTs = pSspec->sampleTs; - pSspec->sampleTs = nextTs; - pSspec->partial = 0; - TsDiffAsDouble(&pSspec->sampleSec, &pSspec->sampleTs, &pSspec->refTs); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - i = pSChan->firstInBuf; - inStatus_i = pSChan->inStatus[i]; - full_i = inStatus_i == SYD_B_FULL || inStatus_i == SYD_B_RESTART || - inStatus_i == SYD_B_SNAP_BEGIN || - inStatus_i == SYD_B_SNAP_SINGLE || inStatus_i == SYD_B_SNAP_END; - i1 = NEXT_INBUF(pSChan, i); - inStatus_i1 = pSChan->inStatus[i1]; - full_i1 = inStatus_i1 == SYD_B_FULL || inStatus_i1 == SYD_B_RESTART || - inStatus_i1 == SYD_B_SNAP_BEGIN || - inStatus_i1 == SYD_B_SNAP_SINGLE || inStatus_i1 == SYD_B_SNAP_END; - if (i < 0) { - pSChan->sampInBuf = -1; - moreFlag = 0; - pSspec->partial = 1; - retStat = S_syd_partial; - } - else if (full_i && TsCmpStampsLE(&BUFiTS, &nextTs)) { - pSChan->sampInBuf = i; - if (inStatus_i1 != SYD_B_FULL) - moreFlag = 0; - pSChan->reused = 0; - } - else if (pSChan->inStatus[i] == SYD_B_SAMPLED || - pSChan->inStatus[i] == SYD_B_MISSING) { - if ((full_i1 || inStatus_i1 == SYD_B_MISSING) && - TsCmpStampsLE(&BUFi1TS, &nextTs)) { - pSChan->inStatus[i] = SYD_B_EMPTY; - pSChan->firstInBuf = i1; - pSChan->reused = 0; - pSChan->sampInBuf = i1; - i2 = NEXT_INBUF(pSChan, i1); - inStatus_i2 = pSChan->inStatus[i2]; - full_i2 = inStatus_i2 == SYD_B_FULL || - inStatus_i2 == SYD_B_RESTART || - inStatus_i2 == SYD_B_SNAP_BEGIN || - inStatus_i2 == SYD_B_SNAP_SINGLE || - inStatus_i2 == SYD_B_SNAP_END; - if (!full_i2) - moreFlag = 0; - } - else { - if (pSChan->inStatus[i] == SYD_B_SAMPLED) - pSChan->reused = 1; - pSChan->sampInBuf = i; - if (!full_i1) - moreFlag = 0; - } - } - else if (inStatus_i == SYD_B_EOF) { - pSChan->sampInBuf = i; - moreFlag = 0; - pSspec->eofCount++; - pSspec->partial = 1; - retStat = S_syd_partial; - } - else { - pSChan->sampInBuf = -1; - moreFlag = 0; - pSspec->partial = 1; - retStat = S_syd_partial; - } - if (pSChan->sampInBuf >= 0 && - pSChan->inStatus[pSChan->sampInBuf] == SYD_B_MISSING) { - moreFlag = 0; - pSspec->partial = 1; - retStat = S_syd_partial; - } - } - if (pMoreFlag != NULL) - *pMoreFlag = moreFlag; - - return retStat; -} - -/*+/internal****************************************************************** -* NAME sydInputGetIn - get new input data, possibly discarding old -* -* DESCRIPTION -* Checks input buffers, discarding old buffers, if possible. Then, -* except for SYD_TY_CA, an attempt is made to fill 2 input buffers. -* Finally, the time stamps are checked for the first 2 buffers--if -* either is 0, it is set to 1. -* -* RETURNS -* NULL -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -static void -sydInputGetIn(pSspec) -SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */ -{ - long stat; /* status return from calls */ - SYD_CHAN *pSChan; /* pointer to channel in Sspec */ - int i, i1, discard; - enum sydBStatus inStatus_i1; - int full_i1; - - assert(pSspec != NULL); - assert(pSspec->pChanHead != NULL); - -/*---------------------------------------------------------------------------- -* try to get both buffers for the channel to be SYD_B_FULL, performing -* reads as necessary. When processing is complete, buffer status will be -* either SYD_B_FULL, SYD_B_SAMPLED, SYD_B_MISSING, SYD_B_EMPTY, -* or SYD_B_EOF. -*----------------------------------------------------------------------------*/ - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { -/*----------------------------------------------------------------------------- -* see if the oldest input can be thrown away. This is possible if: -* o buffer status is SYD_B_SAMPLED and one of the following is also true: -* - channel is SYD_SY_NONF, or -* - channel is SYD_SY_FILLED, and either: -* . the next buffer's status is SYD_B_FULL (or RESTART), and the -* next buffer's time stamp is less than or equal to the previous -* sample time stamp; or, -* . the next buffer's status is SYD_B_MISSING, and the next -* buffer's time stamp is less than or equal to the previous -* sample time stamp; or, -* o buffer status is SYD_B_MISSING and: -* - the next buffer's status is SYD_B_FULL (or RESTART), and the next -* buffer's time stamp is less than or equal to the previous -* sample time stamp -* -*----------------------------------------------------------------------------*/ - if ((i = pSChan->firstInBuf) >= 0) { - discard = 0; - i1 = NEXT_INBUF(pSChan, i); - inStatus_i1 = pSChan->inStatus[i1]; - full_i1 = inStatus_i1==SYD_B_FULL || inStatus_i1==SYD_B_RESTART || - inStatus_i1==SYD_B_SAMPLED || inStatus_i1==SYD_B_SNAP_BEGIN || - inStatus_i1==SYD_B_SNAP_SINGLE || inStatus_i1==SYD_B_SNAP_END; - if (pSChan->inStatus[i] == SYD_B_SAMPLED) { - if (pSChan->sync == SYD_SY_NONF) - discard = 1; - else if (inStatus_i1 == SYD_B_MISSING || full_i1) { - if (TsCmpStampsLE(&BUFi1TS, &pSspec->sampleTs)) - discard = 1; - } - } - else if (pSChan->inStatus[i] == SYD_B_MISSING) { - if (pSChan->sync == SYD_SY_NONF && - TsCmpStampsLE(&BUFiTS, &pSspec->sampleTs)) { - discard = 1; - } - else if (full_i1) { - if (TsCmpStampsLE(&BUFi1TS, &pSspec->sampleTs)) - discard = 1; - } - else if (inStatus_i1 == SYD_B_MISSING) - discard = 1; - } - if (discard) { - pSChan->inStatus[i] = SYD_B_EMPTY; - if (i == pSChan->lastInBuf) { - pSChan->lastInBuf = -1; - pSChan->firstInBuf = -1; - } - else - pSChan->firstInBuf = NEXT_INBUF(pSChan, i); - } - } - } -/*----------------------------------------------------------------------------- -* now try to get 2 buffers of input data (except for CA), then check for -* zero time stamps. If a zero time stamp is found, it is set to 1 -* second past the epoch. (This is done because a lot of the code depends -* on non-zero time stamp as a way of detecting valid data.) -*----------------------------------------------------------------------------*/ - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSspec->type != SYD_TY_CA) { - if (pSChan->firstInBuf < 0) - stat = (pSspec->pFunc)(pSspec, pSChan, SYD_FC_READ, NULL); - if (pSChan->firstInBuf == pSChan->lastInBuf) - stat = (pSspec->pFunc)(pSspec, pSChan, SYD_FC_READ, NULL); - -skipSecondRead: - ; - } - if ((i = pSChan->firstInBuf) >= 0) { - if (BUFiTS.secPastEpoch == 0) - BUFiTS.secPastEpoch = 86401; - i = NEXT_INBUF(pSChan, i); - if (i >= 0 && BUFiTS.secPastEpoch == 0) - BUFiTS.secPastEpoch = 86401; - } - if (pSspec->type == SYD_TY_SSF) - break; - } -} - -/*+/subr********************************************************************** -* NAME sydInputReset - reset synchronous sample buffers for channels -* -* DESCRIPTION -* This routine flags as EMPTY the input buffers for the channels in a -* synchronous set spec. Several routines are available: -* -* sydInputReset flags as empty all buffers for all channels -* This routine is appropriate to use after a -* positioning operation, since such an operation -* invalidates both FULL and SAMPLED buffers. -* -* sydInputResetKeepNewest flags as empty all buffers except the -* newest one, which is flagged as SAMPLED -* This routine is primarily intended for use with -* Channel Access. Keeping the newest buffer and -* flagging it as SAMPLED allows: a) using it if -* no new value comes in; or b) throwing it away -* if a new value does come in. -* -* sydInputResetSampled flags as empty only those buffers which -* are flagged as SAMPLED -* This routine is appropriate to use between -* successive retrievals. Since -* there is no "gap" between retrievals, the FULL -* buffers must be available to the next retrieval. -* Making SAMPLED buffers available for the next -* retrieval could result in the next retrieval -* having the same retrieval time stamp as the -* prior retrieval. -* -* RETURNS -* S_syd_OK -* -* BUGS -* o text -* -* NOTES -* 1. For retrievals from Channel Access, sydInputReset retains the -* newest buffer for filled channels. -* -*-*/ -void -sydInputReset(pSspec) -SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */ -{ - SYD_CHAN *pSChan; - int i; - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - i = pSChan->firstInBuf; - while (i >= 0 && i != pSChan->lastInBuf) { - pSChan->inStatus[i] = SYD_B_EMPTY; - i = NEXT_INBUF(pSChan, i); - pSChan->firstInBuf = i; - } - if ((i=pSChan->firstInBuf) >= 0) { - if (pSspec->type == SYD_TY_CA && pSChan->sync == SYD_SY_FILLED) - pSChan->inStatus[i] = SYD_B_FULL; - else { - pSChan->inStatus[i] = SYD_B_EMPTY; - pSChan->firstInBuf = pSChan->lastInBuf = -1; - } - } - pSChan->sampInBuf = -1; - } - pSspec->sampleTs.secPastEpoch = 0; -} - -/*+/subr********************************************************************** -* NAME sydInputResetKeepNewest -* -*-*/ -void -sydInputResetKeepNewest(pSspec) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -{ - SYD_CHAN *pSChan; - int i; - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - i = pSChan->firstInBuf; - while (i >= 0 && i != pSChan->lastInBuf) { - pSChan->inStatus[i] = SYD_B_EMPTY; - i = NEXT_INBUF(pSChan, i); - pSChan->firstInBuf = i; - } - if ((i=pSChan->firstInBuf) > 0) - pSChan->inStatus[i] = SYD_B_SAMPLED; - pSChan->sampInBuf = -1; - } - pSspec->sampleTs.secPastEpoch = 0; -} - -/*+/subr********************************************************************** -* NAME sydInputResetSampled -* -*-*/ -void -sydInputResetSampled(pSspec) -SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */ -{ - SYD_CHAN *pSChan; - int i; - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - i = pSChan->firstInBuf; - while (i >= 0) { - if (pSChan->inStatus[i] == SYD_B_SAMPLED) { - pSChan->inStatus[i] = SYD_B_EMPTY; - if (pSChan->lastInBuf == i) { - pSChan->lastInBuf = -1; - pSChan->firstInBuf = -1; - i = -1; - } - else if (pSChan->firstInBuf == i) - pSChan->firstInBuf = NEXT_INBUF(pSChan, i); - } - if (i == pSChan->lastInBuf) - i = -1; /* leave the loop */ - else - i = NEXT_INBUF(pSChan, i); - } - pSChan->sampInBuf = -1; - } - pSspec->sampleTs.secPastEpoch = 0; -} - -/*+/subr********************************************************************** -* NAME sydInputStoreInSet - store a sample into the sample set -* -* DESCRIPTION -* Stores a sample acquired by sydInputGet into the next available -* sample set buffer. Flags for the sample set buffer are set -* appropriately. The minDataVal and maxDataVal for the channel -* are updated (unless the alarm severity indicates INVALID). -* -* If a test condition has been established by sydTestAddFromText, -* the condition is tested. If the condition is false, then the -* sample isn't stored. -* -* If the `ignorePartial' flag is set, then some special processing -* is done to avoid losing interesting status information for -* synchronous channels. -* -* RETURNS -* void -* -* BUGS -* o text -* -* NOTES -* 1. If the retrieval source is Channel Access, and if the time stamp -* for this sample is earlier than the previous sample, then this -* sample is ignored. -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -void -sydInputStoreInSet(pSspec, ignorePartial) -SYD_SPEC *pSspec; -int ignorePartial; /* I 0,1 to store,ignore partial samples */ -{ - int sub; /* subscript of sample */ - chtype type; - long stat; - SYD_CHAN *pSChan; - int i, i1, el; - int useVal; /* indicates if sample data is to be stored */ - short alStat, alSev; - int ignore=0; - -#define Si pSChan->inStatus[i] -#define Si1 pSChan->inStatus[i1] - - sub = pSspec->lastData; - if (ignorePartial && pSspec->partial) - ignore = 1; - else if (!sydTest(pSspec)) - ignore = 1; - else if (sub >= 0 && pSspec->type == SYD_TY_CA && - TsCmpStampsLE(&pSspec->sampleTs, &pSspec->pTimeStamp[sub])) { - ignore = 1; - } - if (ignore) { - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - i = pSChan->sampInBuf; - if (i != pSChan->lastInBuf) { - i1 = i + 1; - if (i1 >= pSChan->nInBufs) - i1 = 0; - if (Si1==SYD_B_MISSING || Si1==SYD_B_EOF || Si1==SYD_B_EMPTY) - i1 = -1; - } - else - i1 = -1; - if (i >= 0) { - if (i1 >= 0) { - if (Si == SYD_B_RESTART) - pSChan->inStatus[i1] = SYD_B_RESTART; - else if (Si == SYD_B_SNAP_BEGIN) { - if (Si1 == SYD_B_SNAP_END) - pSChan->inStatus[i1] = SYD_B_SNAP_SINGLE; - else if (Si1 == SYD_B_SNAP_SINGLE) - pSChan->inStatus[i1] = SYD_B_SNAP_BEGIN; - } - } - if (Si != SYD_B_MISSING) - pSChan->inStatus[i] = SYD_B_SAMPLED; - } - } - return; - } - if (++pSspec->lastData >= pSspec->dataDim) - pSspec->lastData = 0; - sub = pSspec->lastData; - - pSspec->pDeltaSec[sub] = pSspec->sampleSec; - pSspec->pTimeStamp[sub] = pSspec->sampleTs; - pSspec->pPartial[sub] = pSspec->partial; - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->pData == NULL || pSChan->dataChan == 0) - ; /* no action if no malloc's or if not data channel */ - else if (pSChan->dataChan) { - bzero((char *)&pSChan->pFlags[sub], sizeof(*pSChan->pFlags)); - pSChan->pDataCodeL[sub] = '#'; - pSChan->pDataCodeR[sub] = ' '; - type = pSChan->dbrType; - if ((i = pSChan->sampInBuf) < 0) { - pSChan->pFlags[sub].missing = 1; - pSChan->pDataCodeL[sub] = 'M'; - } - else if (pSChan->inStatus[i] == SYD_B_EOF) { - pSChan->pFlags[sub].missing = 1; - pSChan->pFlags[sub].eof = 1; - pSChan->pDataCodeL[sub] = 'M'; - pSChan->pDataCodeR[sub] = 'E'; - } - else if (pSChan->inStatus[i] == SYD_B_MISSING) { - pSChan->pFlags[sub].missing = 1; - pSChan->pDataCodeL[sub] = 'M'; - pSChan->pDataCodeR[sub] = 'N'; - } - else { -/*----------------------------------------------------------------------------- -* store the channel's alarm status and severity -*----------------------------------------------------------------------------*/ - pSChan->pDataAlStat[sub] = alStat = - pSChan->pInBuf[i]->tstrval.status; - pSChan->pDataAlSev[sub] = alSev = - pSChan->pInBuf[i]->tstrval.severity; -/*----------------------------------------------------------------------------- -* check out the channel's status, storing it into the status array. -* If the status indicates a bad value, reset the useVal flag, so -* that the value won't be used in computing the maximum and minimum -* for the channel. -*----------------------------------------------------------------------------*/ - useVal = 1; - if (alSev == INVALID_ALARM) { - useVal = 0; - pSChan->pDataCodeL[sub] = 'I'; - } - else if (pSChan->reused) { - pSChan->pFlags[sub].filled = 1; - pSChan->pDataCodeL[sub] = 'F'; - } - else if (pSChan->inStatus[i] == SYD_B_SNAP_BEGIN) { - pSChan->pFlags[sub].restart = 1; - pSChan->pFlags[sub].snapstart = 1; - pSChan->pDataCodeL[sub] = 'S'; - } - else if (pSChan->inStatus[i] == SYD_B_SNAP_SINGLE) { - pSChan->pFlags[sub].restart = 1; - pSChan->pFlags[sub].snapstart = 1; - pSChan->pFlags[sub].snapend = 1; - pSChan->pDataCodeL[sub] = 'S'; - } - else if (pSChan->inStatus[i] == SYD_B_SNAP_END) { - pSChan->pFlags[sub].ok = 1; - pSChan->pFlags[sub].snapend = 1; - pSChan->pDataCodeL[sub] = 'O'; - } - else if (pSChan->inStatus[i] == SYD_B_RESTART) { - pSChan->pFlags[sub].restart = 1; - pSChan->pDataCodeL[sub] = 'R'; - } - else { - pSChan->pFlags[sub].ok = 1; - pSChan->pDataCodeL[sub] = 'O'; - } - if (alStat == NO_ALARM) - ; /* no action */ - else if (alStat == READ_ALARM) - pSChan->pDataCodeR[sub] = 'R'; - else if (alStat == HIHI_ALARM) - pSChan->pDataCodeR[sub] = 'H'; - else if (alStat == HIGH_ALARM) - pSChan->pDataCodeR[sub] = 'h'; - else if (alStat == LOLO_ALARM) - pSChan->pDataCodeR[sub] = 'L'; - else if (alStat == LOW_ALARM) - pSChan->pDataCodeR[sub] = 'l'; - else if (alSev == MAJOR_ALARM) - pSChan->pDataCodeR[sub] = 'M'; - else if (alSev == MINOR_ALARM) - pSChan->pDataCodeR[sub] = 'm'; -/*----------------------------------------------------------------------------- -* now go ahead and store the sample into the set. Also adjust the -* maximum and minimum, as needed. -*----------------------------------------------------------------------------*/ - if (type == DBR_TIME_FLOAT) { - float *pSrc, *pDest; - pSrc = &pSChan->pInBuf[i]->tfltval.value; - pDest = ((float *)pSChan->pData) + sub * pSChan->elCount; - if (useVal && pSChan->minMaxNeedInit) { - pSChan->maxDataVal = pSChan->minDataVal = (double)*pSrc; - pSChan->minMaxNeedInit = 0; - } - for (el=0; el<(int) pSChan->elCount; el++) { - if (useVal) { - if ((double)*pSrc > pSChan->maxDataVal) - pSChan->maxDataVal = (double)*pSrc; - if ((double)*pSrc < pSChan->minDataVal) - pSChan->minDataVal = (double)*pSrc; - } - *pDest++ = *pSrc++; - } - } - else if (type == DBR_TIME_SHORT) { - short *pSrc, *pDest; - double dbl; - pSrc = &pSChan->pInBuf[i]->tshrtval.value; - pDest = ((short *)pSChan->pData) + sub * pSChan->elCount; - if (useVal && pSChan->minMaxNeedInit) { - if (pSChan->isRVAL) - dbl = (double)(*(unsigned short *)pSrc); - else - dbl = (double)(*pSrc); - pSChan->maxDataVal = pSChan->minDataVal = dbl; - pSChan->minMaxNeedInit = 0; - } - for (el=0; el<(int) pSChan->elCount; el++) { - if (useVal) { - if (pSChan->isRVAL) - dbl = (double)(*(unsigned short *)pSrc); - else - dbl = (double)(*pSrc); - if (dbl > pSChan->maxDataVal) - pSChan->maxDataVal = dbl; - if (dbl < pSChan->minDataVal) - pSChan->minDataVal = dbl; - } - *pDest++ = *pSrc++; - } - } - else if (type == DBR_TIME_DOUBLE) { - double *pSrc, *pDest; - pSrc = &pSChan->pInBuf[i]->tdblval.value; - pDest = ((double *)pSChan->pData) + sub * pSChan->elCount; - if (useVal && pSChan->minMaxNeedInit) { - pSChan->maxDataVal = pSChan->minDataVal = *pSrc; - pSChan->minMaxNeedInit = 0; - } - for (el=0; el<(int) pSChan->elCount; el++) { - if (useVal) { - if (*pSrc > pSChan->maxDataVal) - pSChan->maxDataVal = *pSrc; - if (*pSrc < pSChan->minDataVal) - pSChan->minDataVal = *pSrc; - } - *pDest++ = *pSrc++; - } - } - else if (type == DBR_TIME_LONG) { - long *pSrc, *pDest; - double dbl; - pSrc = &pSChan->pInBuf[i]->tlngval.value; - pDest = ((long *)pSChan->pData) + sub * pSChan->elCount; - if (useVal && pSChan->minMaxNeedInit) { - if (pSChan->isRVAL) - dbl = (double)(*(unsigned long *)pSrc); - else - dbl = (double)(*pSrc); - pSChan->maxDataVal = pSChan->minDataVal = (double)*pSrc; - pSChan->minMaxNeedInit = 0; - } - for (el=0; el<(int) pSChan->elCount; el++) { - if (useVal) { - if (pSChan->isRVAL) - dbl = (double)(*(unsigned long *)pSrc); - else - dbl = (double)(*pSrc); - if (dbl > pSChan->maxDataVal) - pSChan->maxDataVal = dbl; - if (dbl < pSChan->minDataVal) - pSChan->minDataVal = dbl; - } - *pDest++ = *pSrc++; - } - } - else if (type == DBR_TIME_STRING) { - char *pSrc, *pDest; - pSrc = pSChan->pInBuf[i]->tstrval.value; - pDest = ((char *)pSChan->pData) + - sub * db_strval_dim * pSChan->elCount; - for (el=0; el<(int) pSChan->elCount; el++) { - strcpy(pDest, pSrc); - pDest += db_strval_dim; - pSrc += db_strval_dim; - } - } - else if (type == DBR_TIME_CHAR) { - unsigned char *pSrc, *pDest; - pSrc = &pSChan->pInBuf[i]->tchrval.value; - pDest = ((unsigned char *)pSChan->pData) + - sub * pSChan->elCount; - if (useVal && pSChan->minMaxNeedInit) { - pSChan->maxDataVal = pSChan->minDataVal = (double)*pSrc; - pSChan->minMaxNeedInit = 0; - } - for (el=0; el<(int) pSChan->elCount; el++) { - if (useVal) { - if ((double)*pSrc > pSChan->maxDataVal) - pSChan->maxDataVal = (double)*pSrc; - if ((double)*pSrc < pSChan->minDataVal) - pSChan->minDataVal = (double)*pSrc; - } - *pDest++ = *pSrc++; - } - } - else if (type == DBR_TIME_ENUM) { - unsigned short *pSrc, *pDest; - pSrc = &pSChan->pInBuf[i]->tenmval.value; - pDest = ((unsigned short *)pSChan->pData) + sub * pSChan->elCount; - if (useVal && pSChan->minMaxNeedInit) { - pSChan->maxDataVal = pSChan->minDataVal = (double)*pSrc; - pSChan->minMaxNeedInit = 0; - } - for (el=0; el<(int) pSChan->elCount; el++) { - if (useVal) { - if ((double)*pSrc > pSChan->maxDataVal) - pSChan->maxDataVal = (double)*pSrc; - if ((double)*pSrc < pSChan->minDataVal) - pSChan->minDataVal = (double)*pSrc; - } - *pDest++ = *pSrc++; - } - } - else - assertAlways(0); - } - if (i >= 0 && pSChan->inStatus[i] != SYD_B_MISSING) - pSChan->inStatus[i] = SYD_B_SAMPLED; - pSChan->restrictMaxDataVal = pSChan->maxDataVal; - pSChan->restrictMinDataVal = pSChan->minDataVal; - } - } - - if (pSspec->firstData < 0 || pSspec->firstData == pSspec->lastData) { - if (++pSspec->firstData >= pSspec->dataDim) - pSspec->firstData = 0; - pSspec->restrictFirstData = pSspec->firstData; - } - if (pSspec->sampleCount < pSspec->dataDim) - pSspec->sampleCount++; - pSspec->restrictLastData = pSspec->lastData; -} - -/*+/subr********************************************************************** -* NAME sydInputSync - synchronize input buffers with disk for `by channel' -* -* DESCRIPTION -* Get in sync with an archiver `by channel' data file, which may -* have had information written to it since the sydOpen call or -* the last sydInputSync call. -* -* RETURNS -* S_syd_OK, or -* other error code -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydInputSync(pSspec) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -{ - long retStat=S_syd_OK; - long stat; - - assert(pSspec != NULL); - - if (pSspec->type != SYD_TY_CF) - return S_syd_OK; - stat = (pSspec->pFunc)(pSspec, NULL, SYD_FC_READ_SYNC, NULL); - if (stat != S_syd_OK) - retStat = stat; - return retStat; -} - -/*+/subr********************************************************************** -* NAME sydMonitorStart - start monitoring channels for user monitoring -* -* DESCRIPTION -* For each channel in the sync set spec, add a Channel Access monitor. -* The monitor will use the deadband specified by the SYD_ATTR_DEADBAND -* attribute (which defaults to .ADEL). -* -* RETURNS -* S_syd_OK -* -* SEE ALSO -* sydChanOpen, sydSetAttr, sydMonitorStop -* -*-*/ -long -sydMonitorStart(pSspec) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -{ - long retStat=S_syd_OK;/* return status to caller */ - long stat; /* status return from calls */ - SYD_CHAN *pSChan; /* pointer to channel in Sspec */ - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) - stat = (pSspec->pFunc)(pSspec, pSChan, SYD_FC_READ, NULL); - return retStat; -} - -/*+/subr********************************************************************** -* NAME sydMonitorStop - stop monitoring channels for user monitoring -* -* DESCRIPTION -* For each channel in the sync set spec, delete the Channel Access -* monitor. If the sync set spec isn't being monitored by a user -* routine, this routine does nothing. -* -* RETURNS -* S_syd_OK -* -* SEE ALSO -* sydChanOpen, sydSetAttr, sydMonitorStart -* -*-*/ -long -sydMonitorStop(pSspec) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -{ - long retStat=S_syd_OK;/* return status to caller */ - long stat; /* status return from calls */ - SYD_CHAN *pSChan; /* pointer to channel in Sspec */ - - if (pSspec->monFn != NULL) { - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) - stat = (pSspec->pFunc)(pSspec, pSChan, SYD_FC_STOP, NULL); - } - return retStat; -} - -/*+/macro********************************************************************* -* NAME sydOpen - create and initialize an empty synchronous set spec -* -* DESCRIPTION -* This routine builds an empty synchronous set spec structure. In -* order to use the SYD_SPEC, channels for synchronous samples must -* be specified. Retrieval will be for synchronous samples of data, -* in which all channels have the same time stamp; retrieval begins -* with the oldest data available and continues to the most recent. -* Several versions of this routine are available, corresponding -* to the source of the data: -* -* sydOpenCA(&pSspec, NULL) init for Channel Access -* sydOpenCF(&pSspec, filePath) init for "by channel" file -* sydOpenSSF(&pSspec, filePath) init for "sample set" file -* -* RETURNS -* S_syd_OK, or -* S_syd_noMem if memory isn't available to store set descriptor -* -* BUGS -* o should set up, in the sync set spec, the number of input buffers, -* rather than having that job be done in sydChanOpen. -* -* SEE ALSO -* sydChanOpen, sydAddTest -* sydInputGet, sydMonitorStart -* -* EXAMPLE -* -*-*/ -long -sydOpen(ppSspec) -SYD_SPEC **ppSspec; /* O pointer to synchronous set spec pointer */ -{ - assert(ppSspec != NULL); - assert(*ppSspec != NULL); - - (*ppSspec)->pChanHead = (*ppSspec)->pChanTail = NULL; - (*ppSspec)->pAccept = NULL; - (*ppSspec)->refTs.secPastEpoch = (*ppSspec)->refTs.nsec = 0; - (*ppSspec)->priorTs = (*ppSspec)->refTs; - (*ppSspec)->sampleTs = (*ppSspec)->refTs; - (*ppSspec)->chanCount = 0; - (*ppSspec)->disconCount = 0; - (*ppSspec)->needGrCount = 0; - (*ppSspec)->eofCount = 0; - (*ppSspec)->dataDim = 0; - (*ppSspec)->sampleCount = 0; - (*ppSspec)->pDeltaSec = NULL; - (*ppSspec)->pTimeStamp = NULL; - (*ppSspec)->statDim = (*ppSspec)->statCount = 0; - (*ppSspec)->pStatDeltaSec = NULL; - (*ppSspec)->pStatTimeStamp = NULL; - (*ppSspec)->pStatPopCount = NULL; - (*ppSspec)->pPartial = NULL; - (*ppSspec)->lastData = (*ppSspec)->firstData = -1; - (*ppSspec)->restrictLastData = (*ppSspec)->restrictFirstData = -1; - (*ppSspec)->restrictDeltaSecSubtract = 0.; - (*ppSspec)->roundNsec = 0; - (*ppSspec)->deadband = DBE_LOG; - (*ppSspec)->useStats = (*ppSspec)->useMeans = 0; - (*ppSspec)->monFn = NULL; - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydPosition - position the data file -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o doesn't report EOF if that condition occurs -* o doesn't provide a way for the caller to find out the actual position -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydPosition(pSspec, pStamp) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -TS_STAMP *pStamp; /* I stamp at which to position; NULL to rewind */ -{ - SYD_CHAN *pSChan; - long stat; - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - stat = (pSspec->pFunc)(pSspec, pSChan, SYD_FC_POSITION, pStamp); - if (pSspec->type == SYD_TY_SSF) - break; - } - sydInputReset(pSspec); - pSspec->sampleTs.secPastEpoch = pSspec->sampleTs.nsec = 0; - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydSampleExport -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o options should be #defined symbols -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSampleExport(pSspec, out, option, samp) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -FILE *out; /* IO stream pointer for output */ -int option; /* I filtering option */ - /* 1 spreadsheet; delta time and values */ - /* 2 spreadsheet; delta time and values and status */ - /* 3 spreadsheet; delta time, count, and values */ - /* 4 spreadsheet; as for 3, with status */ -int samp; /* I sample number in synchronous set */ -{ - SYD_CHAN *pSChan; /* pointer to channel in synchronous set */ - char stampText[28]; - int i; - -/*----------------------------------------------------------------------------- -* generate headings, depending on option: -* 1==> "mm/dd/yy hh:mm:ss.msc" -* date time name1 name2 ... -* stamp seconds egu egu ... -* -* 2==> "mm/dd/yy hh:mm:ss.msc" -* date time stat name1 stat name2 ... -* stamp seconds stat egu stat egu ... -* -* 3==> "mm/dd/yy hh:mm:ss.msc" -* date time nEl name1 nEl name2 ... -* stamp seconds nEl egu nEl egu ... -* -* 4==> "mm/dd/yy hh:mm:ss.msc" -* date time stat nEl name1 stat nEl name2 ... -* stamp seconds stat nEl egu stat nEl egu ... -*----------------------------------------------------------------------------*/ - if (samp == pSspec->restrictFirstData) { - (void)fprintf(out, "\"%s\"\n\"date\"\t\"time\"", tsStampToText( - &pSspec->restrictRefTs, TS_TEXT_MMDDYY, stampText)); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan = pSChan->pNext) { - if (pSChan->dataChan) { - if (option == 2 || option == 4) - (void)fprintf(out, "\t\"stat\""); - if (option == 3 || option == 4) - (void)fprintf(out, "\t\"nEl\""); - (void)fprintf(out, "\t\"%s\"", pSChan->name); - } - } - (void)fprintf(out, "\n\"stamp\"\t\"seconds\""); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan = pSChan->pNext) { - if (pSChan->dataChan) { - if (option == 2 || option == 4) - (void)fprintf(out, "\t\"stat\""); - if (option == 3 || option == 4) - (void)fprintf(out, "\t\"nEl\""); - (void)fprintf(out, "\t\"%s\"", pSChan->EGU); - } - } - (void)fprintf(out, "\n"); - } - -/*----------------------------------------------------------------------------- -* print the value for each channel for this sample. -*----------------------------------------------------------------------------*/ - tsStampToText(&pSspec->pTimeStamp[samp], TS_TEXT_MMDDYY, stampText); - (void)fprintf(out, "\"%s\"%c%.3f", stampText,'\t', - pSspec->pDeltaSec[samp] - pSspec->restrictDeltaSecSubtract); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->dataChan) { - if (option == 1) - sydSamplePrint1(pSChan, out, '\t', USE_QUO, 0, samp); - else if (option == 2) - sydSamplePrint1(pSChan, out, '\t', PRE_FL|USE_QUO, 0, samp); - else if (option == 3) - sydSamplePrint1(pSChan, out, '\t', USE_QUO|SHOW_AR, 0, samp); - else if (option == 4) - sydSamplePrint1(pSChan,out,'\t',PRE_FL|USE_QUO|SHOW_AR,0,samp); - } - } - (void)fprintf(out, "\n"); - pSChan = pSspec->pChanHead; - if (pSChan->pFlags[samp].snapend && !pSChan->pFlags[samp].snapstart) - (void)fprintf(out, "\n"); /* blank line after snapshot */ -} - -/*+/subr********************************************************************** -* NAME sydSampleExportStats -* -* DESCRIPTION -* If the `useMeans' flag is set in conjunction with `useStats', then -* only the means are printed. -* -* RETURNS -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSampleExportStats(pSspec, out, snap) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -FILE *out; /* IO stream pointer for output */ -int snap; /* I snapshot number in synchronous set */ -{ - SYD_CHAN *pSChan; /* pointer to channel in synchronous set */ - char stampText[28]; - double dblVal; - -/*----------------------------------------------------------------------------- -* generate heading -* "mm/dd/yy hh:mm:ss.msc" -* date time sample name1 egu name2 egu ... -* stamp seconds count mean stdDev mean stdDev ... -* -* "mm/dd/yy hh:mm:ss.msc" -* date time sample name1 name2 ... -* stamp seconds count egu egu ... -*----------------------------------------------------------------------------*/ - if (snap == 0 && pSspec->useMeans == 0) { - (void)fprintf(out, "\"%s\"\n\"date\"\t\"time\"\t\"sample\"", - tsStampToText(&pSspec->restrictRefTs,TS_TEXT_MMDDYY,stampText)); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan = pSChan->pNext) { - if (pSChan->dataChan) - (void)fprintf(out,"\t\"%s\"\t\"%s\"",pSChan->name,pSChan->EGU); - } - (void)fprintf(out, "\n\"stamp\"\t\"seconds\"\t\"count\""); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan = pSChan->pNext) { - if (pSChan->dataChan) - (void)fprintf(out, "\t\"mean\"\t\"stdDev\""); - } - (void)fprintf(out, "\n"); - } - if (snap == 0 && pSspec->useMeans) { - (void)fprintf(out, "\"%s\"\n\"date\"\t\"time\"\t\"sample\"", - tsStampToText(&pSspec->restrictRefTs,TS_TEXT_MMDDYY,stampText)); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan = pSChan->pNext) { - if (pSChan->dataChan) - (void)fprintf(out,"\t\"%s\"",pSChan->name); - } - (void)fprintf(out, "\n\"stamp\"\t\"seconds\"\t\"count\""); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan = pSChan->pNext) { - if (pSChan->dataChan) - (void)fprintf(out,"\t\"%s\"",pSChan->EGU); - } - (void)fprintf(out, "\n"); - } - -/*----------------------------------------------------------------------------- -* print the statistics for each channel for this snapshot. -*----------------------------------------------------------------------------*/ - tsStampToText(&pSspec->pStatTimeStamp[snap], TS_TEXT_MMDDYY, stampText); - (void)fprintf(out, "\"%s\"\t%.3f", stampText, - pSspec->pStatDeltaSec[snap] - pSspec->restrictDeltaSecSubtract); - (void)fprintf(out, "\t%d", pSspec->pStatPopCount[snap]); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->dataChan) { - dblVal = pSChan->pStats[snap].mean; - if (dblVal == 0.) - (void)fprintf(out, "\t0"); - else if (dblVal > -.1 && dblVal < .1) - (void)fprintf(out, "\t%.*E", pSChan->precision, dblVal); - else - (void)fprintf(out, "\t%.*f", pSChan->precision, dblVal); - if (pSspec->useMeans == 0) { - dblVal = pSChan->pStats[snap].stdDev; - if (dblVal == 0.) - (void)fprintf(out, "\t0"); - else if (dblVal > -.1 && dblVal < .1) - (void)fprintf(out, "\t%.*E", pSChan->precision, dblVal); - else - (void)fprintf(out, "\t%.*f", pSChan->precision, dblVal); - } - } - } - (void)fprintf(out, "\n"); -} - -/*+/internal****************************************************************** -* NAME widthPrint -* -*-*/ -static void -widthPrint(out, pre, text, width, pass, pMore) -FILE *out; -char *pre, *text; -int width, pass; -int *pMore; -{ - int L=strlen(text); - int sub=pass*width; - - if (pre[0] != '\0') - (void)fprintf(out, "%s", pre); - if (sub < L) { - if (pass == 0 && L <= width) - (void)fprintf(out, "%*.*s", width, width, &text[sub]); - else - (void)fprintf(out, "%-*.*s", width, width, &text[sub]); - } - else - (void)fprintf(out, "%*s", width, " "); - if (sub + width < L) - *pMore = 1; -} - -/*+/subr********************************************************************** -* NAME sydSamplePrint -* -* DESCRIPTION -* Print the values for all channels in a particular sample. Various -* aspects of formatting can be specified with arguments, including -* the printing of column headings, number of columns, column width, -* and the inclusion of printer control characters. -* -* For array channels, only the first value of the array is printed -* on the line with the time stamp--the full array is printed on -* following lines. -* -* RETURNS -* S_syd_OK -* -* BUGS -* o -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSamplePrint(pSspec, out, formatFlag, headerFlag, nCol, colWidth, samp) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -FILE *out; /* I stream pointer for output */ -int formatFlag; /* I ==1 causes page formatting for printing */ -int headerFlag; /* I ==1 causes printing of column headings */ -int nCol; /* I >0 specifies number of table columns, - with folded lines to accomodate excess - channels */ -int colWidth; /* I >0 specifies column width, in characters */ -int samp; /* I sample number in synchronous set */ -{ - SYD_CHAN *pSChan; /* pointer to channel in synchronous set */ - char stampText[28]; - int i, tmpWid; - int more, pass, colNum; - SYD_CHAN *pNext; - - if (colWidth < 1) - colWidth = 10; - -/*----------------------------------------------------------------------------- -* print a heading line with channel names; if this isn't the first page, -* put a ^L prior to the heading. -*----------------------------------------------------------------------------*/ -#define FMT_INDENT if (formatFlag) (void)fprintf(out, " ") -#define SKIP_STAMP (void)fprintf(out, " %21s", " ") - - if (headerFlag) { - if (formatFlag) { - if (samp != pSspec->restrictFirstData) - (void)fprintf(out, "\f"); - (void)fprintf(out, "\n\n"); /* 2 line top margin */ - } - pNext = pSspec->pChanHead; - tmpWid = colWidth; - if (tmpWid <= 2) - tmpWid = 1; - while (1) { - pass = 0; - while (1) { - more = 0; - pSChan = pNext; - FMT_INDENT; SKIP_STAMP; - for (colNum=0; colNumdataChan) - widthPrint(out, " ", pSChan->name,tmpWid,pass,&more); - pSChan = pSChan->pNext; - if (pSChan == NULL) - break; - } - (void)fprintf(out, "\n"); - if (more == 0) - break; - pass++; - } - if (tmpWid > 2) { - pass = 0; - while (1) { - more = 0; - pSChan = pNext; - FMT_INDENT; SKIP_STAMP; - for (colNum=0; colNumdataChan) - widthPrint(out," ",pSChan->EGU,tmpWid,pass,&more); - pSChan = pSChan->pNext; - if (pSChan == NULL) - break; - } - (void)fprintf(out, "\n"); - if (more == 0) - break; - pass++; - } - } - (void)fprintf(out, "\n"); - if ((pNext = pSChan) == NULL) - break; - } - } -/*----------------------------------------------------------------------------- -* print the value for each channel for this sample. Print the status -* flags following values, but print only the first element for array -* channels. -*----------------------------------------------------------------------------*/ - FMT_INDENT; - if (pSspec->pPartial[samp]) (void)fprintf(out, "*"); - else (void)fprintf(out, " "); - (void)fprintf(out, " %s", tsStampToText( - &pSspec->pTimeStamp[samp], TS_TEXT_MMDDYY, stampText)); - colNum = 0; - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->dataChan) { - if (colNum >= nCol) { - (void)fprintf(out, "\n"); - FMT_INDENT; SKIP_STAMP; - colNum = 0; - } - sydSamplePrint1(pSChan, out, ' ', POST_FL|ENF_WID, colWidth, samp); - colNum++; - } - } - (void)fprintf(out, "\n"); -/*----------------------------------------------------------------------------- -* if any of the channels is an array channel, print the full array following -* the time-stamped line (which had only the first value) -*----------------------------------------------------------------------------*/ - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->dataChan && pSChan->elCount > 1) { - (void)fprintf(out, "%s", pSChan->name); - for (i=0; i<(int) pSChan->elCount; i++) { - if (i%nCol == 0) - (void)fprintf(out, "\n%5d", i); - (void)fputc(' ', out); - sydSamplePrintVal(out, pSChan, samp, i, ENF_WID, colWidth); - } - (void)fprintf(out, "\n"); - } - } - - return S_syd_OK; -} - -/*+/internal****************************************************************** -* NAME sydSamplePrint1 - print a value for a channel -* -* DESCRIPTION -* -* RETURNS -* void -* -*-*/ -static void -sydSamplePrint1(pSChan, out, sep, flags, colWidth, sampNum) -SYD_CHAN *pSChan; /* I pointer to sync channel */ -FILE *out; /* I file pointer for writing value */ -char sep; /* I character to use a a prefix for each field, - as a separator; usually ' ' or '\t' */ -int flags; /* I flags, or'd together, or 0: - PRE_FL print status flag, prior to value - POST_FL print status flag, after value - SHOW_AR print all array values, preceded by - array element count - ENF_WID enforce column width - USE_QUO put quotes around text items - */ -int colWidth; /* I >0 specifies column width, in characters; - == 2 requests only printing status code*/ -int sampNum; /* I sample number in sync set */ -{ - int i; - chtype type; /* type of value */ - char text[100]; - char *special; /* != NULL says print "msg", not value */ - - type = pSChan->dbrType; - - if (colWidth == 2) { - if (pSChan->pData == NULL) - (void)fprintf(out, " %c", sep,'M'); - else - (void)fprintf(out, " %c", pSChan->pDataCodeL[sampNum]); - return; - } - if (flags&PRE_FL || flags&POST_FL) { - if (colWidth > 3) - colWidth -= 3; - } - - if (flags&PRE_FL) { - if (pSChan->pData == NULL) { - if (flags&USE_QUO) - (void)fprintf(out, "%c\"%c%c\"", sep,'M','D'); - else - (void)fprintf(out, "%c%c%c", sep,'M','D'); - } - else { - if (flags&USE_QUO) { - (void)fprintf(out, "%c\"%c%c\"", sep, - pSChan->pDataCodeL[sampNum], pSChan->pDataCodeR[sampNum]); - } - else { - (void)fprintf(out, "%c%c%c", sep, - pSChan->pDataCodeL[sampNum], pSChan->pDataCodeR[sampNum]); - } - } - } - (void)fputc(sep, out); - special = NULL; - if (pSChan->pData == NULL) - special = "no_data"; - else if (pSChan->pFlags[sampNum].eof) - special = "EOF"; - else if (pSChan->pFlags[sampNum].missing) - special = "no_data"; - else if (pSChan->pDataCodeL[sampNum] == 'I' && - flags&PRE_FL == 0 && flags&POST_FL == 0) { - special = "invalid"; - } - - if (special == NULL) { - if (flags&SHOW_AR) { - (void)fprintf(out, "%d", pSChan->elCount); - for (i=0; i<(int) pSChan->elCount; i++) { - (void)fputc(sep, out); - sydSamplePrintVal(out, pSChan, sampNum, i, flags, colWidth); - } - } - else - sydSamplePrintVal(out, pSChan, sampNum, 0, flags, colWidth); - } - else { - if (flags&SHOW_AR) - (void)fprintf(out, "1%c", sep); - if (flags&USE_QUO) { - if (flags&ENF_WID) - (void)fprintf(out, "\"%*.*s\"", colWidth, colWidth, special); - else - (void)fprintf(out, "\"%s\"", special); - } - else { - if (flags&ENF_WID) - (void)fprintf(out, "%*.*s", colWidth, colWidth, special); - else - (void)fprintf(out, "%s", special); - } - } - - if (flags&POST_FL) { - if (pSChan->pData == NULL) { - if (flags&USE_QUO) - (void)fprintf(out, "%c\"%c%c\"", sep,'M','D'); - else - (void)fprintf(out, "%c%c%c", sep,'M','D'); - } - else { - if (flags&USE_QUO) { - (void)fprintf(out, "%c\"%c%c\"", sep, - pSChan->pDataCodeL[sampNum], pSChan->pDataCodeR[sampNum]); - } - else { - (void)fprintf(out, "%c%c%c", sep, - pSChan->pDataCodeL[sampNum], pSChan->pDataCodeR[sampNum]); - } - } - } -} - -/*+/internal****************************************************************** -* NAME sydSamplePrintVal - print a single value -* -*-*/ -static void -sydSamplePrintVal(out, pSChan, sampNum, sub, flags, colWidth) -FILE *out; -SYD_CHAN *pSChan; -int sampNum; -int sub; /* subscript for array channels */ -int flags; -int colWidth; -{ - int myType=0; /* 0,1,2 for lng, dbl, str */ - chtype type; /* type of value */ - char text[100]; - long lngVal=0; - double dblVal=0.0; - char *strVal=NULL; - - type = pSChan->dbrType; - - if (type == DBR_TIME_STRING) { - myType = 2; - strVal = ((char *)pSChan->pData) + - sampNum * db_strval_dim * pSChan->elCount + sub * db_strval_dim; - } - else if (type == DBR_TIME_FLOAT) { - float *p; - myType = 1; - p = ((float *)pSChan->pData) + sampNum * pSChan->elCount + sub; - dblVal = (double)(*p); - } - else if (type == DBR_TIME_SHORT) { - short *p; - myType = 0; - p = ((short *)pSChan->pData) + sampNum * pSChan->elCount + sub; - if (pSChan->isRVAL) - lngVal = (long)(*(unsigned short *)p); - else - lngVal = (long)(*p); - } - else if (type == DBR_TIME_DOUBLE) { - double *p; - myType = 1; - p = ((double *)pSChan->pData) + sampNum * pSChan->elCount + sub; - dblVal = *p; - } - else if (type == DBR_TIME_LONG) { - long *p; - myType = 0; - p = ((long *)pSChan->pData) + sampNum * pSChan->elCount + sub; - if (pSChan->isRVAL) - lngVal = *(unsigned long *)p; - else - lngVal = *p; - } - else if (type == DBR_TIME_CHAR) { - char *p; - myType = 0; - p = ((char *)pSChan->pData) + sampNum * pSChan->elCount + sub; - lngVal = (long)(*p); - } - else if (type == DBR_TIME_ENUM) { - short *p; - myType = 0; - p = ((short *)pSChan->pData) + sampNum * pSChan->elCount + sub; - lngVal = (long)(*p); - if (lngVal < pSChan->grBuf.genmval.no_str) - myType = 2, strVal = pSChan->grBuf.genmval.strs[lngVal]; - } - - if (flags&ENF_WID) { - if (myType == 0) - strVal=text, cvtLngToTxt(text, colWidth, lngVal); - else if (myType == 1) - strVal=text,cvtDblToTxt(text, colWidth, dblVal, pSChan->precision); - (void)fprintf(out, "%*.*s", colWidth, colWidth, strVal); - } - else { - if (myType == 0) - (void)fprintf(out, "%*d", colWidth, lngVal); - else if (myType == 1) { - if (dblVal == 0.) - (void)fprintf(out, "0"); - else if (dblVal > -.1 && dblVal < .1) - (void)fprintf(out, "%*.*E",colWidth,pSChan->precision,dblVal); - else - (void)fprintf(out, "%*.*f",colWidth,pSChan->precision,dblVal); - } - else - (void)fprintf(out, "%*s", colWidth, strVal); - } -} - -/*+/internal****************************************************************** -* NAME sydSamplePrintStats -* -* DESCRIPTION -* -* RETURNS -* S_syd_OK -* -* BUGS -* o -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long sydSamplePrintStats(pSspec, out, formatFlag, headerFlag, nCol, colWidth, snap) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -FILE *out; /* I stream pointer for output */ -int formatFlag; /* I ==1 causes page formatting for printing */ -int headerFlag; /* I ==1 causes printing of column headings */ -int nCol; /* I >0 specifies number of table columns, - with folded lines to accomodate excess - channels */ -int colWidth; /* I >0 specifies column width, in characters */ -int snap; /* I snapshot number in synchronous set */ -{ - SYD_CHAN *pSChan; /* pointer to channel in synchronous set */ - char stampText[28]; - int i; - int prec; - char text[100]; - int more, pass, colNum; - SYD_CHAN *pNext; - - - if (colWidth < 6) - colWidth = 6; - -/*----------------------------------------------------------------------------- -* print a heading line with channel names; if this isn't the first page, -* put a ^L prior to the heading. -*----------------------------------------------------------------------------*/ - if (headerFlag) { - if (formatFlag) { - if (snap != 0) - (void)fprintf(out, "\f"); - (void)fprintf(out, "\n\n"); /* 2 line top margin */ - } -#undef SKIP_STAMP -#define SKIP_STAMP (void)fprintf(out, " %21s %4s", " ", " ") - pNext = pSspec->pChanHead; - while (1) { - pass = 0; - while (1) { - more = 0; - pSChan = pNext; - FMT_INDENT; SKIP_STAMP; - for (colNum=0; colNumdataChan) - widthPrint(out, " ", pSChan->name,colWidth,pass,&more); - if (pSChan->dataChan && pSspec->useMeans == 0) - widthPrint(out, " ", pSChan->EGU,colWidth,pass,&more); - pSChan = pSChan->pNext; - if (pSChan == NULL) - break; - } - (void)fprintf(out, "\n"); - if (more == 0) - break; - pass++; - } - if (pSspec->useMeans == 0) - (void)fprintf(out, "\n"); - if ((pNext = pSChan) == NULL) - break; - } - pSChan = pSspec->pChanHead; - FMT_INDENT; SKIP_STAMP; - for (colNum=0; colNumdataChan && pSspec->useMeans == 0) { - (void)fprintf(out, " %*s %*s", colWidth, "mean", - colWidth, "stdDev"); - } - else if (pSChan->dataChan && pSspec->useMeans) - (void)fprintf(out, " %*s", colWidth, pSChan->EGU); - pSChan = pSChan->pNext; - if (pSChan == NULL) - break; - } - (void)fprintf(out, "\n"); - if (pSspec->useMeans == 0) { - pSChan = pSspec->pChanHead; - FMT_INDENT; SKIP_STAMP; - for (colNum=0; colNumdataChan) { - fprintf(out, " %.*s", colWidth*2+1, - "--------------------------------------------------"); - } - pSChan = pSChan->pNext; - if (pSChan == NULL) - break; - } - } - (void)fprintf(out, "\n"); - } -/*----------------------------------------------------------------------------- -* print the stats for each channel for this snapshot. -*----------------------------------------------------------------------------*/ - FMT_INDENT; - (void)fprintf(out, " "); - (void)fprintf(out, " %s", tsStampToText( - &pSspec->pStatTimeStamp[snap], TS_TEXT_MMDDYY, stampText)); - (void)fprintf(out, " %4d", pSspec->pStatPopCount[snap]); - colNum = 0; - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->dataChan) { - if (colNum >= nCol) { - (void)fprintf(out, "\n"); - FMT_INDENT; SKIP_STAMP; - colNum = 0; - - } - prec = pSChan->precision; - cvtDblToTxt(text, colWidth, pSChan->pStats[snap].mean, prec); - fprintf(out, " %*.*s", colWidth, colWidth, text); - if (pSChan->dataChan && pSspec->useMeans == 0) { - cvtDblToTxt(text, colWidth, pSChan->pStats[snap].stdDev, prec); - fprintf(out, " %*.*s", colWidth, colWidth, text); - } - colNum++; - } - } - (void)fprintf(out, "\n"); - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydSampleWriteSSF -* -* DESCRIPTION -* -* RETURNS -* S_syd_OK -* -* BUGS -* o -* -* SEE ALSO -* -* EXAMPLE -* sydSampleWriteSSF(pSspec, out, "PROGRAM: rfqTScan", "sample button", -* sampNum); -* -*-*/ -long -sydSampleWriteSSF(pSspec, pFile, reqDesc, sampDesc, samp) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -FILE *pFile; /* I stream pointer for writing */ -char *reqDesc; /* I description of "request", or NULL */ -char *sampDesc; /* I description for "sample", or NULL */ -int samp; /* I sample number in synchronous set */ -{ - SYD_CHAN *pSChan; /* pointer to channel in synchronous set */ - char stampText[28]; - - if (reqDesc != NULL) - (void)fprintf(pFile, "%s\n", reqDesc); - (void)fprintf(pFile, "SAMPLE: at %s", tsStampToText( - &pSspec->pTimeStamp[samp], TS_TEXT_MMDDYY, stampText)); - if (sampDesc != NULL) - (void)fprintf(pFile, "--%s", sampDesc); - (void)fprintf(pFile, "\n%%endHeader%%\n"); - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->dataChan) { - (void)fprintf(pFile, "%s %s", SydChanName(pSChan), - dbf_type_to_text(SydChanDbfType(pSChan))); - (void)fprintf(pFile, " %d", - pSChan->pDataAlSev != NULL ? pSChan->pDataAlSev[samp] : 0); - (void)fprintf(pFile, " %d", - pSChan->pDataAlStat != NULL ? pSChan->pDataAlStat[samp] : 0); - sydSamplePrint1(pSChan, pFile, ' ', SHOW_AR, 0, samp); - (void)fprintf(pFile, "\n"); - } - } - (void)fprintf(pFile, "%%endData%%\n"); - (void)fflush(pFile); - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydSampleSetAlloc - acquire memory for holding a sample set -* -* DESCRIPTION -* Conditionally allocates memory for holding a sample set. If memory -* has already been allocated to hold at least the requested number -* of samples, then nothing is done. -* -* This routine must be called prior to calling other sydSampleSet... -* routines. (But AFTER calling sydChanOpen for all channels of -* interest!) -* -* If memory has already been allocated, but it isn't sufficient to -* hold the requested number of samples, then that memory is free'd -* and larger memory is allocated. -* -* The allocated memory is automatically free'd by sydClose. -* -* RETURNS -* S_syd_OK, or -* S_syd_noMem if sufficient memory is unavailable -* -* BUGS -* o text -* -* SEE ALSO -* sydClose -* -* EXAMPLE -* -*-*/ -long -sydSampleSetAlloc(pSspec, reqCount) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -int reqCount; /* I number of samples in the set */ -{ - SYD_CHAN *pSChan; - - if (reqCount > pSspec->dataDim) - sydSampleSetFree(pSspec); - if (pSspec->dataDim <= 0) { - pSspec->pDeltaSec = (double *)malloc(reqCount * sizeof(double)); - if (pSspec->pDeltaSec == NULL) - goto sampleMallocErr; - pSspec->pTimeStamp = (TS_STAMP *)malloc(reqCount * sizeof(TS_STAMP)); - if (pSspec->pTimeStamp == NULL) - goto sampleMallocErr; - pSspec->pPartial = (char *)malloc(reqCount * sizeof(char)); - if (pSspec->pPartial == NULL) - goto sampleMallocErr; - pSspec->dataDim = reqCount; - } - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->conn == 0) - ; /* no action if never been connected */ - else if (pSChan->pData == NULL) { - pSChan->pData = (void *)malloc(reqCount * - dbr_value_size[pSChan->dbrType] * pSChan->elCount); - if (pSChan->pData == NULL) - goto sampleMallocErr; - - pSChan->pDataAlStat = (void *)malloc(reqCount * - sizeof(*pSChan->pDataAlStat)); - if (pSChan->pDataAlStat == NULL) - goto sampleMallocErr; - pSChan->pDataAlSev = (void *)malloc(reqCount * - sizeof(*pSChan->pDataAlSev)); - if (pSChan->pDataAlSev == NULL) - goto sampleMallocErr; - pSChan->pDataCodeL = (void *)malloc(reqCount * - sizeof(*pSChan->pDataCodeL)); - if (pSChan->pDataCodeL == NULL) - goto sampleMallocErr; - pSChan->pDataCodeR = (void *)malloc(reqCount * - sizeof(*pSChan->pDataCodeR)); - if (pSChan->pDataCodeR == NULL) - goto sampleMallocErr; - pSChan->pFlags = (void *)malloc(reqCount * - sizeof(*pSChan->pFlags)); - if (pSChan->pFlags == NULL) - goto sampleMallocErr; - } - } - pSspec->reqCount = reqCount; - pSspec->firstData = pSspec->lastData = -1; - pSspec->sampleCount = 0; - pSspec->refTs.secPastEpoch = pSspec->refTs.nsec = 0; - pSspec->restrictFirstData = pSspec->restrictLastData = -1; - pSspec->restrictRefTs = pSspec->refTs; - pSspec->restrictDeltaSecSubtract = 0.; - pSChan = pSspec->pChanHead; - - return S_syd_OK; - -sampleMallocErr: - (void)printf("couldn't get memory to store data\n"); - sydSampleSetFree(pSspec); - return S_syd_noMem; -} - -/*+/subr********************************************************************** -* NAME sydSampleSetExport - export sample set data to output -* -* DESCRIPTION -* Exports the sample set data with the desired filtering. -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSampleSetExport(pSspec, out, option) -FILE *out; /* I stream pointer for output */ -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -int option; /* I filtering option */ -{ - int samp; /* sample number in synchronous set */ - - if (pSspec->useStats) { - for (samp=0; sampstatCount; samp++) - sydSampleExportStats(pSspec, out, samp); - return S_syd_OK; - } - samp = pSspec->restrictFirstData; - while (samp >= 0) { - sydSampleExport(pSspec, out, option, samp); - if (samp == pSspec->restrictLastData) - samp = -1; - else if (++samp >= pSspec->dataDim) - samp = 0; - } - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydSampleSetFree - free the array storage for holding a sample set -* -* DESCRIPTION -* Free's the sample set arrays for a synchronous sample spec. The -* underlying, channel-dependent items in the synchronous sample spec -* aren't altered. -* -* This routine is intended to be called when the number of synchronous -* samples is increased--free the current sample set storage using this -* routine and then allocate new storage using sydSampleSetAlloc. -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSampleSetFree(pSspec) -SYD_SPEC *pSspec; -{ - SYD_CHAN *pSChan; - - assert(pSspec != NULL); - - if (pSspec->pDeltaSec != NULL) { - free((char *)pSspec->pDeltaSec); - pSspec->pDeltaSec = NULL; - } - if (pSspec->pTimeStamp != NULL) { - free((char *)pSspec->pTimeStamp); - pSspec->pTimeStamp = NULL; - } - if (pSspec->pPartial != NULL) { - free((char *)pSspec->pPartial); - pSspec->pPartial = NULL; - } - if (pSspec->pStatTimeStamp != NULL) { - free((char *)pSspec->pStatTimeStamp); - pSspec->pStatTimeStamp = NULL; - } - if (pSspec->pStatDeltaSec != NULL) { - free((char *)pSspec->pStatDeltaSec); - pSspec->pStatDeltaSec = NULL; - } - if (pSspec->pStatPopCount != NULL) { - free((char *)pSspec->pStatPopCount); - pSspec->pStatPopCount = NULL; - } - pSspec->dataDim = 0; - pSspec->sampleCount = 0; - pSspec->firstData = pSspec->lastData = -1; - pSspec->restrictFirstData = pSspec->restrictLastData = -1; - pSspec->statDim = pSspec->statCount = 0; - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) - sydChanFreeArrays(pSChan); - return S_syd_OK; -} - - -/*+/subr********************************************************************** -* NAME sydSampleSetGet - get the samples for a sample set -* -* DESCRIPTION -* -* RETURNS -* S_syd_OK, or -* S_syd_EOF if end of file is encountered, or -* S_syd_chanNotConn if none of the channels is connected -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSampleSetGet(pSspec) -SYD_SPEC *pSspec; -{ - long stat=S_syd_OK; - SYD_CHAN *pSChan; - int n=0; - - assert(pSspec != NULL); - - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (pSChan->discon == 0) - n++; - sydChanPrep(pSspec, pSChan); - } - - pSspec->firstData = pSspec->lastData = -1; - pSspec->restrictFirstData = pSspec->restrictLastData = -1; - pSspec->restrictDeltaSecSubtract = 0.; - pSspec->sampleCount = 0; - - if (n <= 0) { - (void)printf("sydSampleSetGet: none of the channels is connected\n"); - return S_syd_chanNotConn; - } - - while (stat != S_syd_EOF && pSspec->sampleCount < pSspec->reqCount) { - if ((stat = sydInputGet(pSspec, NULL)) != S_syd_EOF) - sydInputStoreInSet(pSspec, 0); - } - return stat; -} - -/*+/subr********************************************************************** -* NAME sydSampleSetPrint - print the samples in a sample set -* -* DESCRIPTION -* -* If the `useStats' flag is set in the sync set spec, then means -* and standard deviations are printed instead of the actual data -* values. (The caller must already have called sydSampleSetStats.) -* -* If the `useMeans' flag is set in conjunction with `useStats', then -* only the means are printed. -* -* RETURNS -* S_syd_OK -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSampleSetPrint(pSspec, out, formatFlag, nCol, colWidth) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -FILE *out; /* IO stream pointer for output */ -int formatFlag; /* I ==1 causes page formatting for printing */ -int nCol; /* I >0 causes that many table columns, folded lines */ -int colWidth; /* I >0 specifies column width, in characters */ -{ - int samp; /* sample number in synchronous set */ - int lineCount=0; - int headerFlag=1; - - assert(pSspec != NULL); - - if (pSspec->useStats) { - for (samp=0; sampstatCount; samp++) { - if (lineCount == 0 && nCol <= 0) - headerFlag = 1; - sydSamplePrintStats(pSspec, out, - formatFlag, headerFlag, nCol, colWidth, samp); - headerFlag = 0; - if (++lineCount > 60) - lineCount = 0; - } - return S_syd_OK; - } - samp = pSspec->restrictFirstData; - while (samp >= 0) { - if (lineCount == 0 && nCol <= 0) - headerFlag = 1; - sydSamplePrint(pSspec,out,formatFlag,headerFlag,nCol,colWidth,samp); - headerFlag = 0; - if (++lineCount > 60) - lineCount = 0; - if (samp == pSspec->restrictLastData) - samp = -1; - else if (++samp >= pSspec->dataDim) - samp = 0; - } - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydSampleSetRestrict - set for processing restricted range of time -* -* DESCRIPTION -* Sets up for processing a restricted range of the samples in the -* sample set, with the restriction based on time. The range starts -* with the first sample whose stamp is >= the desired begin stamp. -* The range ends with the last sample whose stamp is <= the desired -* end stamp. -* -* If the begin stamp pointer is NULL, then the range starts with -* the first sample. The end stamp pointer is treated similarly. -* -* RETURNS -* S_syd_OK, or -* S_syd_ERROR if 1) begin stamp is after time range in set; or -* 2) end stamp is before time range in set; or 3) begin -* stamp is equal to or after end stamp -* -*-*/ -long -sydSampleSetRestrict(pSspec, pTsBegin, pTsEnd) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -TS_STAMP *pTsBegin; /* I pointer to stamp to begin, or NULL */ -TS_STAMP *pTsEnd; /* I pointer to stamp to end, or NULL */ -{ - SYD_CHAN *pSChan; - TS_STAMP tsBegin, tsEnd; - int i, beg=-1, end=-1, first; - int statCount=0, sampCount; - double val; - - assert(pSspec != NULL); - if (pSspec->sampleCount <= 1) - return S_syd_OK; - - if (pTsBegin == NULL) tsBegin = pSspec->pTimeStamp[pSspec->firstData]; - else tsBegin = *pTsBegin; - if (pTsEnd == NULL) tsEnd = pSspec->pTimeStamp[pSspec->lastData]; - else tsEnd = *pTsEnd; - if (TsCmpStampsGT(&tsBegin, &pSspec->pTimeStamp[pSspec->lastData])) - return S_syd_ERROR; - if (TsCmpStampsLT(&tsEnd, &pSspec->pTimeStamp[pSspec->firstData])) - return S_syd_ERROR; - if (TsCmpStampsLE(&tsEnd, &tsBegin)) - return S_syd_ERROR; - -/*----------------------------------------------------------------------------- -* find the appropriate spots to start and end -*----------------------------------------------------------------------------*/ - i = pSspec->firstData; - while (beg < 0) { - if (TsCmpStampsGE(&pSspec->pTimeStamp[i], &tsBegin)) { - beg = i; - break; - } - if (++i >= pSspec->dataDim) - i = 0; - } - assertAlways(beg >= 0); - i = pSspec->lastData; - while (end < 0) { - if (TsCmpStampsLE(&pSspec->pTimeStamp[i], &tsEnd) || i == beg) { - end = i; - break; - } - if (--i < 0) - i = pSspec->dataDim - 1; - } - assertAlways(end >= 0); - -/*----------------------------------------------------------------------------- -* set up the `restrict' structure items -*----------------------------------------------------------------------------*/ - pSspec->restrictFirstData = beg; - pSspec->restrictLastData = end; - pSspec->restrictRefTs = pSspec->pTimeStamp[beg]; - pSspec->restrictRefTs.nsec = 0; - TsDiffAsDouble(&pSspec->restrictDeltaSecSubtract, - &pSspec->restrictRefTs, &pSspec->refTs); - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - i = beg; - first = 1; - while (1) { - if (sydValAsDbl(pSChan, i, &val)) { - if (pSChan->restrictMinDataVal > val || first) - pSChan->restrictMinDataVal = val; - if (pSChan->restrictMaxDataVal < val || first) - pSChan->restrictMaxDataVal = val; - first = 0; - } - if (i == end) - break; - if (++i >= pSspec->dataDim) - i = 0; - - } - } - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydSampleSetStats - compute statistics for sample set -* -*-*/ -long -sydSampleSetStats(pSspec) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -{ - long stat=S_syd_OK; - SYD_CHAN *pSChan; - int i, i1, n, beg, end; - int statCount=0, sampCount; - assert(pSspec != NULL); - -/*----------------------------------------------------------------------------- -* first, find out how many snapshots there are and set up the -* appropriate structures for statistics; assume that all channels -* are the same. -*----------------------------------------------------------------------------*/ - pSChan = pSspec->pChanHead; - i = pSspec->restrictFirstData; - while (1) { - i1 = i + 1 < pSspec->dataDim ? i + 1 : 0; - if (pSChan->pFlags[i].snapend || pSChan->pFlags[i].eof || - i == pSspec->restrictLastData || pSChan->pFlags[i1].restart) { - statCount++; - } - if (i == pSspec->restrictLastData) break; - if (++i >= pSspec->dataDim) i = 0; - } - if (statCount > pSspec->statDim) { - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (!pSChan->dataChan) - continue; - if (pSspec->statDim > 0) { - free((char *)pSChan->pStats); - free((char *)pSspec->pStatTimeStamp); - free((char *)pSspec->pStatDeltaSec); - free((char *)pSspec->pStatPopCount); - } - pSChan->pStats=(SYD_STATS *)malloc(statCount*sizeof(SYD_STATS)); - assertAlways(pSChan->pStats != NULL); - pSspec->pStatDeltaSec = - (double *)malloc(statCount*sizeof(double)); - assertAlways(pSspec->pStatDeltaSec != NULL); - pSspec->pStatTimeStamp = - (TS_STAMP *)malloc(statCount*sizeof(TS_STAMP)); - assertAlways(pSspec->pStatTimeStamp != NULL); - pSspec->pStatPopCount = - (long *)malloc(statCount*sizeof(long)); - assertAlways(pSspec->pStatPopCount != NULL); - } - pSspec->statDim = statCount; - } - pSspec->statCount = statCount; -/*----------------------------------------------------------------------------- -* then, do the statistics -*----------------------------------------------------------------------------*/ - n = sampCount = 0; - i = beg = end = pSspec->restrictFirstData; - pSChan = pSspec->pChanHead; - while (1) { - i1 = i + 1 < pSspec->dataDim ? i + 1 : 0; - if (pSChan->pFlags[i].snapend || pSChan->pFlags[i].eof || - i == pSspec->restrictLastData || pSChan->pFlags[i1].restart) { - if (!pSChan->pFlags[i].eof) { - end = i; - sampCount++; - } - if (sampCount > 0) - sydSampleSetStats_1(pSspec, n, beg, end, sampCount); - sampCount = 0; - beg = -1; - n++; - } - else { - end = i; - sampCount++; - } - if (i == pSspec->restrictLastData) break; - if (++i >= pSspec->dataDim) i = 0; - if (beg < 0) - beg = end = i; - } - - return stat; -} - -/*+/internal****************************************************************** -* NAME sydSampleSetStats_1 - do stats for one snapshot -* -*-*/ -sydSampleSetStats_1(pSspec, statNum, sampBeg, sampEnd, sampCount) -SYD_SPEC *pSspec; -int statNum, sampBeg, sampEnd, sampCount; -{ - SYD_CHAN *pSChan; - double mean, stdDev, diff, val; - int i; - - pSspec->pStatDeltaSec[statNum] = pSspec->pDeltaSec[sampBeg]; - pSspec->pStatTimeStamp[statNum] = pSspec->pTimeStamp[sampBeg]; - pSspec->pStatPopCount[statNum] = sampCount; - for (pSChan=pSspec->pChanHead; pSChan!=NULL; pSChan=pSChan->pNext) { - if (!pSChan->dataChan) - continue; - mean = stdDev = 0.; - i = sampBeg; - while (1) { - if (sydValAsDbl(pSChan, i, &val)) - mean += val; - if (i == sampEnd) break; - if (++i >= pSspec->dataDim) i = 0; - } - if (sampCount > 0) - mean /= sampCount; - i = sampBeg; - while (1) { - if (sydValAsDbl(pSChan, i, &val)) { - diff = val - mean; - stdDev += diff * diff; - } - if (i == sampEnd) break; - if (++i >= pSspec->dataDim) i = 0; - } - if (sampCount > 1) { - stdDev /= (double)(sampCount - 1); - stdDev = sqrt(stdDev); - } - else - stdDev = 0.; - pSChan->pStats[statNum].mean = mean; - pSChan->pStats[statNum].stdDev = stdDev; - } -} - -/*+/subr********************************************************************** -* NAME sydSampleSetWriteSSF - write sample set data to `sample set' file -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSampleSetWriteSSF(pSspec, pFile, reqDesc, sampDesc) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -FILE *pFile; /* I stream pointer for writing */ -char *reqDesc; /* I description of "request", or NULL */ -char *sampDesc; /* I description for "sample", or NULL */ -{ - int samp; /* sample number in synchronous set */ - - samp = pSspec->restrictFirstData; - while (samp >= 0) { - sydSampleWriteSSF(pSspec, pFile, reqDesc, sampDesc, samp); - if (samp == pSspec->restrictLastData) - samp = -1; - else if (++samp >= pSspec->dataDim) - samp = 0; - } - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydSetAttr - set attributes for synchronous set spec -* -* DESCRIPTION -* Set various attributes for a synchronous set specification. -* -* Set the default deadband to use in monitoring channels. This -* attribute must be set before adding any channels to the sync set spec. -* sydSetAttr(pSspec, SYD_ATTR_DEADBAND, 0, text) -* text can be "ADEL" or "MDEL" -* -* Set a callback routine to be called each time a channel receives a -* monitor from Channel Access (must be done prior to adding any -* channels to the sync set spec): -* sydSetAttr(pSspec, SYD_ATTR_MON_FN, 0, callbackFn); -* -* When this attribute is set, the normal sydSubr mechanism for handling -* data is disabled, and the caller is entirely responsible for all -* activities. The callback function has the form: -* void callbackFn(arg) -* struct event_handler_args arg; -* { -* arg.user is the pArg from the sydChanOpen call -* } -* -* Set so that printing, plotting, and exporting use statistics (i.e., -* mean and standard deviation) rather than raw data: -* sydSetAttr(pSspec, SYD_ATTR_USE_STATS, 1, NULL); -* (A value of 0 causes raw data to be used.) -* -* Set so that printing, plotting, and exporting use sample means -* rather than raw data: -* sydSetAttr(pSspec, SYD_ATTR_USE_MEANS, 1, NULL); -* (A value of 0 causes raw data to be used.) -* -* -* RETURNS -* S_syd_OK -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSetAttr(pSspec, attr, value, pArg) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -SYD_ATTR attr; /* I attribute key; one of the SYD_ATTR_xxx */ -int value; /* I value for numeric attributes */ -void *pArg; /* I pointer to value for non-numeric attributes */ -{ - if (attr == SYD_ATTR_DEADBAND) { - assert(pSspec->pChanHead == NULL); - if (strcmp((char *)pArg, "ADEL") == 0) - pSspec->deadband = DBE_LOG; - else if (strcmp((char *)pArg, "MDEL") == 0) - pSspec->deadband = DBE_VALUE; - else - assertAlways(0); - } - else if (attr == SYD_ATTR_MON_FN) - pSspec->monFn = pArg; - else if (attr == SYD_ATTR_USE_STATS) { - pSspec->useStats = value; - pSspec->useMeans = 0; - } - else if (attr == SYD_ATTR_USE_MEANS) { - pSspec->useStats = value; - pSspec->useMeans = value; - } - else - assertAlways(0); - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydTest - test the condition for the sync set spec -* -* DESCRIPTION -* For the sample most recently acquired by sydInputGet, tests the -* condition established by sydTestAddFromText. -* -* If no condition was established, this routine returns 1. -* -* RETURNS -* 1 if the condition is true for the present value of the channel -* 0 otherwise -* -*-*/ -long -sydTest(pSspec) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -{ - SYD_CHAN *pSChan; - SYD_TEST *pTest; - int i, change; - chtype type; - double dblVal=0.0; - long lngVal=0; - char *strVal=NULL; - int myType=0; /* 0,1,2 for double, long, string */ - - if ((pTest = pSspec->pAccept) == NULL) - return 1; - pSChan = pTest->pSChan; - i = pSChan->sampInBuf; - if (i < 0 || pSChan->inStatus[i] == SYD_B_EMPTY || - pSChan->inStatus[i] == SYD_B_EOF || - pSChan->inStatus[i] == SYD_B_MISSING) - return 0; - type = pSChan->dbrType; -#define TEST_IT(val, item,ty) val = pSChan->pInBuf[i]->item.value, myType = ty - if (type == DBR_TIME_FLOAT) TEST_IT(dblVal, tfltval, 0); - else if (type == DBR_TIME_SHORT) TEST_IT(lngVal, tshrtval, 1); - else if (type == DBR_TIME_DOUBLE) TEST_IT(dblVal, tdblval, 0); - else if (type == DBR_TIME_LONG) TEST_IT(lngVal, tlngval, 1); - else if (type == DBR_TIME_STRING) - strcpy(strVal, pSChan->pInBuf[i]->tstrval.value), myType = 2; - else if (type == DBR_TIME_CHAR) TEST_IT(lngVal, tchrval, 1); - else if (type == DBR_TIME_ENUM) { -#if 0 - jjj -#endif - } - change = 0; - if (myType == 0) { - if (dblVal < pTest->dblVal) change = -1; - else if (dblVal > pTest->dblVal) change = 1; - } - else if (myType == 1) { - if (lngVal < pTest->lngVal) change = -1; - else if (lngVal > pTest->lngVal) change = 1; - } -#define COND_IS(ty) pTest->cond == SYD_TSTC_##ty - if (change == 0) { - if (COND_IS(EQ) || COND_IS(LE) || COND_IS(GE)) - return 1; - } - else if (change == -1) { - if (COND_IS(NE) || COND_IS(LE) || COND_IS(LT)) - return 1; - } - else { - if (COND_IS(NE) || COND_IS(GE) || COND_IS(GT)) - return 1; - } - return 0; -} - -/*+/subr********************************************************************** -* NAME sydTestAddFromText - add a sample test from a text string -* -* DESCRIPTION -* Scans a text string which specifies a test condition and -* builds a test structure for the synchronous set spec -* -* if chanName condition -* -* This routine adds a synchronous channel structure to the synchronous -* set spec, flagging the sync channel struct as a `test channel'. -* If the sync set spec already has a sync channel struct for the -* channel, then that sync channel struct will be flagged as both -* a `data channel' and also a `test channel'. Programs using -* test channels which aren't also data channels must distinguish -* between the two in their handling of samples. -* -* RETURNS -* S_syd_OK, or -* S_syd_noMem if malloc failed -* S_syd_ERROR if an error is detected -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. The test structure must be closed by calling sydTestClose. -* (This happens automatically when sydClose is called.) -* -* EXAMPLE -* -*-*/ -long -sydTestAddFromText(pSspec, text) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -char *text; /* I pointer to string with test specification */ -{ - char *myText=NULL; - char *pText, *pFld, delim, *pMsg; - SYD_TEST *pTest=NULL; - char *name; - enum sydChanSync sync=SYD_SY_NONF; - int i; - long stat; - SYD_CHAN *pSChan; - - assert(pSspec != NULL); - assert(text != NULL); - - if (pSspec->pAccept != NULL) { - (void)printf("sydTestAddFromText: sync set spec already has trigger\n"); - return S_syd_ERROR; - } - if ((myText = (char *)malloc(strlen(text))) == NULL) { - (void)printf("sydTestAddFromText: couldn't malloc for text temp\n"); - return S_syd_noMem; - } - pText = myText; - strcpy(myText, text); - if ((pTest = (SYD_TEST *)malloc(sizeof(SYD_TEST))) == NULL) { - (void)printf("sydTestAddFromText: couldn't malloc for test struct\n"); - free(myText); - return S_syd_noMem; - } - pSspec->pAccept = pTest; - pTest->type = pTest->cond = 0; - pTest->pSChan = NULL; - - if (nextAlphField(&pText, &pFld, &delim) <= 1) { - pMsg = "no trigger keyword found"; - goto trigScanErr; - } - if (strcmp(pFld, "if") == 0) - pTest->type = SYD_TST_IF; - else { - pMsg = "illegal test type"; - goto trigScanErr; - } - if (pTest->type == SYD_TST_IF) { -/*----------------------------------------------------------------------------- -* if chanName condition -*----------------------------------------------------------------------------*/ - if (nextChanNameField(&pText, &name, &delim) <= 1) { - pMsg = "no channel name found"; - goto trigScanErr; - } - if (strcmp(name, "F") == 0) { - sync = SYD_SY_FILLED; - if (nextChanNameField(&pText, &name, &delim) <= 1) { - pMsg = "no channel name found"; - goto trigScanErr; - } - } - stat = sydChanOpen(pSspec, &pSChan, name, sync, NULL, 1); - if (stat != S_syd_OK && stat != S_syd_chanNotConn) { - pMsg = "couldn't find channel"; - goto trigScanErr; - } - pTest->pSChan = pSChan; - if (nextNonSpaceField(&pText, &pFld, &delim) <= 1) { - pMsg = "condition expected"; - goto trigScanErr; - } - for (i=1; i= SYD_TSTC_PAST || i == SYD_TSTC_CHANGE) { - pMsg = "condition expected"; - goto trigScanErr; - } - pTest->cond = i; - if (nextNonSpaceField(&pText, &pFld, &delim) <= 1) { - pMsg = "comparison value expected"; - goto trigScanErr; - } - if (strlen(pFld) >= db_strval_dim) { - pMsg = "comparison value too long"; - goto trigScanErr; - } - strcpy(pTest->strVal, pFld); - if (sscanf(pFld, "%lf", &pTest->dblVal) != 1) - pTest->dblVal = 0.; - pTest->lngVal = pTest->dblVal; - } - - free(myText); - pSspec->pAccept = pTest; - return S_syd_OK; - -trigScanErr: - (void)printf("sydTestAddFromText: %s\n%s\n", pMsg, myText); - sydTestClose(pSspec); - free(myText); - return S_syd_ERROR; -} - -/*+/subr********************************************************************** -* NAME sydTestClose - add a sample test condition -* -* DESCRIPTION -* Closes a test condition. -* -* RETURNS -* S_syd_OK -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. The test structure must be closed by calling sydTestClose. -* (This happens automatically when sydClose is called.) -* -* EXAMPLE -* -*-*/ -long -sydTestClose(pSspec) -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -{ - SYD_TEST *pTest; - assert(pSspec != NULL); - - if ((pTest = pSspec->pAccept) == NULL) - return S_syd_OK; - if (pTest->pSChan == NULL) { - free((char *)pTest); - pSspec->pAccept = NULL; - } - else if (pTest->pSChan->dataChan == 0) - sydChanClose(pSspec, pTest->pSChan); - else { - pTest->pSChan->testChan = 0; - free((char *)pTest); - pSspec->pAccept = NULL; - } - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydTsRound - round time stamp to nearest millisecond -* -*-*/ -sydTsRound(pStamp, roundNsec) -TS_STAMP *pStamp; -int roundNsec; -{ - unsigned long roundTemp; - - roundTemp = pStamp->nsec; - roundTemp = ( (roundTemp + roundNsec/2) / roundNsec ) * roundNsec; - if (roundTemp < 1000000000) - pStamp->nsec = roundTemp; - else { - pStamp->nsec = roundTemp - 1000000000; - pStamp->secPastEpoch++; - } -} - -/*+/subr********************************************************************** -* NAME sydValAsDbl - fetch value from channel as a double -* -* RETURNS -* 1, or -* 0 if the value is missing or EOF, or if the type is invalid -* -*-*/ -int -sydValAsDbl(pSChan, sampNum, pDbl) -SYD_CHAN *pSChan; /* I sync channel pointer */ -int sampNum; /* I sample number */ -double *pDbl; /* O value */ -{ - if (pSChan->pFlags[sampNum].missing || pSChan->pFlags[sampNum].eof) - return 0; - if (pSChan->dbfType == DBF_FLOAT) - *pDbl = (double)(((float *)pSChan->pData)[sampNum]); - else if (pSChan->dbfType == DBF_DOUBLE) - *pDbl = ((double *)pSChan->pData)[sampNum]; - else if (pSChan->dbfType == DBF_SHORT) { - if (pSChan->isRVAL) - *pDbl = (double)(((unsigned short *)pSChan->pData)[sampNum]); - else - *pDbl = (double)(((short *)pSChan->pData)[sampNum]); - } - else if (pSChan->dbfType == DBF_LONG) { - if (pSChan->isRVAL) - *pDbl = (double)(((unsigned long *)pSChan->pData)[sampNum]); - else - *pDbl = (double)(((long *)pSChan->pData)[sampNum]); - } - else if (pSChan->dbfType == DBF_CHAR) - *pDbl = (double)(((char *)pSChan->pData)[sampNum]); - else - return 0; - - return 1; -} diff --git a/src/libCom/sydSubrCA.c b/src/libCom/sydSubrCA.c deleted file mode 100644 index df212a06c..000000000 --- a/src/libCom/sydSubrCA.c +++ /dev/null @@ -1,537 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 06-12-91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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: - * ----------------- - * .00 06-12-91 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 06-19-91 rac replace with - * .03 08-15-91 rac use new call for sydOpen - * .04 09-23-91 rac allow async completion of ca_search - * .05 02-13-92 rac use ADEL for monitoring; perform time-stamp - * rounding if requested - * .06 03-08-92 rac use deadband from pSspec for monitoring - * .07 03-27-92 rac fix bug in reconnect--discon wasn't getting reset; - * properly handle wrap-around in input buffer; call - * user's CA monitor handler if desired; do a flush - * after ca_search; handle disconCount and needGrCount - * in sampleSetSpec; move copyGr and copyVal into - * sydSubr.c - * .08 09-14-92 rac discontinue use of special malloc routines - * .09 09-29-92 rac discard samples with duplicate time stamps - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code - */ -/*+/mod*********************************************************************** -* TITLE sydSubrCA.c - acquire synchronous samples from Channel Access -* -* DESCRIPTION -* -*-***************************************************************************/ -#include -#define SYD_PRIVATE -#include -#include -#ifndef INCLcadefh -# include -#endif - -#ifdef vxWorks -# include -# include -#else -# include -#endif - -long sydCAFunc(); -static void sydCAFuncConnHandler(); -void sydCAFuncMonHandler(); -static long sydFuncCA_finishConn(); - -#define sydCA_searchNOW /* force immediate completion of connection */ -#undef sydCA_searchNOW /* asynchronous completion of connection */ -static void sydCAFuncInitGR(); - -long -sydOpenCA(ppSspec, pHandle) -SYD_SPEC **ppSspec; /* O pointer to synchronous set spec pointer */ -void *pHandle; /* I NULL; someday might implement a callback - routine to be called when a sample is available */ -{ - long stat; - - assert(ppSspec != NULL); - - if ((*ppSspec = (SYD_SPEC *)malloc(sizeof(SYD_SPEC))) == NULL) - return S_syd_noMem; - (*ppSspec)->pFunc = sydCAFunc; - (*ppSspec)->type = SYD_TY_CA; - if ((stat = sydCAFunc(*ppSspec, NULL, SYD_FC_INIT, pHandle)) != S_syd_OK){ - free((char *)*ppSspec); - return stat; - } - (*ppSspec)->nInBufs = SYD_CHAN_MAX_IN; - - return sydOpen(ppSspec); -} -/*+/subr********************************************************************** -* NAME sydCAFunc - handle "Channel Access" data interactions -* -* DESCRIPTION -* Handle acquisition of synchronous samples from Channel Access. -* -* The caller must periodically call ca_pend_event in order for these -* routines to make connections to channels, detect connect/disconnect, -* and receive data. The frequency with which ca_pend_event is called -* should be about the same as the maximum frequency that data values -* will change. -* -* sydCAFunc(pSspec, NULL, SYD_FC_INIT, pCallback) -* sydCAFunc(pSspec, pSChan, SYD_FC_OPEN, NULL) chanName already in pSChan -* sydCAFunc(pSspec, pSChan, SYD_FC_READ, NULL) start monitoring -* sydCAFunc(pSspec, pSChan, SYD_FC_STOP, NULL) stop monitoring -* sydCAFunc(pSspec, pSChan, SYD_FC_POSITION, &stamp) no operation performed -* sydCAFunc(pSspec, pSChan, SYD_FC_CLOSE, NULL) -* sydCAFunc(pSspec, NULL, SYD_FC_FILEINFO, outStream) -* sydCAFunc(pSspec, NULL, SYD_FC_WRAPUP, NULL) no operation performed -* -* RETURNS -* S_syd_OK, or -* S_syd_EOF, or -* S_syd_ERROR, or -* other code indicating error -* -* BUGS -* o doesn't do anything (or even detect) overwriting un-sampled -* buffers (for SYD_FC_READ) -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydCAFunc(pSspec, pStruct, funcCode, pArg) -SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */ -void *pStruct; /* IO pointer to data struct used by funcCode */ -enum sydFuncCode funcCode;/* I function code */ -void *pArg; /* I pointer to arg, as required by funcCode */ -{ - SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ - chid pCh; /* channel pointer */ - long retStat=S_syd_OK; - long stat; - int i; - - pSChan = (SYD_CHAN *)pStruct; - - if (funcCode == SYD_FC_INIT) { - pSspec->pHandle = (void *)NULL; - } - else if (funcCode == SYD_FC_OPEN) { -/*----------------------------------------------------------------------------- -* Initiate a connection to Channel Access for this channel. The action -* depends on whether searches are to be completed _now_, or asynchronously. -* -* If searches are to be completed now, then a ca_pend_io is done. If -* the search isn't successful, an error return is given. -* -* If searches are to be asynchronous, the connection handler is allowed -* to do the required connection processing. -*----------------------------------------------------------------------------*/ - pSChan->dbfType = pSChan->dbrType = TYPENOTCONN; - pSspec->disconCount++; - pSChan->elCount = 1; - pSChan->evid = NULL; - pSChan->gotGr = 0; - pSspec->needGrCount++; - pSChan->restart = 1; - sydCAFuncInitGR(pSChan); -#ifdef sydCA_searchNOW - stat = ca_search(pSChan->name, &pCh); -#else - stat = ca_build_and_connect(pSChan->name, TYPENOTCONN, 0, &pCh, - NULL, sydCAFuncConnHandler, pSChan); - stat = ca_flush_io(); -#endif - if (stat != ECA_NORMAL) { - retStat = S_syd_ERROR; - (void)printf("sydCAFunc: error on ca_search for %s :\n%s\n", - pSChan->name, ca_message(stat)); - return retStat; - } - pSChan->pHandle = (void *)pCh; -#ifdef sydCA_searchNOW - stat = ca_pend_io(2.); - if (stat != ECA_NORMAL) { - retStat = S_syd_chanNotFound; - ca_clear_channel(pCh); - return retStat; - } - ca_puser(pCh) = pSChan; - retStat = sydFuncCA_finishConn(pSChan, pCh); - if (retStat != S_syd_OK) - return retStat; - pSChan->pSspec->disconCount--; - stat = ca_change_connection_event(pCh, sydCAFuncConnHandler); - if (stat != ECA_NORMAL) { - retStat = S_syd_ERROR; - (void)printf("sydCAFunc: error on ca_search for %s :\n%s\n", - pSChan->name, ca_message(stat)); - ca_clear_channel(pCh); - return retStat; - } -#else - retStat = S_syd_chanNotConn; -#endif - } - else if (funcCode == SYD_FC_READ) { - if ((pCh = (chid)pSChan->pHandle) == NULL) - return retStat; - if (pSChan->evid == NULL) { - if (pSChan->pSspec->monFn == NULL) { - stat = ca_add_masked_array_event(pSChan->dbrType, - pSChan->elCount, pCh, sydCAFuncMonHandler, NULL, - 0., 0., 0., &pSChan->evid, pSChan->pSspec->deadband); - } - else { - stat = ca_add_masked_array_event(pSChan->dbrType, - pSChan->elCount, pCh, - pSChan->pSspec->monFn, pSChan->pArg, - 0., 0., 0., &pSChan->evid, pSChan->pSspec->deadband); - } - if (stat != ECA_NORMAL) { - retStat = S_syd_ERROR; - (void)printf( -"sydCAFunc: error on ca_add_masked_array_event for %s :\n%s\n", - pSChan->name, ca_message(stat)); - ca_clear_channel(pCh); - return retStat; - } - } - } - else if (funcCode == SYD_FC_STOP) { - if ((pCh = (chid)pSChan->pHandle) == NULL) - return retStat; - if (pSChan->evid == NULL) { - ca_clear_event(pSChan->evid); - pSChan->evid = NULL; - } - } - else if (funcCode == SYD_FC_POSITION) { - ; - } - else if (funcCode == SYD_FC_CLOSE) { - if ((pCh = (chid)pSChan->pHandle) != NULL) { - stat = ca_clear_channel(pCh); - if (stat != ECA_NORMAL) - retStat = S_syd_ERROR; - } - } - else if (funcCode == SYD_FC_FILEINFO) { - (void)fprintf((FILE *)pArg, "no info for Channel Access\n"); - } - else if (funcCode == SYD_FC_WRAPUP) { - ; - } - - return retStat; -} - -/*+/internal****************************************************************** -* NAME sydFuncCA_finishConn -* -* DESCRIPTION -* Handles connect and disconnect for a channel. -* -* The first connect results in adding a monitor for the channel using -* the `syd' monitor handler, unless the user has his own monitor -* handler. In the latter case, no monitor is added until the user -* calls sydInputGet the first time. -* -*-*/ -static long -sydFuncCA_finishConn(pSChan, pCh) -SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ -chid pCh; /* channel pointer */ -{ - long retStat=S_syd_OK; - long stat; - - pSChan->dbfType = ca_field_type(pCh); - pSChan->dbrType = dbf_type_to_DBR_TIME(pSChan->dbfType); - pSChan->elCount = ca_element_count(pCh); - pSChan->dbrGrType = dbf_type_to_DBR_GR(pSChan->dbfType); - stat = ca_array_get_callback(pSChan->dbrGrType, 1, pCh, - sydCAFuncMonHandler, NULL); - if (stat != ECA_NORMAL) { - retStat = S_syd_ERROR; - (void)printf( - "sydCAFunc: error on ca_array_get_callback(GR) for %s :\n%s\n", - pSChan->name, ca_message(stat)); - ca_clear_channel(pCh); - return retStat; - } - if (pSChan->evid == NULL) { - if (pSChan->pSspec->monFn == NULL) { - stat = ca_add_masked_array_event(pSChan->dbrType, - pSChan->elCount, pCh, sydCAFuncMonHandler, NULL, - 0., 0., 0., &pSChan->evid, pSChan->pSspec->deadband); - } - if (stat != ECA_NORMAL) { - retStat = S_syd_ERROR; - (void)printf( - "sydCAFunc: error on ca_add_masked_array_event for %s :\n%s\n", - pSChan->name, ca_message(stat)); - ca_clear_channel(pCh); - return retStat; - } - } - pSChan->conn = 1; - pSChan->discon = 0; - retStat = sydChanOpen1(pSChan->pSspec, pSChan); - return retStat; -} - -/*+/subr********************************************************************** -* NAME sydCAFuncConnHandler - connection handler for sync CA data routines -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -static void -sydCAFuncConnHandler(arg) -struct connection_handler_args arg; -{ - SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ - chid pCh; /* channel pointer */ - long retStat=S_syd_OK; - long stat; - int i; - - pCh = arg.chid; - pSChan = (SYD_CHAN *)ca_puser(pCh); - if (arg.op == CA_OP_CONN_UP) { - if (pSChan->conn == 0) - retStat = sydFuncCA_finishConn(pSChan, pCh); - if (retStat != S_syd_OK) { - (void)printf( -"sydCAFuncConnHandler: error finishing connection for %s\n", ca_name(pCh)); - } - pSChan->restart = 1; - pSChan->discon = 0; - pSChan->pSspec->disconCount--; - } - else { - pSChan->discon = 1; - pSChan->pSspec->disconCount++; - } -} - -/*+/subr********************************************************************** -* NAME sydCAFuncMonHandler - handle monitor and get_callback -* -* DESCRIPTION -* Receive data from Channel Access and store in the input buffers -* of channels' synchronous data descriptors. The data will be -* retrieved later and assembled into synchronous samples by -* sydSampleGet. -* -* If data are received from Channel Access faster than the program -* removes it with sydSampleGet, then the oldest unretrieved data -* is lost. -* -* If time stamp rounding is to be done, it is done here. -* -* RETURNS -* void -* -* BUGS -* o no indication is given of lost data -* o no precautions are taken to protect against the case where a -* monitor comes in (following a disconnect/connect) with an old, old -* time stamp. -* -* SEE ALSO -* sydSampleGet, sydSampleStore -* -* EXAMPLE -* sydResetBufKeepNewest(pSspec); -* sydSampleSetAlloc(pSspec, nSamp); -* pSspec->sampleCount = 0; -* pSspec->refTs->secPastEpoch = 0; -* pSspec->refTs->nsec = 0; -* -* while (sydSampleGet(pSspec) != S_syd_noDataNow) -* sydSampleStore(pSspec); -* -* -*-*/ -void -sydCAFuncMonHandler(arg) -struct event_handler_args arg; -{ - SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ - SYD_SPEC *pSspec; /* pointer to syncSet spec */ - chid pCh; /* channel pointer */ - long retStat=S_syd_OK; - long stat; - int i, i1, j; - long inStatus; - union db_access_val *pBuf; - int nbytes; - - pCh = arg.chid; - pBuf = arg.dbr; - pSChan = (SYD_CHAN *)ca_puser(pCh); - pSspec = pSChan->pSspec; - - if (dbr_type_is_GR(arg.type)) { - pSChan->gotGr = 1; - pSspec->needGrCount--; - sydCopyGr(&pSChan->grBuf, pBuf, arg.type); - stat = sydChanOpenGR(pSChan); - return; - } - if (!dbr_type_is_TIME(arg.type)) - return; - - if (pSspec->roundNsec > 0) - sydTsRound(&pBuf->tfltval.stamp, pSspec->roundNsec); -/*----------------------------------------------------------------------------- -* If this monitor has the same time stamp as the prior monitor for -* this channel, discard this one. -*----------------------------------------------------------------------------*/ - if ((i = pSChan->lastInBuf) >= 0) { - if (TsCmpStampsLE(&pBuf->tfltval.stamp, - &pSChan->pInBuf[i]->tfltval.stamp)) { - return; - } - } - -/*----------------------------------------------------------------------------- -* If the reference time stamp for the sync set hasn't been set yet, -* or if it has, but the time stamp in this monitor is earlier, set it. -*----------------------------------------------------------------------------*/ - if (pSspec->refTs.secPastEpoch == 0 || pSspec->sampleCount == 0) { - if (pBuf->tfltval.stamp.secPastEpoch != 0 && - TsCmpStampsLE(&pBuf->tfltval.stamp, &pSspec->refTs)) { - pSspec->refTs = pBuf->tfltval.stamp; - } - } - - i = NEXT_INBUF(pSChan, pSChan->lastInBuf); - i1 = NEXT_INBUF(pSChan, i); - if (pSChan->restart) { - pSChan->inStatus[i] = SYD_B_RESTART; - pSChan->restart = 0; - } - else - pSChan->inStatus[i] = SYD_B_FULL; - - nbytes = dbr_size_n(arg.type, pSChan->elCount); - bcopy((char *)pBuf, (char *)pSChan->pInBuf[i], nbytes); - - pSChan->lastInBuf = i; - if (pSChan->firstInBuf == i) { - pSChan->firstInBuf = i1; - pSChan->inStatus[i1] = SYD_B_RESTART; - } - else if (pSChan->firstInBuf < 0) - pSChan->firstInBuf = i; -} - -/*+/internal****************************************************************** -* NAME sydCAFuncInitGR -* -*-*/ -static void -sydCAFuncInitGR(pSChan) -SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ -{ - if (pSChan->dbrType == DBR_TIME_FLOAT) { -#define FLT_DEST pSChan->grBuf.gfltval - FLT_DEST.status = FLT_DEST.severity = NO_ALARM; - FLT_DEST.precision = 3; - (void)strcpy(FLT_DEST.units, " "); - FLT_DEST.upper_disp_limit = FLT_DEST.lower_disp_limit = 0.; - FLT_DEST.upper_alarm_limit = FLT_DEST.lower_alarm_limit = 0.; - FLT_DEST.upper_warning_limit = FLT_DEST.lower_warning_limit = 0.; - } - else if (pSChan->dbrType == DBR_TIME_SHORT) { -#define SHRT_DEST pSChan->grBuf.gshrtval - SHRT_DEST.status = SHRT_DEST.severity = NO_ALARM; - (void)strcpy(SHRT_DEST.units, " "); - SHRT_DEST.upper_disp_limit = SHRT_DEST.lower_disp_limit = 0; - SHRT_DEST.upper_alarm_limit = SHRT_DEST.lower_alarm_limit = 0; - SHRT_DEST.upper_warning_limit = SHRT_DEST.lower_warning_limit = 0; - } - else if (pSChan->dbrType == DBR_TIME_DOUBLE) { -#define DBL_DEST pSChan->grBuf.gdblval - DBL_DEST.status = DBL_DEST.severity = NO_ALARM; - DBL_DEST.precision = 3; - (void)strcpy(DBL_DEST.units, " "); - DBL_DEST.upper_disp_limit = DBL_DEST.lower_disp_limit = 0.; - DBL_DEST.upper_alarm_limit = DBL_DEST.lower_alarm_limit = 0.; - DBL_DEST.upper_warning_limit = DBL_DEST.lower_warning_limit = 0.; - } - else if (pSChan->dbrType == DBR_TIME_LONG) { -#define LNG_DEST pSChan->grBuf.glngval - LNG_DEST.status = LNG_DEST.severity = NO_ALARM; - (void)strcpy(LNG_DEST.units, " "); - LNG_DEST.upper_disp_limit = LNG_DEST.lower_disp_limit = 0; - LNG_DEST.upper_alarm_limit = LNG_DEST.lower_alarm_limit = 0; - LNG_DEST.upper_warning_limit = LNG_DEST.lower_warning_limit = 0; - } - else if (pSChan->dbrType == DBR_TIME_STRING) { -#define STR_DEST pSChan->grBuf.gstrval - STR_DEST.status = STR_DEST.severity = NO_ALARM; - } - else if (pSChan->dbrType == DBR_TIME_ENUM) { -#define ENM_DEST pSChan->grBuf.genmval - ENM_DEST.status = ENM_DEST.severity = NO_ALARM; - ENM_DEST.no_str = 0; - } - else if (pSChan->dbrType == DBR_TIME_CHAR) { -#define CHR_DEST pSChan->grBuf.gchrval - CHR_DEST.status = CHR_DEST.severity = NO_ALARM; - (void)strcpy(CHR_DEST.units, " "); - CHR_DEST.upper_disp_limit = CHR_DEST.lower_disp_limit = 0; - CHR_DEST.upper_alarm_limit = CHR_DEST.lower_alarm_limit = 0; - CHR_DEST.upper_warning_limit = CHR_DEST.lower_warning_limit = 0; - } -} diff --git a/src/libCom/sydSubrCF.c b/src/libCom/sydSubrCF.c deleted file mode 100644 index ecdea352a..000000000 --- a/src/libCom/sydSubrCF.c +++ /dev/null @@ -1,398 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 12-04-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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: - * ----------------- - * .00 12-04-90 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 06-19-91 rac replace with - * .03 08-06-91 rac allow specifying file name - * .04 09-11-91 rac finish allowing user specified name - * .05 02-27-92 rac do ts rounding here instead of sydSubr.c - * .06 09-14-92 rac discontinue use of special malloc routines - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code - */ -/*+/mod*********************************************************************** -* TITLE sydSubrCF.c - acquire synchronous samples from `by channel' AR file -* -* DESCRIPTION -* -*-***************************************************************************/ -#include -#define SYD_PRIVATE -#include -#include -#ifndef INC_arAccessLib_h -# include -#endif -#ifndef INC_tsDefs_h -# include -#endif -#ifndef INC_arCS_h -# include -#endif -#ifndef INCLcadefh -# include -#endif - -#ifdef vxWorks -# include -# include /* for O_RDWR and O_RDONLY definitions */ -# include -#else -# include -# include /* for O_RDWR and O_RDONLY definitions */ -#endif -long sydCFFunc(); -long sydCFFuncGetGR(); - - -/*+/subr********************************************************************** -* NAME sydOpenCF - open an AR `by channel' file for retrieval -* -* DESCRIPTION -* Open an archiver `by channel' file for synchronous data retrieval. -* -* RETURNS -* S_syd_OK, or -* S_syd_ERROR, or -* other code indicating error -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydOpenCF(ppSspec, filePath) -SYD_SPEC **ppSspec; /* O pointer to synchronous set spec pointer */ -char *filePath; /* I path name for `by channel' archive file */ -{ - long stat; - - assert(ppSspec != NULL); - - if ((*ppSspec = (SYD_SPEC *)malloc(sizeof(SYD_SPEC))) == NULL) - return S_syd_noMem; - (*ppSspec)->pFunc = sydCFFunc; - (*ppSspec)->type = SYD_TY_CF; - if ((stat = sydCFFunc(*ppSspec, NULL, SYD_FC_INIT, filePath)) != S_syd_OK){ - free((char *)*ppSspec); - *ppSspec = NULL; - return stat; - } - (*ppSspec)->nInBufs = 2; - return sydOpen(ppSspec); -} -/*+/subr********************************************************************** -* NAME sydCFFunc - handle "by channel" data file interactions -* -* DESCRIPTION -* -* sydCFFunc(pSspec, NULL, SYD_FC_INIT, filePath) open "by channel" file -* sydCFFunc(pSspec, pSChan, SYD_FC_OPEN, NULL) chanName already in pSChan -* sydCFFunc(pSspec, pSChan, SYD_FC_READ, NULL) -* sydCFFunc(pSspec, NULL, SYD_FC_READ_SYNC, NULL) sync "by channel" file -* sydCFFunc(pSspec, pSChan, SYD_FC_POSITION, &stamp) -* sydCFFunc(pSspec, pSChan, SYD_FC_CLOSE, NULL) -* sydCFFunc(pSspec, NULL, SYD_FC_FILEINFO, outFile) -* sydCFFunc(pSspec, NULL, SYD_FC_WRAPUP, NULL) close "by channel" file -* -* RETURNS -* S_syd_OK, or -* S_syd_EOF, or -* other code indicating error -* -* BUGS -* o doesn't detect or report EOF -* o doesn't do anything (or even detect) overwriting un-sampled -* buffers (for SYD_FC_READ) -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydCFFunc(pSspec, pStruct, funcCode, pArg) -SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */ -void *pStruct; /* IO pointer to data struct used by funcCode */ -enum sydFuncCode funcCode;/* I function code */ -void *pArg; /* I pointer to arg, as required by funcCode */ -{ - SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ - AR_CHAN_DESC *pChanDesc=NULL;/* pointer to chanDesc for channel */ - AR_CF_DESC *pCfDesc; /* pointer to cfDesc for channel file */ - long retStat=S_syd_OK; - long stat, inStatus; - int i; - - pSChan = (SYD_CHAN *)pStruct; - if (pSChan != NULL) - pChanDesc = (AR_CHAN_DESC *)pSChan->pHandle; - if (pSspec != NULL) - pCfDesc = (AR_CF_DESC *)pSspec->pHandle; - - if (funcCode == SYD_FC_INIT) { - pCfDesc = arCFOpen(pArg, O_RDONLY); - if (pCfDesc == NULL) { - (void)printf("couldn't open %s\n", pArg); - retStat = S_syd_ERROR; - } - pSspec->pHandle = (void *)pCfDesc; - } - else if (funcCode == SYD_FC_OPEN) { - pChanDesc = arCFChanOpen(pCfDesc, pSChan->name, O_RDONLY); - if (pChanDesc == NULL) - retStat = S_syd_chanNotFound; - else { - pSChan->pHandle = (void *)pChanDesc; - pSChan->dbfType = ArCFChanFieldType(pChanDesc); - pSChan->dbrType = dbf_type_to_DBR_TIME(pSChan->dbfType); - pSChan->elCount = ArCFChanElementCount(pChanDesc); - sydCFFuncGetGR(pSChan, pChanDesc); - } - } - else if (funcCode == SYD_FC_READ) { - i = NEXT_INBUF(pSChan, pSChan->lastInBuf); - pSChan->inStatus[i] = inStatus = SYD_B_EMPTY; - while (pSChan->inStatus[i] == SYD_B_EMPTY) { - stat = arCFChanRead(pChanDesc, - pSChan->dbrType, pSChan->pInBuf[i], pSChan->elCount); - if (stat == OK) { - if (inStatus == SYD_B_EMPTY) - pSChan->inStatus[i] = SYD_B_FULL; - else - pSChan->inStatus[i] = inStatus; - if (pSspec->roundNsec > 0) { - sydTsRound(&pSChan->pInBuf[i]->tfltval.stamp, - pSspec->roundNsec); - } - } - else if ((pChanDesc->flags & AR_CDESC_EOF) != 0) - pSChan->inStatus[i] = SYD_B_EOF; - else if ((pChanDesc->flags & AR_CDESC_SNAP_BEGIN) != 0) { - if ((pChanDesc->flags & AR_CDESC_SNAP_END) != 0) - inStatus = SYD_B_SNAP_SINGLE; - else - inStatus = SYD_B_SNAP_BEGIN; - } - else if ((pChanDesc->flags & AR_CDESC_SNAP_END) != 0) - inStatus = SYD_B_SNAP_END; - else if ((pChanDesc->flags & AR_CDESC_BEGIN) != 0) - inStatus = SYD_B_RESTART; - } - pSChan->lastInBuf = i; - if (pSChan->firstInBuf < 0) - pSChan->firstInBuf = i; - } - else if (funcCode == SYD_FC_STOP) { - } - else if (funcCode == SYD_FC_READ_SYNC) { - /* synchronize file buf in memory with data on disk */ - stat = arCFSyncRead(pCfDesc); - if (stat != OK) - retStat = S_syd_ERROR; - } - else if (funcCode == SYD_FC_POSITION) { - stat = arCFChanPosition(pChanDesc, (TS_STAMP *)pArg); - if (stat != OK) { - if ((pChanDesc->flags & AR_CDESC_EOF) == 0) { - (void)printf("error for %s\n", pSChan->name); - assertAlways(0); - } - } - } - else if (funcCode == SYD_FC_CLOSE) { - if (pSChan->pHandle != NULL) - retStat = arCFChanClose((AR_CHAN_DESC **)&pSChan->pHandle); - } - else if (funcCode == SYD_FC_FILEINFO) { - TS_STAMP oldestStamp, newestStamp; - char oldestStampText[28], newestStampText[28]; - char name[db_name_dim]; - int j; - - assert(pCfDesc != NULL); - if (ArB0MIHead(pCfDesc) != 0) { - AR_MI_BUF *pMICurrent; - AR_CHAN_HDR *pChanHdr; - - assert(ArB0MIHead(pCfDesc) > 0); - assert(ArB0MITail(pCfDesc) > 0); - assert(ArB0MINblk(pCfDesc) > 0); - assert(pCfDesc->pMIHead != NULL); - assert(pCfDesc->pMITail != NULL); - - pMICurrent = pCfDesc->pMIHead; - while (pMICurrent != NULL) { - int i; - - for (i=0; ichanHdr[i]; - - if (pChanHdr->name[0] != '\0') { - strcpy(name, pChanHdr->name); - j = strlen(name); - if (j > 4) { - if (strncmp(&name[j-4], ".VAL", 4) == 0) - name[j-4] = '\0'; - } - oldestStamp.secPastEpoch = pChanHdr->oldestSecPastEpoch; - oldestStamp.nsec = 0; - newestStamp.secPastEpoch = pChanHdr->newestSecPastEpoch; - newestStamp.nsec = 0; - (void)fprintf((FILE *)pArg, "%s %d %s %s %s\n", - name, pChanHdr->elCount, - dbf_type_to_text(pChanHdr->chanType), - tsStampToText(&oldestStamp, TS_TEXT_MMDDYY, - oldestStampText), - tsStampToText(&newestStamp, TS_TEXT_MMDDYY, - newestStampText) ); - } - } - pMICurrent = pMICurrent->pNextMI; - } - } - else - (void)fprintf((FILE *)pArg, "no channels in file\n"); - } - else if (funcCode == SYD_FC_WRAPUP) { - if (pCfDesc != NULL) { - if ((stat = arCFClose(&pCfDesc)) != OK) { - (void)printf("trouble closing arChan/arChanData.bin\n"); - retStat = S_syd_ERROR; - } - } - pSspec->pHandle = NULL; - } - - return retStat; -} - -long -sydCFFuncGetGR(pSChan, pChanDesc) -SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ -AR_CHAN_DESC *pChanDesc; /* pointer to chanDesc for channel */ -{ - int i; - - if (pSChan->dbrType == DBR_TIME_FLOAT) { -#define FLT_SRC ArCDChanHdr(pChanDesc).graphics.floatGr -#define FLT_DEST pSChan->grBuf.gfltval - FLT_DEST.status = NO_ALARM; - FLT_DEST.severity = NO_ALARM; - FLT_DEST.precision = FLT_SRC.precision; - (void)strcpy(FLT_DEST.units, FLT_SRC.units); - FLT_DEST.upper_disp_limit = FLT_SRC.upDispLim; - FLT_DEST.lower_disp_limit = FLT_SRC.lowDispLim; - FLT_DEST.upper_alarm_limit = FLT_SRC.upAlmLim; - FLT_DEST.lower_alarm_limit = FLT_SRC.lowAlmLim; - FLT_DEST.upper_warning_limit = FLT_SRC.upWarnLim; - FLT_DEST.lower_warning_limit = FLT_SRC.lowWarnLim; - pSChan->dbrGrType = DBR_GR_FLOAT; - } - else if (pSChan->dbrType == DBR_TIME_SHORT) { -#define SHRT_SRC ArCDChanHdr(pChanDesc).graphics.shortGr -#define SHRT_DEST pSChan->grBuf.gshrtval - SHRT_DEST.status = NO_ALARM; - SHRT_DEST.severity = NO_ALARM; - (void)strcpy(SHRT_DEST.units, SHRT_SRC.units); - SHRT_DEST.upper_disp_limit = SHRT_SRC.upDispLim; - SHRT_DEST.lower_disp_limit = SHRT_SRC.lowDispLim; - SHRT_DEST.upper_alarm_limit = SHRT_SRC.upAlmLim; - SHRT_DEST.lower_alarm_limit = SHRT_SRC.lowAlmLim; - SHRT_DEST.upper_warning_limit = SHRT_SRC.upWarnLim; - SHRT_DEST.lower_warning_limit = SHRT_SRC.lowWarnLim; - pSChan->dbrGrType = DBR_GR_SHORT; - } - else if (pSChan->dbrType == DBR_TIME_DOUBLE) { -#define DBL_SRC ArCDChanHdr(pChanDesc).graphics.doubleGr -#define DBL_DEST pSChan->grBuf.gdblval - DBL_DEST.status = NO_ALARM; - DBL_DEST.severity = NO_ALARM; - DBL_DEST.precision = DBL_SRC.precision; - (void)strcpy(DBL_DEST.units, DBL_SRC.units); - DBL_DEST.upper_disp_limit = DBL_SRC.upDispLim; - DBL_DEST.lower_disp_limit = DBL_SRC.lowDispLim; - DBL_DEST.upper_alarm_limit = DBL_SRC.upAlmLim; - DBL_DEST.lower_alarm_limit = DBL_SRC.lowAlmLim; - DBL_DEST.upper_warning_limit = DBL_SRC.upWarnLim; - DBL_DEST.lower_warning_limit = DBL_SRC.lowWarnLim; - pSChan->dbrGrType = DBR_GR_DOUBLE; - } - else if (pSChan->dbrType == DBR_TIME_LONG) { -#define LNG_SRC ArCDChanHdr(pChanDesc).graphics.longGr -#define LNG_DEST pSChan->grBuf.glngval - LNG_DEST.status = NO_ALARM; - LNG_DEST.severity = NO_ALARM; - (void)strcpy(LNG_DEST.units, LNG_SRC.units); - LNG_DEST.upper_disp_limit = LNG_SRC.upDispLim; - LNG_DEST.lower_disp_limit = LNG_SRC.lowDispLim; - LNG_DEST.upper_alarm_limit = LNG_SRC.upAlmLim; - LNG_DEST.lower_alarm_limit = LNG_SRC.lowAlmLim; - LNG_DEST.upper_warning_limit = LNG_SRC.upWarnLim; - LNG_DEST.lower_warning_limit = LNG_SRC.lowWarnLim; - pSChan->dbrGrType = DBR_GR_LONG; - } - else if (pSChan->dbrType == DBR_TIME_STRING) { -#define STR_DEST pSChan->grBuf.gstrval - STR_DEST.status = NO_ALARM; - STR_DEST.severity = NO_ALARM; - pSChan->dbrGrType = DBR_GR_STRING; - } - else if (pSChan->dbrType == DBR_TIME_ENUM) { -#define ENM_SRC ArCDChanHdr(pChanDesc).graphics.enumGr -#define ENM_DEST pSChan->grBuf.genmval - ENM_DEST.status = NO_ALARM; - ENM_DEST.severity = NO_ALARM; - ENM_DEST.no_str = ArCFChanNStates(pChanDesc); - for (i=0; idbrGrType = DBR_GR_ENUM; - } - else if (pSChan->dbrType == DBR_TIME_CHAR) { -#define CHR_SRC ArCDChanHdr(pChanDesc).graphics.charGr -#define CHR_DEST pSChan->grBuf.gchrval - CHR_DEST.status = NO_ALARM; - CHR_DEST.severity = NO_ALARM; - (void)strcpy(CHR_DEST.units, CHR_SRC.units); - CHR_DEST.upper_disp_limit = CHR_SRC.upDispLim; - CHR_DEST.lower_disp_limit = CHR_SRC.lowDispLim; - CHR_DEST.upper_alarm_limit = CHR_SRC.upAlmLim; - CHR_DEST.lower_alarm_limit = CHR_SRC.lowAlmLim; - CHR_DEST.upper_warning_limit = CHR_SRC.upWarnLim; - CHR_DEST.lower_warning_limit = CHR_SRC.lowWarnLim; - pSChan->dbrGrType = DBR_GR_CHAR; - } - return S_syd_OK; -} diff --git a/src/libCom/sydSubrPFO.c b/src/libCom/sydSubrPFO.c deleted file mode 100644 index 5203a0a04..000000000 --- a/src/libCom/sydSubrPFO.c +++ /dev/null @@ -1,227 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 12-04-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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: - * ----------------- - * .00 12-04-90 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 06-19-91 rac replace with - * .03 02-27-92 rac do ts rounding here instead of sydSubr.c - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE sydSubrPFO.c - acquire synchronous samples from `gsd_...' routines -* -* DESCRIPTION -* -*-***************************************************************************/ -#include -#define SYD_PRIVATE -#include -#include -#ifndef INC_tsDefs_h -# include -#endif -#ifndef INCLcadefh -# include -#endif -#include -#define PFO_CHAN_DEF -#include - -#ifdef vxWorks -# include -# include /* for O_RDWR and O_RDONLY definitions */ -# include -#else -# include -# include /* for O_RDWR and O_RDONLY definitions */ -#endif - -long sydPFOFunc(); -long sydPFOFuncGetGR(); - -long -sydOpenPFO(ppSspec, pHandle) -SYD_SPEC **ppSspec; /* O pointer to synchronous set spec pointer */ -void *pHandle; /* I pointer to handle for "source" */ -{ - long stat; - - assert(ppSspec != NULL); - - if ((*ppSspec = (SYD_SPEC *)GenMalloc(sizeof(SYD_SPEC))) == NULL) - return S_syd_noMem; - (*ppSspec)->pFunc = sydPFOFunc; - (*ppSspec)->type = SYD_TY_PFO; - if ((stat = sydPFOFunc(*ppSspec, NULL, SYD_FC_INIT, pHandle)) != S_syd_OK){ - GenFree((char *)*ppSspec); - *ppSspec = NULL; - return stat; - } - (*ppSspec)->nInBufs = 2; - return sydOpen(ppSspec, pHandle); -} -/*+/subr********************************************************************** -* NAME sydPFOFunc - handle gsd_xxx sync data interactions -* -* DESCRIPTION -* -* sydPFOFunc(pSspec, NULL, SYD_FC_INIT, NULL) -* sydPFOFunc(pSspec, pSChan, SYD_FC_OPEN, pPfoChan) -* sydPFOFunc(pSspec, pSChan, SYD_FC_READ, NULL) -* sydPFOFunc(pSspec, pSChan, SYD_FC_POSITION, NULL) -* sydPFOFunc(pSspec, pSChan, SYD_FC_CLOSE, NULL) -* sydPFOFunc(pSspec, NULL, SYD_FC_FILEINFO, NULL) -* sydPFOFunc(pSspec, NULL, SYD_FC_WRAPUP, NULL) -* -* RETURNS -* S_syd_OK, or -* other code indicating error -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydPFOFunc(pSspec, pStruct, funcCode, pArg) -SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */ -void *pStruct; /* IO pointer to data struct used by funcCode */ -enum sydFuncCode funcCode;/* I function code */ -void *pArg; /* I pointer to arg, as required by funcCode */ -{ - SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ - PFO_CHAN *pPChan; /* pointer to pfo channel struct */ - struct gsd_sync_data *pSyn; /* pointer to pfo sync data struct */ - long retStat=S_syd_OK; - int bufNum, nBytes; - - pSChan = (SYD_CHAN *)pStruct; - - if (funcCode == SYD_FC_INIT) { - pSspec->pHandle = NULL; - } - else if (funcCode == SYD_FC_OPEN) { - pPChan = (PFO_CHAN *)pArg; - pSChan->pHandle = (void *)pPChan->pGsd; - pSChan->dbfType = ca_field_type(pPChan->pGsd->pChid); - pSChan->dbrType = pPChan->pGsd->time_type; - assert(dbr_type_is_TIME(pSChan->dbrType)); - pSChan->elCount = pPChan->pGsd->count; - sydPFOFuncGetGR(pSspec, pSChan, pPChan); - } - else if (funcCode == SYD_FC_READ) { - pSyn = (struct gsd_sync_data *)pSChan->pHandle; - if (pSyn->svalid != 0) { - bufNum = NEXT_INBUF(pSChan, pSChan->lastInBuf); - nBytes = dbr_size_n(pSChan->dbrType, pSChan->elCount); - bcopy((char *)pSyn->pSdata, (char *)pSChan->pInBuf[bufNum], nBytes); - pSChan->inStatus[bufNum] = SYD_B_FULL; - pSChan->lastInBuf = bufNum; - if (pSChan->firstInBuf < 0) - pSChan->firstInBuf = bufNum; - if (pSspec->roundNsec > 0) { - sydTsRound(&pSChan->pInBuf[bufNum]->tfltval.stamp, - pSspec->roundNsec); - } - } - } - else if (funcCode == SYD_FC_POSITION) { - ; /* no action */ - } - else if (funcCode == SYD_FC_CLOSE) { - ; /* no action */ - } - else if (funcCode == SYD_FC_FILEINFO) { - ; /* no action */ - } - else if (funcCode == SYD_FC_WRAPUP) { - pSspec->pHandle = NULL; - } - - return retStat; -} - -static long -sydPFOFuncGetGR(pSspec, pSChan, pPChan) -SYD_SPEC *pSspec; /* pointer to syncSet specification */ -SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ -PFO_CHAN *pPChan; /* pointer to pfo channel struct */ -{ - int i; - - if (pSChan->dbrType == DBR_TIME_FLOAT) { - assert(pPChan->dbrGrType == DBR_GR_FLOAT || - pPChan->dbrGrType == DBR_CTRL_FLOAT); - pSChan->grBuf.gfltval = pPChan->pDbrGr->gfltval; - pSChan->dbrGrType = DBR_GR_FLOAT; - } - else if (pSChan->dbrType == DBR_TIME_SHORT) { - assert(pPChan->dbrGrType == DBR_GR_SHORT || - pPChan->dbrGrType == DBR_CTRL_SHORT); - pSChan->grBuf.gshrtval = pPChan->pDbrGr->gshrtval; - pSChan->dbrGrType = DBR_GR_SHORT; - } - else if (pSChan->dbrType == DBR_TIME_DOUBLE) { - assert(pPChan->dbrGrType == DBR_GR_DOUBLE || - pPChan->dbrGrType == DBR_CTRL_DOUBLE); - pSChan->grBuf.gdblval = pPChan->pDbrGr->gdblval; - pSChan->dbrGrType = DBR_GR_DOUBLE; - } - else if (pSChan->dbrType == DBR_TIME_LONG) { - assert(pPChan->dbrGrType == DBR_GR_LONG || - pPChan->dbrGrType == DBR_CTRL_LONG); - pSChan->grBuf.glngval = pPChan->pDbrGr->glngval; - pSChan->dbrGrType = DBR_GR_LONG; - } - else if (pSChan->dbrType == DBR_TIME_STRING) { - assert(pPChan->dbrGrType == DBR_GR_STRING || - pPChan->dbrGrType == DBR_CTRL_STRING); - pSChan->grBuf.gstrval = pPChan->pDbrGr->gstrval; - pSChan->dbrGrType = DBR_GR_STRING; - } - else if (pSChan->dbrType == DBR_TIME_ENUM) { - assert(pPChan->dbrGrType == DBR_GR_ENUM || - pPChan->dbrGrType == DBR_CTRL_ENUM); - pSChan->grBuf.genmval = pPChan->pDbrGr->genmval; - pSChan->dbrGrType = DBR_GR_ENUM; - } - else if (pSChan->dbrType == DBR_TIME_CHAR) { - assert(pPChan->dbrGrType == DBR_GR_CHAR || - pPChan->dbrGrType == DBR_CTRL_CHAR); - pSChan->grBuf.gchrval = pPChan->pDbrGr->gchrval; - pSChan->dbrGrType = DBR_GR_FLOAT; - } - return S_syd_OK; -} diff --git a/src/libCom/sydSubrSSF.c b/src/libCom/sydSubrSSF.c deleted file mode 100644 index 4ae16d6a4..000000000 --- a/src/libCom/sydSubrSSF.c +++ /dev/null @@ -1,1094 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 12-04-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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: - * ----------------- - * .00 12-04-90 rac initial version - * .01 06-18-91 rac installed in SCCS - * .02 06-19-91 rac replace with - * .03 08-14-91 rac - * .04 02-27-92 rac do ts rounding here instead of sydSubr.c - * .05 08-18-92 rac add SYD_FC_STOP function code - * .06 09-09-92 rac allow reading text values such as `no data'; look at - * the _end_ of the file to do name searches; handle - * channels which are missing and/or disconnected; - * discontinue use of special malloc routines - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code - */ -/*+/mod*********************************************************************** -* TITLE sydSubrSSF.c - acquire synchronous samples from AR `sample set' files -* -* DESCRIPTION -* -*-***************************************************************************/ -#include -#define SYD_PRIVATE -#include -#include -#ifndef INC_tsDefs_h -# include -#endif -#ifndef INCLcadefh -# include -#endif - -#ifdef vxWorks -# include -# include /* for O_RDWR and O_RDONLY definitions */ -# include -# include -#else -# include -# include /* for O_RDWR and O_RDONLY definitions */ -# include -# include -#endif - -long sydSSFFunc(); -static long sydSSFFuncGetGR(); -static long sydSSFFuncReadData(); -static long sydSSFFuncSeekSample(); -static long sydSSFFuncSeekStamp(); - -/*+/macro********************************************************************* -* NAME posXxx - text file search and positioning routines -* -* DESCRIPTION -* These routines allow setting the position for text files. The -* file may be positioned at its beginning or its end. It is -* supported to search, either forward or backward, for a string, -* leaving the file positioned at the beginning of the string. -* -* long pos; -* FILE *pStream; -* -* pos = posBOF(pStream); -* pos = posEOF(pStream); -* pos = posKeyFwd("key", pStream); -* pos = posKeyRev("key", pStream, pos); -* pos = posPos(pStream, pos); -* -* RETURNS -* position, or -* <0 if an error occurs -* -* BUGS -* o the use of fseek and ftell doesn't match the Standard C specification -* and may be non-portable. They have been verified to function -* properly under SunOS 4.1 and VxWorks 4.0.2. -* -*-*/ -static long posBOF(); -static long posEOF(); -static long posKeyFwd(); -static long posKeyRev(); -static long posPos(); - -/*+/internal****************************************************************** -* NAME posBOF - position file at the beginning -* -*-*/ -static long -posBOF(pStream) -FILE *pStream; -{ - if (fseek(pStream, 0L, 0) < 0) { - perror("posBOF: fseek error"); - return -1; - } - return ftell(pStream); -} -/*+/internal****************************************************************** -* NAME posEOF - position file at the end -* -*-*/ -static long -posEOF(pStream) -FILE *pStream; -{ - if (fseek(pStream, 0L, 2) < 0) { - perror("posEOF: fseek error"); - return -1; - } - return ftell(pStream); -} -/*+/internal****************************************************************** -* NAME posKeyFwd - search forward for a string -* -* RETURNS -* position of key (its first character), or -* -1 if search fails -* -*-*/ -static long -posKeyFwd(key, pStream) -char *key; -FILE *pStream; -{ - int i, lastChar; - int c; - long pos; - - lastChar = strlen(key) - 1; - i = 0; - - if ((pos = ftell(pStream)) < 0) { - if (!feof(pStream)) - perror("posKeyFwd: ftell error"); - return -1; - } - - while (1) { - if ((c = fgetc(pStream)) == EOF) - return -1; - if ((char)c == key[i]) { - if (i == lastChar) - break; - i++; - } - else { - if (i == 0) { - if ((pos = ftell(pStream)) < 0) { - if (!feof(pStream)) - perror("posKeyFwd: ftell error"); - return -1; - } - } - else if (i == 1) { - pos++; - if ((char)c != key[0]) - i = 0; - } - else { - pos++; - if (fseek(pStream, pos, 0) != 0) { - if (!feof(pStream)) - perror("posKeyFwd: fseek error"); - return -1; - } - i = 0; - } - } - } - if (fseek(pStream, pos, 0) != 0) { - if (!feof(pStream)) - perror("posKeyFwd: fseek error"); - return -1; - } - return pos; -} -/*+/internal****************************************************************** -* NAME posKeyRev - search backward for a string -* -* RETURNS -* position of key (its first character), or -* -1 if search fails -* -*-*/ -static long -posKeyRev(key, pStream, lastPos) -char *key; -FILE *pStream; -long lastPos; /* I position to start search; -1 for EOF */ -{ - int i, lastChar; - int c; - long pos; - - lastChar = i = strlen(key) - 1; - - if (lastPos >= 0) { - if (fseek(pStream, lastPos, 0) != 0) { - if (!feof(pStream)) - perror("posKeyRev: fseek error"); - return -1; - } - } - else { - if (fseek(pStream, 0L, 2) != 0) { - if (!feof(pStream)) - perror("posKeyRev: fseek error"); - return -1; - } - } - while (1) { - if (ftell(pStream) <= 0) - return -1; - if (fseek(pStream, -1L, 1) != 0) { - if (!feof(pStream)) - perror("posKeyRev: fseek error"); - return -1; - } - if ((c = fgetc(pStream)) == EOF) - return -1; - if (fseek(pStream, -1L, 1) != 0) { - if (!feof(pStream)) - perror("posKeyRev: fseek error"); - return -1; - } - if ((char)c == key[i]) { - if (i == 0) - break; - i--; - } - else - i = lastChar; - } - if ((pos = ftell(pStream)) < 0) - perror("posKeyRev: ftell error"); - return pos; -} -/*+/internal****************************************************************** -* NAME posPos - set file to desired position -* -*-*/ -static long -posPos(pStream, pos) -FILE *pStream; -long pos; -{ - if (fseek(pStream, pos, 0) < 0) { - perror("posPos: fseek error"); - return -1; - } - return ftell(pStream); -} - -/*+/subr********************************************************************** -* NAME sydOpenSSF -* -*-*/ -long -sydOpenSSF(ppSspec, filePath) -SYD_SPEC **ppSspec; /* O pointer to synchronous set spec pointer */ -char *filePath; /* I path name for `sample set' archive file */ -{ - long stat; - - assert(ppSspec != NULL); - - if ((*ppSspec = (SYD_SPEC *)malloc(sizeof(SYD_SPEC))) == NULL) - return S_syd_noMem; - (*ppSspec)->pFunc = sydSSFFunc; - (*ppSspec)->type = SYD_TY_SSF; - if ((stat = sydSSFFunc(*ppSspec, NULL,SYD_FC_INIT,filePath)) != S_syd_OK){ - free((char *)*ppSspec); - *ppSspec = NULL; - return stat; - } - (*ppSspec)->nInBufs = 2; - return sydOpen(ppSspec); -} -/*+/subr********************************************************************** -* NAME sydSSFFunc - handle "sample set" data file interactions -* -* DESCRIPTION -* -* sydSSFFunc(pSspec, NULL, SYD_FC_INIT, filePath) open "sample set" file -* sydSSFFunc(pSspec, pSChan, SYD_FC_OPEN, NULL) chanName already in pSChan -* sydSSFFunc(pSspec, pSChan, SYD_FC_READ, NULL) -* sydSSFFunc(pSspec, pSChan, SYD_FC_POSITION, &stamp) -* sydSSFFunc(pSspec, pSChan, SYD_FC_CLOSE, NULL) -* sydSSFFunc(pSspec, NULL, SYD_FC_FILEINFO, outStream) -* sydSSFFunc(pSspec, NULL, SYD_FC_WRAPUP, NULL) close "sample set" file -* -* RETURNS -* S_syd_OK, or -* S_syd_EOF, or -* other code indicating error -* -* BUGS -* o doesn't detect or report EOF -* o doesn't do anything (or even detect) overwriting un-sampled -* buffers (for SYD_FC_READ) -* o needs a "get graphics information" function and function code -* o if a channel wasn't connected when the last snapshot in the file -* was written, its elCount is assumed to be 1 -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydSSFFunc(pSspec, pStruct, funcCode, pArg) -SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */ -void *pStruct; /* IO pointer to data struct used by funcCode */ -enum sydFuncCode funcCode;/* I function code */ -void *pArg; /* I pointer to arg, as required by funcCode */ -{ - SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ - FILE *ssFile; /* file pointer for sample set data file */ - long retStat=S_syd_OK; - long stat; - int i; - long pos; - char record[120]; - char recDelim; - char *pRecord; - char *pField; - char delim; - char chanName[db_name_dim+2]; - chtype type; - int elCount; - - pSChan = (SYD_CHAN *)pStruct; - if (pSspec != NULL) - ssFile = (FILE *)pSspec->pHandle; - - if (funcCode == SYD_FC_INIT) { - if ((ssFile = fopen((char *)pArg, "r")) == NULL) { - (void)printf("couldn't open %s\n", (char *)pArg); - perror(NULL); - retStat = S_syd_ERROR; - } - pSspec->pHandle = (void *)ssFile; - } - else if (funcCode == SYD_FC_OPEN) { - if ((pos = posKeyRev("%endHeader%", ssFile, -1L)) < 0) { - (void)printf("couldn't find %%endHeader%%\n"); - (void)posBOF(ssFile); - return S_syd_chanNotFound; - } - strcpy(chanName, "\n"); - strcat(chanName, pSChan->name); - strcat(chanName, " "); - if ((pos = posKeyFwd(chanName, ssFile)) < 0) - return S_syd_chanNotFound; - assert(sizeof(record) == 120); - fgetc(ssFile); /* skip over the \n */ - if (fgets(record, 120, ssFile) == NULL) - assertAlways(0); - pRecord = record; - recDelim = record[strlen(record)-1]; - if (nextChanNameField(&pRecord, &pField, &delim) <= 1) - assertAlways(0); - if (strcmp(pField, pSChan->name) != 0) - assertAlways(0); - pSChan->pHandle = NULL; - if (nextAlphField(&pRecord, &pField, &delim) <= 1) - assertAlways(0); - dbf_text_to_type(pField, type); - if (type >= 0) { - pSChan->dbfType = type; - pSChan->dbrType = dbf_type_to_DBR_TIME(type); - pSChan->dbrGrType = dbf_type_to_DBR_GR(type); - stat = sscanf(pRecord, "%*d %*d %d", &elCount); - assert(stat == 1); - pSChan->elCount = elCount; - } - else { - pSChan->dbfType = TYPENOTCONN; - pSChan->dbrType = TYPENOTCONN; - pSChan->dbrGrType = TYPENOTCONN; - pSChan->elCount = 1; - } - sydSSFFuncGetGR(pSspec, pSChan); - pSChan->sync = SYD_SY_NONF; /* force channel to be sync */ - (void)posBOF(ssFile); - } - else if (funcCode == SYD_FC_READ) { - TS_STAMP timeStamp; - enum sydBStatus bufStat, newStat; - int bufNum, oldBufNum, first=1; - char typeText[80]; - -/*----------------------------------------------------------------------------- -* find the next line with SAMPLE: and get the time stamp. When done: -* o bufStat will be one of: -* SYD_B_RESTART this sample starts a new "run" of data -* SYD_B_FULL this is an ordinary sample -* SYD_B_EOF end of file -* SYD_B_MISSING no value for this channel i nthis sample -* o the file will be positioned following the %endHeader% line -* o if time stamp rounding has been requested, it will be done -*----------------------------------------------------------------------------*/ - while (1) { - newStat = SYD_B_EMPTY; - bufStat = sydSSFFuncSeekSample(ssFile, &timeStamp); - if (pSspec->roundNsec > 0) - sydTsRound(&timeStamp, pSspec->roundNsec); - -/*----------------------------------------------------------------------------- -* now, read the actual data. This is done by processing all the data -* lines in the file, storing those which match a channel in the synchronous -* set. (This is somewhat contrary to the "advertising" for this function -* code, which implies that only a single channel is read.) When done: -* o all channels in the set will have an appropriate buffer status -* o all channels will have the same time stamp -* o all channels with data will have the data in the buffer -* o all channels will have .lastInBuf updated -*----------------------------------------------------------------------------*/ - pSChan = pSspec->pChanHead; - if (first) { - oldBufNum = pSChan->lastInBuf; - bufNum = NEXT_INBUF(pSChan, oldBufNum); - first = 0; - } - while (pSChan != NULL) { - if (bufStat != SYD_B_EOF) - pSChan->inStatus[bufNum] = SYD_B_MISSING; - else - pSChan->inStatus[bufNum] = bufStat; - pSChan->pInBuf[bufNum]->tfltval.stamp = timeStamp; - pSChan->lastInBuf = bufNum; - if (pSChan->firstInBuf < 0) - pSChan->firstInBuf = bufNum; - pSChan = pSChan->pNext; - } - if (bufStat == SYD_B_EOF) - return S_syd_EOF; - while (1) { - stat = fscanf(ssFile, "%s", chanName); - assert(stat == 1); - if ((pSChan = sydChanFind(pSspec, chanName)) != NULL) { - (void)fscanf(ssFile, "%s", typeText); - dbf_text_to_type(typeText, type); - if (pSChan->dbfType == TYPENOTCONN && type >= 0) { - pSChan->dbfType = type; - pSChan->dbrType = dbf_type_to_DBR_TIME(type); - pSChan->dbrGrType = dbf_type_to_DBR_GR(type); - sydSSFFuncGetGR(pSspec, pSChan); - } - stat = sydSSFFuncReadData(pSChan, ssFile, - bufStat, bufNum, oldBufNum, type); - if (pSChan->inStatus[bufNum] != SYD_B_MISSING && - newStat == SYD_B_EMPTY) { - newStat = pSChan->inStatus[bufNum]; - } - } - else if (strcmp(chanName, "%endData%") == 0) - break; - else { - while ((delim = fgetc(ssFile)) != EOF && delim != '\n') - ; /* keep skipping until end of line */ - } - } - if (newStat != SYD_B_EMPTY) - break; - } - } - else if (funcCode == SYD_FC_STOP) { - } - else if (funcCode == SYD_FC_POSITION) { - TS_STAMP *pStamp; - TS_STAMP stamp, earlyStamp; - long earlyPos; - - pStamp = (TS_STAMP *)pArg; - if (pStamp == NULL) { - (void)posBOF(ssFile); - return retStat; - } -/*----------------------------------------------------------------------------- -* find 2 adjacent samples to make it easy to determine which way to -* search. There are several cases: -* 1. the file is at least 2 away from EOF and both stamps can be found -* forward -* 2. the file is 1 away from EOF--1 stamp backward and 1 forward -* 3. the file contains no stamps -* 4. the file is at EOF and both stamps must be found backward -* 5. the file only contains one stamp -* -* Cases 2 and 4 are treated by rewinding the file to avoid any backward -* searching. This transforms those cases into one of the other cases. -* -* When this section is done, `earlyStamp' and `stamp' will contain two -* adjacent stamps. If they are equal, then case 4 exists. The file -* will be positioned following `stamp'. -*----------------------------------------------------------------------------*/ - earlyPos = sydSSFFuncSeekStamp(ssFile, &earlyStamp, 0, 0L); - pos = sydSSFFuncSeekStamp(ssFile, &stamp, 0, 0L); - if (earlyPos < 0 || pos < 0) { - (void)posBOF(ssFile); - earlyPos = sydSSFFuncSeekStamp(ssFile, &earlyStamp, 0, 0L); - if ((pos = sydSSFFuncSeekStamp(ssFile, &stamp, 0, 0L)) < 0) { - stamp = earlyStamp; - pos = earlyPos; - } - } - if (earlyPos < 0) - return S_syd_ERROR; - if (TsCmpStampsLT(pStamp, &earlyStamp)) { - (void)posBOF(ssFile); - earlyPos = sydSSFFuncSeekStamp(ssFile, &earlyStamp, 0, 0L); - if ((pos = sydSSFFuncSeekStamp(ssFile, &stamp, 0, 0L)) < 0) { - stamp = earlyStamp; - pos = earlyPos; - } - } - if (earlyPos < 0) - return S_syd_ERROR; -/*----------------------------------------------------------------------------- -* now, find the record with the proper time stamp, going forward -*----------------------------------------------------------------------------*/ - while (1) { - if (TsCmpStampsLE(pStamp, &earlyStamp)) - break; - else if (TsCmpStampsLE(pStamp, &stamp) && - TsCmpStampsGE(pStamp, &earlyStamp)) { - if (TsCmpStampsEQ(pStamp, &earlyStamp)) { - stamp = earlyStamp; - pos = earlyPos; - } - break; - } - else if (TsCmpStampsEQ(&earlyStamp, &stamp)) - break; - else if (TsCmpStampsGT(pStamp, &stamp)) { - earlyStamp = stamp; - earlyPos = pos; - pos = sydSSFFuncSeekStamp(ssFile, &stamp, 0, earlyPos); - if (pos < 0) { - stamp = earlyStamp; - pos = earlyPos; - } - } - } -/*----------------------------------------------------------------------------- -* finally, position the file at the proper record -*----------------------------------------------------------------------------*/ - if (TsCmpStampsGT(pStamp, &stamp)) - return S_syd_EOF; - if (TsCmpStampsLE(pStamp, &earlyStamp)) - (void)posPos(ssFile, earlyPos); - else - (void)posPos(ssFile, pos); - } - else if (funcCode == SYD_FC_CLOSE) { - ; /* no action to close a channel in sample set files */ - } - else if (funcCode == SYD_FC_FILEINFO) { - TS_STAMP oldestStamp; - char oldestStampText[28]; - TS_STAMP newestStamp; - char newestStampText[28]; - int j; - - if (posBOF(ssFile) < 0) { - (void)fprintf((FILE *)pArg, "error positioning file\n"); - return S_syd_ERROR; - } - if (sydSSFFuncSeekStamp(ssFile, &oldestStamp, 0, 0L) < 0) { - (void)fprintf((FILE *)pArg, "error finding oldest time stamp\n"); - return S_syd_ERROR; - } - if (sydSSFFuncSeekStamp(ssFile, &newestStamp, 1, -1L) < 0) { - (void)fprintf((FILE *)pArg, "error finding newest time stamp\n"); - return S_syd_ERROR; - } - (void)fprintf((FILE *)pArg, "data from %s through %s\n", - tsStampToText(&oldestStamp, TS_TEXT_MMDDYY, oldestStampText), - tsStampToText(&newestStamp, TS_TEXT_MMDDYY, newestStampText) ); - if (posKeyRev("%endHeader%", ssFile, -1L) < 0) { - (void)fprintf((FILE *)pArg, - "error locating %%endHeader%% in file\n"); - return S_syd_ERROR; - } - (void)fgets(record, 120, ssFile); /* skip over endHeader */ - while (1) { - if (fgets(record, 120, ssFile) == NULL) { - (void)fprintf((FILE *)pArg, "error reading channel name\n"); - return S_syd_ERROR; - } - pRecord = record; - recDelim = record[strlen(record)-1]; - if (nextChanNameField(&pRecord, &pField, &delim) <= 1) { - (void)fprintf((FILE *)pArg, "error reading channel type\n"); - return S_syd_ERROR; - } - if (strcmp(pField, "%endData%") == 0) - break; - (void)strcpy(chanName, pField); - if (nextAlphField(&pRecord, &pField, &delim) <= 1) { - (void)fprintf((FILE *)pArg, "error reading channel type\n"); - return S_syd_ERROR; - } - if (sscanf(pRecord, "%*d %*d %d", &elCount) != 1) { - (void)fprintf((FILE *)pArg, "error reading element count\n"); - return S_syd_ERROR; - } - j = strlen(chanName); - if (j > 4) { - if (strncmp(&chanName[j-4], ".VAL", 4) == 0) - chanName[j-4] = '\0'; - } - - (void)fprintf((FILE *)pArg, "%s %d %s\n", - chanName, elCount, pField); - if (recDelim != '\n') { - while ((delim = fgetc(ssFile)) != EOF && delim != '\n') - ; /* keep skipping until end of line */ - } - } - if (posBOF(ssFile) < 0) { - (void)fprintf((FILE *)pArg, "error positioning file\n"); - return S_syd_ERROR; - } - } - else if (funcCode == SYD_FC_WRAPUP) { - if (ssFile != NULL) - (void)close(ssFile); - pSspec->pHandle = NULL; - } - - return retStat; -} - -/*+/internal****************************************************************** -* NAME sydSSFFuncReadData -* -* DESCRIPTION -* Read data from the file into the sync set. An entire snapshot is -* read. For each channel in the snapshot, the data is stored in the -* sync set only if the channel is in the set. -* -* BUGS -* o if a channel has a smaller elCount in the file than in the sync set, -* then the `extra' values in the sync set will be garbage -* -*-*/ -static long -sydSSFFuncReadData(pSChan, ssFile, bufStat, bufNum, oldBufNum, type) -SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ -FILE *ssFile; -int bufStat, bufNum, oldBufNum; -chtype type; -{ - long stat; - int alStat, alSev, elCount; - int i; - -/*----------------------------------------------------------------------------- -* first, get and store the alarm status and severity . -* (This is done using the "float" form of the buffer, which is -* possible because for these items all types of buffers look the same.) -*----------------------------------------------------------------------------*/ - stat = fscanf(ssFile, "%d%d%d", &alSev, &alStat, &elCount); - assert(stat == 3); - pSChan->pInBuf[bufNum]->tfltval.status = alStat; - pSChan->pInBuf[bufNum]->tfltval.severity = alSev; -/*----------------------------------------------------------------------------- -* now get the actual data -*----------------------------------------------------------------------------*/ - if (pSChan->dbrType == TYPENOTCONN || type == TYPENOTCONN) { - stat = fscanf(ssFile, "%*s"); - bufStat = SYD_B_MISSING; - } - else if (pSChan->dbrType == DBR_TIME_FLOAT) { - float *pFl, val; - pFl = &pSChan->pInBuf[bufNum]->tfltval.value; - for (i=0; ielCount) - *pFl++ = val; - } - } - else if (pSChan->dbrType == DBR_TIME_SHORT) { - short *pSh, val; - pSh = &pSChan->pInBuf[bufNum]->tshrtval.value; - for (i=0; ielCount) - *pSh++ = val; - } - } - else if (pSChan->dbrType == DBR_TIME_DOUBLE) { - double *pDbl, val; - pDbl = &pSChan->pInBuf[bufNum]->tdblval.value; - for (i=0; ielCount) - *pDbl++ = val; - } - } - else if (pSChan->dbrType == DBR_TIME_LONG) { - long *pL, val; - pL = &pSChan->pInBuf[bufNum]->tlngval.value; - for (i=0; ielCount) - *pL++ = val; - } - } - else if (pSChan->dbrType == DBR_TIME_STRING) { - char *pC, val[db_strval_dim]; - int nChar; - pC = pSChan->pInBuf[bufNum]->tstrval.value; - for (i=0; i 0 && nChar < db_strval_dim); - if (fgets(val, nChar, ssFile) == NULL) - assertAlways(0); - if (i < (int) pSChan->elCount) { - strcpy(pC, val); - pC += db_strval_dim; - } - } - } - else if (pSChan->dbrType == DBR_TIME_CHAR) { - unsigned char *pC, val; - pC = &pSChan->pInBuf[bufNum]->tchrval.value; - for (i=0; ielCount) - *pC++ = val; - } - } - else if (pSChan->dbrType == DBR_TIME_ENUM) { - unsigned short *pSh; - char state[80]; - int iState; - pSh = &pSChan->pInBuf[bufNum]->tenmval.value; - for (i=0; i= pSChan->grBuf.genmval.no_str) { - pSChan->grBuf.genmval.no_str++; - (void)strcpy(pSChan->grBuf.genmval.strs[iState], state); - break; - } - else if (strcmp(pSChan->grBuf.genmval.strs[iState],state) == 0) - break; - iState++; - assert(iState < db_state_dim); - } - if (i < (int) pSChan->elCount) - *pSh++ = iState; - } - } -/*----------------------------------------------------------------------------- -* set the buffer status. If the previous record had a status of MISSING, -* then the buffer status will be SYD_B_RESTART; otherwise, the caller's -* status will be used. (Unless, of course, this routine discovered that -* the status needs to be something else.) -*----------------------------------------------------------------------------*/ - if (bufStat == SYD_B_MISSING) - pSChan->inStatus[bufNum] = bufStat; - else if (oldBufNum >= 0 && pSChan->inStatus[oldBufNum] == SYD_B_MISSING) - pSChan->inStatus[bufNum] = SYD_B_RESTART; - else - pSChan->inStatus[bufNum] = bufStat; - - return S_syd_OK; -} - -/*+/internal****************************************************************** -* NAME sydSSFFuncGetGR - simulate getting graphics information -* -*-*/ -static long -sydSSFFuncGetGR(pSspec, pSChan) -SYD_SPEC *pSspec; /* pointer to syncSet specification */ -SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */ -{ - int i; - - if (pSChan->dbrType == DBR_TIME_FLOAT) { -#define FLT_DEST pSChan->grBuf.gfltval - FLT_DEST.status = NO_ALARM; - FLT_DEST.severity = NO_ALARM; -#if 1 - FLT_DEST.precision = 3; - (void)strcpy(FLT_DEST.units, " "); - FLT_DEST.upper_disp_limit = 0.; - FLT_DEST.lower_disp_limit = 0.; - FLT_DEST.upper_alarm_limit = 0.; - FLT_DEST.lower_alarm_limit = 0.; - FLT_DEST.upper_warning_limit = 0.; - FLT_DEST.lower_warning_limit = 0.; -#else -#define FLT_SRC ArCDChanHdr(pChanDesc).graphics.floatGr - (void)strcpy(FLT_DEST.units, FLT_SRC.units); - FLT_DEST.upper_disp_limit = FLT_SRC.upDispLim; - FLT_DEST.lower_disp_limit = FLT_SRC.lowDispLim; - FLT_DEST.upper_alarm_limit = FLT_SRC.upAlmLim; - FLT_DEST.lower_alarm_limit = FLT_SRC.lowAlmLim; - FLT_DEST.upper_warning_limit = FLT_SRC.upWarnLim; - FLT_DEST.lower_warning_limit = FLT_SRC.lowWarnLim; -#endif - } - else if (pSChan->dbrType == DBR_TIME_SHORT) { -#define SHRT_DEST pSChan->grBuf.gshrtval - SHRT_DEST.status = NO_ALARM; - SHRT_DEST.severity = NO_ALARM; -#if 1 - (void)strcpy(SHRT_DEST.units, " "); - SHRT_DEST.upper_disp_limit = 0; - SHRT_DEST.lower_disp_limit = 0; - SHRT_DEST.upper_alarm_limit = 0; - SHRT_DEST.lower_alarm_limit = 0; - SHRT_DEST.upper_warning_limit = 0; - SHRT_DEST.lower_warning_limit = 0; -#else -#define SHRT_SRC ArCDChanHdr(pChanDesc).graphics.shortGr - (void)strcpy(SHRT_DEST.units, SHRT_SRC.units); - SHRT_DEST.upper_disp_limit = SHRT_SRC.upDispLim; - SHRT_DEST.lower_disp_limit = SHRT_SRC.lowDispLim; - SHRT_DEST.upper_alarm_limit = SHRT_SRC.upAlmLim; - SHRT_DEST.lower_alarm_limit = SHRT_SRC.lowAlmLim; - SHRT_DEST.upper_warning_limit = SHRT_SRC.upWarnLim; - SHRT_DEST.lower_warning_limit = SHRT_SRC.lowWarnLim; -#endif - } - else if (pSChan->dbrType == DBR_TIME_DOUBLE) { -#define DBL_DEST pSChan->grBuf.gdblval - DBL_DEST.status = NO_ALARM; - DBL_DEST.severity = NO_ALARM; -#if 1 - DBL_DEST.precision = 3; - (void)strcpy(DBL_DEST.units, " "); - DBL_DEST.upper_disp_limit = 0.; - DBL_DEST.lower_disp_limit = 0.; - DBL_DEST.upper_alarm_limit = 0.; - DBL_DEST.lower_alarm_limit = 0.; - DBL_DEST.upper_warning_limit = 0.; - DBL_DEST.lower_warning_limit = 0.; -#else -#define DBL_SRC ArCDChanHdr(pChanDesc).graphics.doubleGr - (void)strcpy(DBL_DEST.units, DBL_SRC.units); - DBL_DEST.upper_disp_limit = DBL_SRC.upDispLim; - DBL_DEST.lower_disp_limit = DBL_SRC.lowDispLim; - DBL_DEST.upper_alarm_limit = DBL_SRC.upAlmLim; - DBL_DEST.lower_alarm_limit = DBL_SRC.lowAlmLim; - DBL_DEST.upper_warning_limit = DBL_SRC.upWarnLim; - DBL_DEST.lower_warning_limit = DBL_SRC.lowWarnLim; -#endif - } - else if (pSChan->dbrType == DBR_TIME_LONG) { -#define LNG_DEST pSChan->grBuf.glngval - LNG_DEST.status = NO_ALARM; - LNG_DEST.severity = NO_ALARM; -#if 1 - (void)strcpy(LNG_DEST.units, " "); - LNG_DEST.upper_disp_limit = 0; - LNG_DEST.lower_disp_limit = 0; - LNG_DEST.upper_alarm_limit = 0; - LNG_DEST.lower_alarm_limit = 0; - LNG_DEST.upper_warning_limit = 0; - LNG_DEST.lower_warning_limit = 0; -#else -#define LNG_SRC ArCDChanHdr(pChanDesc).graphics.longGr - (void)strcpy(LNG_DEST.units, LNG_SRC.units); - LNG_DEST.upper_disp_limit = LNG_SRC.upDispLim; - LNG_DEST.lower_disp_limit = LNG_SRC.lowDispLim; - LNG_DEST.upper_alarm_limit = LNG_SRC.upAlmLim; - LNG_DEST.lower_alarm_limit = LNG_SRC.lowAlmLim; - LNG_DEST.upper_warning_limit = LNG_SRC.upWarnLim; - LNG_DEST.lower_warning_limit = LNG_SRC.lowWarnLim; -#endif - } - else if (pSChan->dbrType == DBR_TIME_STRING) { -#define STR_DEST pSChan->grBuf.gstrval - STR_DEST.status = NO_ALARM; - STR_DEST.severity = NO_ALARM; - } - else if (pSChan->dbrType == DBR_TIME_ENUM) { -#define ENM_DEST pSChan->grBuf.genmval - ENM_DEST.status = NO_ALARM; - ENM_DEST.severity = NO_ALARM; -#if 1 - ENM_DEST.no_str = 0; -#else -#define ENM_SRC ArCDChanHdr(pChanDesc).graphics.enumGr - ENM_DEST.no_str = ArCFChanNStates(pChanDesc); - for (i=0; idbrType == DBR_TIME_CHAR) { -#define CHR_DEST pSChan->grBuf.gchrval - CHR_DEST.status = NO_ALARM; - CHR_DEST.severity = NO_ALARM; - (void)strcpy(CHR_DEST.units, " "); -#if 1 - CHR_DEST.upper_disp_limit = 0; - CHR_DEST.lower_disp_limit = 0; - CHR_DEST.upper_alarm_limit = 0; - CHR_DEST.lower_alarm_limit = 0; - CHR_DEST.upper_warning_limit = 0; - CHR_DEST.lower_warning_limit = 0; -#else -#define CHR_SRC ArCDChanHdr(pChanDesc).graphics.charGr - (void)strcpy(CHR_DEST.units, CHR_SRC.units); - CHR_DEST.upper_disp_limit = CHR_SRC.upDispLim; - CHR_DEST.lower_disp_limit = CHR_SRC.lowDispLim; - CHR_DEST.upper_alarm_limit = CHR_SRC.upAlmLim; - CHR_DEST.lower_alarm_limit = CHR_SRC.lowAlmLim; - CHR_DEST.upper_warning_limit = CHR_SRC.upWarnLim; - CHR_DEST.lower_warning_limit = CHR_SRC.lowWarnLim; -#endif - } - return S_syd_OK; -} - -/*+/internal****************************************************************** -* NAME sydSSFFuncSeekStamp - find a `SAMPLE: at' line -* -* DESCRIPTION -* Find a `SAMPLE: at' line and get the time stamp from it. -* -* If the search is forward, the file is left positioned following -* the stamp. If backward, the position is at the beginning of the -* line. -* -* RETURNS -* position of the line -* -*-*/ -static long -sydSSFFuncSeekStamp(ssFile, pStamp, revFlag, pos) -FILE *ssFile; -TS_STAMP *pStamp; -int revFlag; /* I 1 says seek in reverse direction */ -long pos; /* I position to start search if reverse; -1 - says to start at EOF */ -{ - long bufStat; - char record[120], recDelim; - char *pRecord, *pField, delim; - long stat; - - if (revFlag) - pos = posKeyRev("SAMPLE: at", ssFile, pos); - else - pos = posKeyFwd("SAMPLE: at", ssFile); - if (pos < 0) - return pos; - assert(sizeof(record) == 120); - if (fgets(record, 120, ssFile) == NULL) - return -1; - - pRecord = record; - recDelim = record[strlen(record)-1]; - if (nextNonSpaceField(&pRecord, &pField, &delim) <= 1) - assertAlways(0); - if (strcmp(pField, "SAMPLE:") != 0) - assertAlways(0); - if (nextNonSpaceField(&pRecord, &pField, &delim) <= 1) - assertAlways(0); - if (strcmp(pField, "at") != 0) - assertAlways(0); - stat = tsTextToStamp(pStamp, &pRecord); - assert(stat == S_ts_OK); - if (revFlag) { - if (posPos(ssFile, pos) < 0) - assertAlways(0); - } - return pos; -} - -/*+/internal****************************************************************** -* NAME sydSSFFuncSeekSample - find the next sample -* -* DESCRIPTION -* Finds the next `SAMPLE: at' line, gets the time stamp for the -* sample, and gets the `status' for the snapshot. The file is -* positioned following the %endHeader%, ready for reading the data. -* -* RETURNS -* SYD_B_RESTART if `initial' was specified on the `SAMPLE: at' line, or -* SYD_B_FULL -* -*-*/ -static long -sydSSFFuncSeekSample(ssFile, pStamp) -FILE *ssFile; -TS_STAMP *pStamp; -{ - long pos; - long bufStat; - char record[120], recDelim; - char *pRecord, *pField, delim; - long stat; - - if ((pos = posKeyFwd("SAMPLE: at", ssFile)) < 0) - return SYD_B_EOF; - assert(sizeof(record) == 120); - if (fgets(record, 120, ssFile) == NULL) - return SYD_B_EOF; - - pRecord = record; - recDelim = record[strlen(record)-1]; - if (nextNonSpaceField(&pRecord, &pField, &delim) <= 1) - assertAlways(0); - if (strcmp(pField, "SAMPLE:") != 0) - assertAlways(0); - if (nextNonSpaceField(&pRecord, &pField, &delim) <= 1) - assertAlways(0); - if (strcmp(pField, "at") != 0) - assertAlways(0); - stat = tsTextToStamp(pStamp, &pRecord); - assert(stat == S_ts_OK); - while (*pRecord == '-') - pRecord++; - if (strncmp(pRecord, "initial", 7) == 0) - bufStat = SYD_B_RESTART; - else - bufStat = SYD_B_FULL; - if (recDelim != '\n') { - while ((delim = fgetc(ssFile)) != EOF && delim != '\n') - ; /* keep skipping until end of line */ - } - if (posKeyFwd("%endHeader%", ssFile) < 0) - return SYD_B_EOF; - else if (fgets(record, 120, ssFile) == NULL) - return SYD_B_EOF; - return bufStat; -} diff --git a/src/libCom/timer/osiTimer.cpp b/src/libCom/timer/osiTimer.cpp deleted file mode 100644 index 35e4b173e..000000000 --- a/src/libCom/timer/osiTimer.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* - * $Id$ - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - * 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 - * - * - * History - * $Log$ - * Revision 1.8 1997/06/25 05:45:54 jhill - * cleaned up pc port - * - * Revision 1.7 1997/04/10 19:45:34 jhill - * API changes and include with not <> - * - * Revision 1.6 1996/11/02 02:06:58 jhill - * fixed several subtle problems - * - * Revision 1.5 1996/09/16 21:19:25 jhill - * removed unused variable - * - * Revision 1.4 1996/08/05 21:51:11 jhill - * fixed delete this confusion - * - * Revision 1.3 1996/07/24 23:01:53 jhill - * use iter.remove() - * - * Revision 1.2 1996/07/09 23:00:06 jhill - * force timer into limbo state during delete - * - * Revision 1.1 1996/06/26 22:14:13 jhill - * added new src files - * - * Revision 1.1.1.1 1996/06/20 00:28:15 jhill - * ca server installation - * - */ - -// -// NOTES: -// 1) this should use a binary tree to speed up inserts? -// 2) when making this safe for multi threading consider the possibility of -// object delete just after finding an active fdRegI on -// the list but before callBack(). -// -// - -#include -#include - -#define epicsExportSharedSymbols -#include "osiTimer.h" - -osiTimerQueue staticTimerQueue; -static const tsDLIterBD eol; // end of list - -// -// osiTimer::arm() -// -epicsShareFunc void osiTimer::arm (const osiTime * const pInitialDelay) -{ - tsDLIterBD iter; -# ifdef DEBUG - unsigned preemptCount=0u; -# endif - - // - // calculate absolute expiration time - // (dont call base's delay() virtual func - // in the constructor) - // - if (pInitialDelay) { - this->exp = osiTime::getCurrent() + *pInitialDelay; - } - else { - this->exp = osiTime::getCurrent() + this->delay(); - } - - - // - // insert into the pending queue - // - // Finds proper time sorted location using - // a linear search. - // - // **** this should use a binary tree ???? - // - iter = staticTimerQueue.pending.last(); - while (1) { - if (iter==eol) { - // - // add to the beginning of the list - // - staticTimerQueue.pending.push (*this); - break; - } - if (iter->exp <= this->exp) { - // - // add after the item found that expires earlier - // - staticTimerQueue.pending.insertAfter (*this, *iter); - break; - } -# ifdef DEBUG - preemptCount++; -# endif - --iter; - } - this->state = ositPending; - -# ifdef DEBUG - staticTimerQueue.show(10u); -# endif - -# ifdef DEBUG - double theDelay; - if (pInitialDelay) { - theDelay = *pInitialDelay; - } - else { - theDelay = this->delay(); - } - // - // name virtual function isnt always useful here because this is - // often called inside the constructor (unless we are - // rearming the same timer) - // - printf ("Arm of \"%s\" with delay %f at %lx preempting %u\n", - this->name(), theDelay, (unsigned long)this, preemptCount); -# endif - -} - -// -// osiTimer::~osiTimer() -// -epicsShareFunc osiTimer::~osiTimer() -{ - // - // signal the timer queue if this - // was deleted during its expire call - // back - // - if (this == staticTimerQueue.pExpireTmr) { - staticTimerQueue.pExpireTmr = 0; - } - switch (this->state) { - case ositPending: - staticTimerQueue.pending.remove(*this); - break; - case ositExpired: - staticTimerQueue.expired.remove(*this); - break; - case ositLimbo: - break; - default: - assert(0); - } - this->state = ositLimbo; -} - -// -// osiTimer::again() -// -epicsShareFunc osiBool osiTimer::again() const -{ - // - // default is to run the timer only once - // - return osiFalse; -} - -// -// osiTimer::destroy() -// -epicsShareFunc void osiTimer::destroy() -{ - delete this; -} - -// -// osiTimer::delay() -// -epicsShareFunc const osiTime osiTimer::delay() const -{ - // - // default to 1 sec - // - return osiTime (1.0); -} - -epicsShareFunc void osiTimer::show (unsigned level) const -{ - osiTime cur(osiTime::getCurrent()); - double delay; - - printf ("osiTimer at %p for \"%s\" with again = %d\n", - this, this->name(), this->again()); - if (this->exp >= cur) { - delay = this->exp - cur; - } - else { - delay = cur - this->exp; - delay = -delay; - } - if (level>=1u) { - printf ("\tdelay to expire = %f, state = %d\n", - delay, this->state); - } -} - -// -// osiTimerQueue::delayToFirstExpire() -// -osiTime osiTimerQueue::delayToFirstExpire() const -{ - osiTimer *pTmr; - osiTime delay; - - pTmr = this->pending.first(); - if (pTmr) { - delay = pTmr->timeRemaining(); - } - else { - // - // no timer in the queue - return a long delay - 30 min - // - delay = osiTime(30u * secPerMin, 0u); - } -#ifdef DEBUG - printf("delay to first item on the queue %f\n", (double) delay); -#endif - return delay; -} - -// -// osiTimerQueue::process() -// -void osiTimerQueue::process() -{ - tsDLIterBD iter; - tsDLIterBD tmp; - osiTime cur(osiTime::getCurrent()); - osiTimer *pTmr; - - // no recursion - if (this->inProcess) { - return; - } - this->inProcess = osiTrue; - - iter = this->pending.first(); - while ( iter!=eol ) { - if (iter->exp >= cur) { - break; - } - tmp = iter; - ++tmp; - this->pending.remove(*iter); - iter->state = ositExpired; - this->expired.add(*iter); - iter = tmp; - } - - // - // I am careful to prevent problems if they access the - // above list while in an "expire()" call back - // - while ( (pTmr = this->expired.get()) ) { - - pTmr->state = ositLimbo; - -#ifdef DEBUG - double diff = cur-pTmr->exp; - printf ("expired %lx for \"%s\" with error %f\n", - (unsigned long)pTmr, pTmr->name(), diff); -#endif - - // - // Tag current tmr so that we - // can detect if it was deleted - // during the expire call back - // - this->pExpireTmr = pTmr; - pTmr->expire(); - if (this->pExpireTmr == pTmr) { - if (pTmr->again()) { - pTmr->arm(); - } - else { - pTmr->destroy(); - } - } - else { - // - // no recursive calls to process allowed - // - assert(this->pExpireTmr == 0); - } - } - this->inProcess = osiFalse; -} - -// -// osiTimerQueue::show() const -// -void osiTimerQueue::show(unsigned level) const -{ - printf("osiTimerQueue with %u items pending and %u items expired\n", - this->pending.count(), this->expired.count()); - tsDLIterBD iter(this->pending.first()); - while ( iter!=eol ) { - iter->show(level); - ++iter; - } -} - -// -// osiTimerQueue::~osiTimerQueue() -// -osiTimerQueue::~osiTimerQueue() -{ - osiTimer *pTmr; - - // - // destroy any unexpired timers - // - while ( (pTmr = this->pending.get()) ) { - pTmr->state = ositLimbo; - pTmr->destroy(); - } - - // - // destroy any expired timers - // - while ( (pTmr = this->expired.get()) ) { - pTmr->state = ositLimbo; - pTmr->destroy(); - } -} - -// -// osiTimer::name() -// virtual base default -// -epicsShareFunc const char *osiTimer::name() const -{ - return "osiTimer"; -} - -// -// osiTimer::reschedule() -// -// pull this timer out of the queue ans reinstall -// it with a new experation time -// -epicsShareFunc void osiTimer::reschedule(const osiTime &newDelay) -{ - // - // signal the timer queue if this - // occurrring during the expire call - // back - // - if (this == staticTimerQueue.pExpireTmr) { - staticTimerQueue.pExpireTmr = 0; - } - switch (this->state) { - case ositPending: - staticTimerQueue.pending.remove(*this); - break; - case ositExpired: - staticTimerQueue.expired.remove(*this); - break; - case ositLimbo: - break; - default: - assert(0); - } - this->state = ositLimbo; - this->arm(&newDelay); -} - -// -// osiTimer::timeRemaining() -// -// return the number of seconds remaining before -// this timer will expire -// -epicsShareFunc osiTime osiTimer::timeRemaining() -{ - osiTime cur = osiTime::getCurrent(); - osiTime delay; - - if (this->exp>cur) { - delay = this->exp - cur; - } - else { - delay = osiTime(0u,0u); - } - return delay; -} - diff --git a/src/libCom/timer/osiTimer.h b/src/libCom/timer/osiTimer.h deleted file mode 100644 index e8d001b4a..000000000 --- a/src/libCom/timer/osiTimer.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * $Id$ - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - * 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 - * - * - * History - * $Log$ - * Revision 1.5 1997/06/25 05:45:55 jhill - * cleaned up pc port - * - * Revision 1.4 1997/04/10 19:45:42 jhill - * API changes and include with not <> - * - * Revision 1.3 1996/11/02 02:06:59 jhill - * fixed several subtle problems - * - * Revision 1.2 1996/08/05 21:51:11 jhill - * fixed delete this confusion - * - * Revision 1.1 1996/06/26 22:14:15 jhill - * added new src files - * - * Revision 1.1.1.1 1996/06/20 22:15:55 jhill - * installed ca server templates - * - * - */ - - -#ifndef osiTimerHInclude -#define osiTimerHInclude - -#include "shareLib.h" // reset share lib defines -#include "tsDLList.h" -#include "osiTime.h" - -enum osiBool {osiFalse=0, osiTrue=1}; -enum osiTimerState {ositPending, ositExpired, ositLimbo}; - -// -// osiTimer -// -class osiTimer : public tsDLNode { - friend class osiTimerQueue; -public: - epicsShareFunc osiTimer (const osiTime &delay) - { - this->arm(&delay); - } - epicsShareFunc virtual ~osiTimer(); - - // - // called when the timer expires - // - epicsShareFunc virtual void expire()=0; - - // - // called if - // 1) osiTimer exists and the osiTimerQueue is deleted - // 2) when the timer expies and again() returs false - // - // osiTimer::destroy() does a "delete this" - // - epicsShareFunc virtual void destroy(); - - // - // osiTimer::again() returns false - // (run the timer once only) - // returning true indicates that the - // timer should be rearmed with delay - // "delay()" when it expires - // - epicsShareFunc virtual osiBool again() const; - - // - // returns the delay prior to expire - // for subsequent iterations (if "again()" - // returns true) - // - // osiTimer::delay() returns 1 sec - // - epicsShareFunc virtual const osiTime delay() const; - - // - // change the timers expiration to newDelay - // seconds after when reschedule() is called - // - epicsShareFunc void reschedule(const osiTime &newDelay); - - // - // return the number of seconds remaining before - // this timer will expire - // - epicsShareFunc osiTime timeRemaining(); - - epicsShareFunc virtual void show (unsigned level) const; - - // - // for diagnostics - // - epicsShareFunc virtual const char *name() const; -private: - osiTime exp; - osiTimerState state; - - // - // arm() - // place timer in the pending queue - // - epicsShareFunc void arm (const osiTime * const pInitialDelay=0); -}; - - - -// -// osiTimerQueue -// -class osiTimerQueue { -friend class osiTimer; -public: - osiTimerQueue() : inProcess(osiFalse), pExpireTmr(0) {}; - ~osiTimerQueue(); - osiTime delayToFirstExpire () const; - void process (); - void show (unsigned level) const; -private: - tsDLList pending; - tsDLList expired; - osiBool inProcess; - osiTimer *pExpireTmr; - - void install (osiTimer &tmr, osiTime delay); -}; - -extern osiTimerQueue staticTimerQueue; - - -#endif // osiTimerHInclude - diff --git a/src/misc/epicsEnvParams.c b/src/misc/epicsEnvParams.c deleted file mode 100644 index ae022ef0e..000000000 --- a/src/misc/epicsEnvParams.c +++ /dev/null @@ -1,57 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - # Date: 07-20-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 mm-dd-yy iii Comment - * .02 07-29-92 rcz Put under sccs in site directory - * .03 09-14-92 jba Changed EPICS_TS_MIN_WEST to 300 - * .04 09-18-92 jba Changed EPICS_TS_MIN_WEST back to 360 - * ... - */ -#include -#include - -epicsSetEnvParams() -{ - printf("setting EPICS environment parameters\n"); - envSetConfigParam(&EPICS_TS_MIN_WEST, EPICS_TS_MIN_VALUE); - envSetConfigParam(&EPICS_AR_PORT, "7002"); - envSetConfigParam(&EPICS_IOC_LOG_INET, EPICS_IOC_LOG_VALUE); - envSetConfigParam(&EPICS_IOC_LOG_PORT, "7004"); - envSetConfigParam(&EPICS_IOC_LOG_FILE_LIMIT, EPICS_IOC_FILE_VALUE); - envSetConfigParam(&EPICS_IOC_LOG_FILE_NAME, EPICS_IOC_LOG_FILE_TXT); - return 0; -} -epicsPrtEnvParams() -{ - envPrtConfigParam(&EPICS_TS_MIN_WEST); - envPrtConfigParam(&EPICS_AR_PORT); - envPrtConfigParam(&EPICS_IOC_LOG_INET); - envPrtConfigParam(&EPICS_IOC_LOG_PORT); - envPrtConfigParam(&EPICS_IOC_LOG_FILE_LIMIT); - envPrtConfigParam(&EPICS_IOC_LOG_FILE_NAME); - return 0; -} diff --git a/src/misc/epicsEnvParams.h b/src/misc/epicsEnvParams.h deleted file mode 100644 index c210daf23..000000000 --- a/src/misc/epicsEnvParams.h +++ /dev/null @@ -1,14 +0,0 @@ -/* $Id$ - * $Log$ - * Revision 1.2 1994/09/09 12:40:30 mrk - * Removed env variables for old time support. New uses standard Unix methods. - * - * Revision 1.1 1994/07/17 07:14:24 bordua - * Initial version. - * - */ - -char *EPICS_TS_MIN_VALUE= "360"; -char *EPICS_IOC_LOG_VALUE= "164.54.8.167"; -char *EPICS_IOC_FILE_VALUE= "1000000"; -char *EPICS_IOC_LOG_FILE_TXT= "/home/phebos1/epics/apple/log/iocLog.text"; diff --git a/src/rec/caMonitor.c b/src/rec/caMonitor.c deleted file mode 100644 index c3d63bca3..000000000 --- a/src/rec/caMonitor.c +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define QUEUE_SIZE 256 -LOCAL int taskid=0; -LOCAL ELLLIST capvtList; -LOCAL RING_ID ringQ;; -LOCAL FAST_LOCK lock; -LOCAL void *freeListPvt; - -typedef enum {cmdNone,cmdAdd,cmdRemove} COMMAND; - -typedef struct { - ELLNODE node; - CAMONITOR *pcamonitor; - chid chid; - evid evid; - COMMAND cmd; - struct dbr_sts_double rtndata; /*Not currently used */ -} CAPVT; - -void caMonitorTask(void); - -LOCAL void eventCallback(struct event_handler_args eha) -{ - struct dbr_sts_double *pdata = eha.dbr; - CAPVT *pcapvt; - CAMONITOR *pcamonitor; - - pcapvt = (CAPVT *)eha.usr; - pcamonitor = pcapvt->pcamonitor; - (pcamonitor->callback)(pcamonitor); -} - -LOCAL void caMonitorStart(void) -{ - FASTLOCKINIT(&lock); - freeListInitPvt(&freeListPvt,sizeof(CAPVT),1); - if((ringQ = rngCreate(sizeof(void *) * QUEUE_SIZE)) == NULL) { - errMessage(0,"caMonitorStart failed"); - exit(1); - } - ellInit(&capvtList); - taskid = taskSpawn("caMonitorTask",CA_CLIENT_PRI-1,VX_FP_TASK, - CA_CLIENT_STACK,(FUNCPTR)caMonitorTask,0,0,0,0,0,0,0,0,0,0); - if(taskid==ERROR) { - errMessage(0,"caMonitorStart: taskSpawn Failure\n"); - } -} - -long caMonitorAdd(CAMONITOR *pcamonitor) -{ - CAPVT *pcapvt; - - if(!taskid) caMonitorStart(); - FASTLOCK(&lock); - pcapvt = freeListCalloc(freeListPvt); - pcamonitor->caMonitorPvt = pcapvt; - pcapvt->pcamonitor = pcamonitor; - pcapvt->cmd = cmdAdd; - if(rngBufPut(ringQ,(void *)&pcapvt,sizeof(pcapvt)) - !=sizeof(pcamonitor)) errMessage(0,"caMonitorAdd: rngBufPut error"); - ellAdd(&capvtList,(void *)pcapvt); - FASTUNLOCK(&lock); -} - -long caMonitorDelete(CAMONITOR *pcamonitor) -{ - CAPVT *pcapvt = pcamonitor->caMonitorPvt; - - FASTLOCK(&lock); - pcapvt->cmd = cmdRemove; - if(rngBufPut(ringQ,(void *)&pcapvt,sizeof(pcapvt)) - !=sizeof(pcamonitor)) errMessage(0,"caMonitorDelete: rngBufPut error"); - FASTUNLOCK(&lock); -} - -/*LOCAL */ -void caMonitorTask(void) -{ - CAPVT *pcapvt; - CAMONITOR *pcamonitor; - int status; - - taskwdInsert(taskIdSelf(),NULL,NULL); - SEVCHK(ca_task_initialize(),"ca_task_initialize"); - while(TRUE) { - while (rngNBytes(ringQ)>=sizeof(pcapvt)){ - if(rngBufGet(ringQ,(void *)&pcapvt,sizeof(pcapvt)) - !=sizeof(pcapvt)) { - errMessage(0,"caMonitorTask: rngBufGet error"); - continue; - } - FASTLOCK(&lock); - pcamonitor = pcapvt->pcamonitor; - if(pcapvt->cmd==cmdAdd) { - SEVCHK(ca_build_and_connect(pcamonitor->channame,TYPENOTCONN,0, - &pcapvt->chid,0,NULL,pcapvt), - "ca_build_and_connect"); - SEVCHK(ca_add_event(DBR_STS_DOUBLE,pcapvt->chid, - eventCallback,pcapvt,&pcapvt->evid), - "ca_add_event"); - } else {/*must be cmdRemove*/ - SEVCHK(ca_clear_channel(pcapvt->chid),"ca_clear_channel"); - pcapvt->cmd=cmdNone; - ellDelete(&capvtList,(void *)pcapvt); - freeListFree(freeListPvt,pcapvt); - } - pcapvt->cmd=cmdNone; - FASTUNLOCK(&lock); - } - status = ca_pend_event(.1); - if(status!=ECA_NORMAL && status!=ECA_TIMEOUT) - SEVCHK(status,"ca_pend_event"); - } -} - -static void myCallback(struct caMonitor *pcamonitor) -{ - printf("myCallback: %s\n",pcamonitor->channame); -} - -int testCaMonitor(char *name) -{ - CAMONITOR *pcamonitor; - long status; - - pcamonitor = calloc(1,sizeof(CAMONITOR)); - pcamonitor->channame = calloc(1,strlen(name)+1); - pcamonitor->callback = myCallback; - strcpy(pcamonitor->channame,name); - status = caMonitorAdd(pcamonitor); - if(status) errMessage(status,"testCaMonitor error"); - return(0); -} diff --git a/src/rec/caMonitor.h b/src/rec/caMonitor.h deleted file mode 100644 index fff220740..000000000 --- a/src/rec/caMonitor.h +++ /dev/null @@ -1,9 +0,0 @@ -typedef struct caMonitor{ - char *channame; - void (*callback)(struct caMonitor *pcamonitor); - void *userPvt; - void *caMonitorPvt; -} CAMONITOR; - -long caMonitorAdd(CAMONITOR *pcamonitor); -long caMonitorDelete(CAMONITOR *pcamonitor); diff --git a/src/util/apCreateShadow.c b/src/util/apCreateShadow.c deleted file mode 100644 index 9d37bda2e..000000000 --- a/src/util/apCreateShadow.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * apCreateShadow.c - * todo - if symbolic link is relative - * - it should be the same as the one in the source area - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SAME 0 - -static void Usage(); -static void procDirEntries(); -static void createLink(); -static void procLink(); -static void processFile(); -static void dirwalk(); -static void startFromHere(); -static void init_setup(); - -int errno; -static struct stat stbuf; -static char buffer[MAXPATHLEN]; -static char dest_base[MAXPATHLEN]; /* dest base (root of shadow node) */ -static char src_base[MAXPATHLEN]; /* current source descend root node */ -static char dpath[MAXPATHLEN]; /* dest/subdir... */ -static char spath[MAXPATHLEN]; /* src/subdir... */ -static char progName[30]; /* program name */ -static char sys_top[MAXPATHLEN]; /* root node */ -static char topAppl[MAXPATHLEN];/* pathname of master appLoc file */ - - -/**************************************************************************** -MAIN PROGRAM - This program creates an application developers set of shadow nodes - - It must be invoked with a full path name so that the official - application area is known. - -****************************************************************************/ -main(argc, argv) - int argc; - char **argv; -{ -/* - * intial setup - */ - init_setup(argc, argv); - - if (chdir(sys_top)!=0) { - fprintf(stderr, "%s: Can't chdir\n", progName); - exit(1); - } - startFromHere(); - - fprintf(stderr, "apCreateShadow %s\n", "completed"); - return (0); -} - -/**************************************************************************** -PROCLINK -****************************************************************************/ -static void -procLink(name) - char *name; -{ - - char buff[MAXPATHLEN]; - int num_chars; - - if ((num_chars = readlink(name, buff, MAXPATHLEN)) < 0) { - fprintf(stderr, "procLink: FATAL ERROR - errno=%d name=%s\n", errno, name); - exit(1); - } - buff[num_chars] = NULL; - - if ((buff[0] == '/') || ((buff[0] == '.') && (buff[1] == '/'))) { - strcpy(spath, src_base); - strcat(spath, "/"); - strcat(spath, name); - } else { - strcpy(spath, buff); - } - strcpy(dpath, dest_base); - strcat(dpath, "/"); - strcat(dpath, name); - createLink(); -} -/**************************************************************************** -CREATELINK -****************************************************************************/ -static void -createLink() -{ -/* - A symbolic link name2 is created to name1 (name2 is the name - of the file created, name1 is the string used in creating - the symbolic link). Either name may be an arbitrary path - name; the files need not be on the same file system. - */ -if ( access(dpath,R_OK|F_OK)) { - if ((symlink(spath, dpath)) != 0) { - printf("\n####################################################\n"); - printf("createLink: symlink failure: errno=%d\nspath=%s\n\tdpath=%s\n" - ,errno, spath, dpath); - printf("####################################################\n"); - } -} -} -/**************************************************************************** -DIRWALK applies a function to each file in a directory -****************************************************************************/ -static void -dirwalk(dir, dbflag, fcn) - char *dir; - int dbflag; /* in database directory flag*/ - void (*fcn) (); -{ - char name[MAXNAMLEN]; - struct dirent *dp; - DIR *dfd; - if ((dfd = opendir(dir)) == NULL) { - fprintf(stderr, "dirwalk: can't open %s\n", dir); - exit(1); - } - while ((dp = readdir(dfd)) != NULL) { - if (strcmp(dp->d_name, ".") == 0 - || strcmp(dp->d_name, "..") == 0) - continue; /* skip self and parent */ - if (strlen(dir) + strlen(dp->d_name) + 2 > sizeof(name)) - fprintf(stderr, "dirwalk: name %s/%s too long\n", - dir, dp->d_name); - else { - sprintf(name, "%s/%s", dir, dp->d_name); - (*fcn) (name, dir, dbflag); - } - } - closedir(dfd); -} -static void -Usage() -{ - printf("\nUsage:\t%s \n", progName); -} - -/**************************************************************************** -PROCESSFILE - create a soft link and return -****************************************************************************/ -static void -processFile(name, indbdirflag) - char *name; /* regular file */ - int indbdirflag;/* in database directory flag */ -{ - - char *ptr; - char cmd[2 * MAXNAMLEN]; - strcpy(spath, src_base); - strcat(spath, "/"); - strcat(spath, name); - - strcpy(dpath, dest_base); - strcat(dpath, "/"); - strcat(dpath, name); - - if ((ptr = (char *) strstr(name, "Db.")) != NULL - && indbdirflag != 0) { - /* only link in <*>Db.database files */ - if ((ptr = (char *) strstr(name, "Db.database")) != NULL) { - createLink(); - } else { - return; - } - } else { - createLink(); - } - return; -} -/**************************************************************************** -INIT_SETUP -****************************************************************************/ -static void -init_setup(argc, argv) - int argc; - char **argv; -{ - char *ptr; - int len; - FILE *origin_fp; - char Xdest_base[MAXPATHLEN]; - char Xsrc_base[MAXPATHLEN]; - ptr = (char *) strrchr(argv[0], '/'); - if (ptr == 0) { - strcpy(progName, argv[0]); - } else { - strcpy(progName, ptr + 1); - } - if (argc != 2) { - printf("####################################################\n"); - Usage(); - if ((access(".applShadowOrgin",R_OK|F_OK) == 0)) { - system("/usr/5bin/echo \"previous invocation:\n\\tapCreateShadow \\c\";cat .applShadowOrgin"); - } - printf("####################################################\n"); - exit(1); - } - if (*argv[1] != '/') { - printf("####################################################\n"); - printf("%s: ERROR - arg#1 must be a full pathname\n", progName); - Usage(); - printf("####################################################\n"); - exit(1); - } -/* check to see if path points to app system area - file .topAppl exists*/ - /* application base is argv[1] */ - len = strlen(argv[1]); - strncpy(sys_top, argv[1], len); - sys_top[len] = NULL; - - strcpy(topAppl, sys_top); - strcat(topAppl, "/.topAppl"); - if ((stat(topAppl, &stbuf)) != 0) { - fprintf(stderr, "####################################################\n"); - fprintf(stderr, "%s: Can't stat file: %s\n", progName, topAppl); - fprintf(stderr, "####################################################\n"); - Usage(); - exit(1); - } - /* get shadow base */ - if ((getcwd(dest_base, 78)) == NULL) { - fprintf(stderr, "getcwd failed\n"); - exit(1); - } - strcpy(src_base, sys_top); - /* if dest_base is substring of src_base - recursion occurs */ - strcpy(Xdest_base, dest_base); - strcat(Xdest_base, "/"); - strcpy(Xsrc_base, src_base); - strcat(Xsrc_base, "/"); - if ((strstr(Xdest_base, Xsrc_base)) != NULL) { /* error */ - fprintf(stderr, "####################################################\n"); - fprintf(stderr, "%s: You can't run this tool in an application system area!\n", progName); - fprintf(stderr, "####################################################\n"); - exit(1); - } - /* if .applShadow doesn't exist - require touch .applShadow */ - if ((stat("./.applShadow", &stbuf)) != 0) { - fprintf(stderr, "\n"); - fprintf(stderr, "####################################################\n"); - fprintf(stderr, "%s: Can't stat file: './applShadow'\n", progName); - fprintf(stderr, "####################################################\n"); - fprintf(stderr, "If this is NOT the root of your application shadow directory,\n"); - fprintf(stderr, "then please cd to the appropriate place and try again.\n"); - fprintf(stderr, "If this IS the root your shadow directory, then create .applShadow\n"); - fprintf(stderr, "with the following command and then run %s again.\n", progName); - fprintf(stderr, " %%\n touch .applShadow\n"); - fprintf(stderr, "####################################################\n"); - exit(1); - } -/*********************** create/check an invocation marker *******************/ -/*rz*/ - if ((stat("./.applShadowOrgin", &stbuf)) != 0) { - if ((origin_fp = fopen("./.applShadowOrgin", "w")) == NULL) { - fprintf(stderr, "%s: can't fopen %s in dest_base area\n", - progName, ".applShadowOrgin"); - exit(1); - } - fprintf(origin_fp, "%s\n", sys_top); - } else { - if ((origin_fp = fopen("./.applShadowOrgin", "r")) == NULL) { - fprintf(stderr, "%s: can't fopen %s in dest_base area\n", - progName, ".applShadowOrgin"); - exit(1); - } - /* compare sys_top with buffer */ - while ((fgets(buffer, sizeof(buffer) + 2, origin_fp)) != NULL) { - len = strlen(buffer); - /* remove the N/L from input line */ - if (buffer[len - 1] == '\n') { - buffer[len - 1] = 0; - } - if ((strcmp(buffer, sys_top)) != SAME) { - fprintf(stderr, "%s: FATAL ERROR - Illegal invocation\n", progName); - fprintf(stderr, - "Your last system area was %s\n", buffer); - fprintf(stderr, - "Your new (arg1) system area is %s\n", sys_top); - exit(1); - } - } - } - fclose(origin_fp); -} - -/*********************************************/ -static void -startFromHere() -{ - char *dir = "."; - char name[MAXNAMLEN]; - struct dirent *dp; - DIR *dfd; - int localdbflag=0; /* in database directory flag*/ - if ((dfd = opendir(dir)) == NULL) { - fprintf(stderr, "startFromHere: can't open %s\n", dir); - exit(1); - } - while ((dp = readdir(dfd)) != NULL) { - if (strcmp(dp->d_name, ".") == 0 - || strcmp(dp->d_name, "..") == 0) - continue; /* skip self and parent */ - if (strlen(dir) + strlen(dp->d_name) + 2 > sizeof(name)) - fprintf(stderr, "startFromHere: name %s/%s too long\n", - dir, dp->d_name); - else { - sprintf(name, "%s/%s", dir, dp->d_name); - procDirEntries(name,dir,localdbflag); - } - } - printf("\n"); - closedir(dfd); -} -/**************************************************************************** -PROCDIRENTRIES - process directory entries -****************************************************************************/ -static void -procDirEntries(name, dir, indbdirflag) - char *name; /* entry name */ - char *dir; - int indbdirflag; /* in database directory flag*/ -{ - char *ptr; - char *ptr2; - struct stat stbuf; - int localdbflag=0; /* in database directory flag*/ - if (lstat(name, &stbuf) == -1) { - fprintf(stderr, "procDirEntries: can't access %s\n", name); - exit(1); - } - printf("."); fflush(stdout); - if ((stbuf.st_mode & S_IFMT) == S_IFLNK) { - procLink(name); - return; - } - if ((stbuf.st_mode & S_IFMT) == S_IFREG) { - processFile(name,indbdirflag); - return; - } - if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { - /* access the last component (directory) in name */ - ptr = (char *) strrchr(name, '/'); - if ((ptr2 = (char *) strstr(ptr, "Db")) != NULL ) { - localdbflag=1; /*set in database directory flag*/ - } - if ((strcmp(ptr, "/SCCS")) == SAME) { - /* dpath should be composed of - dest_base/SCCS */ - strcpy(dpath, dest_base); - strcat(dpath, "/"); - strcat(dpath, name); - strcpy(spath, src_base); - strcat(spath, "/"); - strcat(spath, name); - createLink(); - return; - } -/* for other directories - create hard and continue dirwalk */ - strcpy(dpath, dest_base); - strcat(dpath, "/"); - strcat(dpath, name); - if (access(dpath, R_OK | F_OK)) { - if ((mkdir(dpath, 0775)) != 0) { - printf("####################################################\n"); - printf("procDirEntries: Can't mkdir %s - errno=%d\n", dpath, errno); - printf("####################################################\n"); - } - } - dirwalk(name, localdbflag, procDirEntries); - } - return; -} diff --git a/src/util/apStatusSync.c b/src/util/apStatusSync.c deleted file mode 100644 index cb77c0ad5..000000000 --- a/src/util/apStatusSync.c +++ /dev/null @@ -1,576 +0,0 @@ -/* APSTATUSSYNC.C - ***************************************************************** - * TODO - change the whole tool => almost DONE - * from the shadow point of view - * dirwalk from ../. (shadow directory) - * - * if regular file - do - * if SCCS file and out for edit - * (report as EDIT) - * else if SCCS file and Not out for edit - * 1. (report as illegal file - should be a link) - * 2. place on the remove list - * else - * 1. place on the remove list - * if link - do - * if a relative link (doesn't start with / ) - * should agree with the appl system area (relative) - * else if it doesn't terminate (no access) - * 1. (report as link component failure) - * 2. place on the remove list - * else if it terminates in the wrong place - * 1. (report as illegal link) - * 2. place on the remove list - * - * if dir - do - * if name == SCCS - * 1. (report as illegal SCCS directory) - * 2. place on the remove list - * else if NOT in the system area - * 1. place on the remove list -***************************************************************** - * APSTATUSSYNC.C - * - * must be run from the top node of an application development node - * - * Reports to stdout: - * Regular files in this node that are out-for-edit. - * These are errors if uid doesn't agree. - * Regular files in this node that should be links to the - * application system area. - * Links that point to a dest. outside of this node and the final - * dest. is not in the application system area or EPICS - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void procDirEntries(); -int processFile(); -int getAppSysPath(); -int procLinkEntries(); -int dirwalk(); -int verbose; -extern int errno; -#define TRUE 1 -#define FALSE 0 -#define SAME 0 - -static char pdot[] = "SCCS/p."; -static char sdot[] = "SCCS/s."; -static char msgbuff[MAXPATHLEN]; -static void *pEpicsRelease = NULL; -static void *pAppSysTop = NULL; -static void *pDvlTop = NULL; -static int lenApplSys; -static int lenEpicsPath; -static int lenDvlTop; -static int initScriptFile(); -static int closeScriptFile(); -static int appendToScriptFile(); -static FILE *apRemoveScriptFp = (FILE*)NULL; -static char *pScriptFileName = "apRemoveScript"; -static char *plogname; /* logname pointer */ - - -/**************************************************************************** - MAIN PROGRAM -****************************************************************************/ -main(argc, argv) - int argc; - char **argv; -{ - if ((argc > 1) && ((strncmp(argv[1], "-v", 2)) == 0)) - verbose = TRUE; - else - verbose = FALSE; - if ((plogname = getenv("LOGNAME")) == 0) { - fprintf(stdout, "apStatusSync: Can't get LOGNAME\n"); - return (-1); - } -fprintf(stdout, "\n\n===========================================================\n"); -fprintf(stdout, "apStatusSync: Status Started ==>> ==>> ==>> ==>> ==>>\n"); -fprintf(stdout, "===========================================================\n"); - if ((initScriptFile()) != 0) - return (-1); - if ((processTopDir()) != 0) - return (-1); - if ((closeScriptFile()) != 0) - return (-1); - postAmble(); - return (0); -} - -/**************************************************************************** -PROCLINKENTRIES - checks valid symbolic link for EPICS - at entry path is the name of a local link -****************************************************************************/ -int -procLinkEntries(path) - char *path; -{ - char resolved_path[MAXPATHLEN]; - char buf[MAXPATHLEN]; - char buf2[MAXPATHLEN]; - char buf3[MAXPATHLEN]; - char buffer[MAXNAMLEN]; - void *pt; - int nchars; - resolved_path[0] = '\0'; - if ((pt = (void *) realpath(path, resolved_path)) == NULL) { - fprintf(stdout, "FATAL ERROR - failed link component of %s\n\t= %s\n", - path, resolved_path); - sprintf(buffer, "#/bin/rm -f ./%s\n", path); - if ((appendToScriptFile(buffer)) < 0) - return (-1); /* should not happen */ - return (-1); - } - /* skip any link path with "/templates/" in it */ - if ((strstr(resolved_path, "/templates/")) != NULL) - return; - /* skip any link path with "vw" in it */ - if ((strstr(path, "vw")) != NULL) { - return; - } - /* skip any link path with "/vxWorks" in it */ - if ((strstr(path, "/vxWorks")) != NULL) - return; - -/* assume a relative link name doesn't begin with a '/' character */ - buf[0] = '\0'; - if ((nchars = readlink(path, buf, MAXPATHLEN)) < 0) { - fprintf(stdout, "\treadlink failed errno=%d\n", errno); - sprintf(buffer, "#/bin/rm -f ./%s\n", path); - if ((appendToScriptFile(buffer)) < 0) - return; - } - buf[nchars] = '\0'; - strcpy(buf2, pAppSysTop); - strcat(buf2, "/"); - strcat(buf2, path); - buf3[0] = '\0'; - if ((strstr(resolved_path, pAppSysTop)) != NULL) { - return; - } else if ((strstr(resolved_path, pEpicsRelease)) != NULL) { - return; - } else if ((strstr(resolved_path, pDvlTop)) != NULL) { - return; - } else { - fprintf(stdout, - "FATAL ERROR - link '%s' should point to the application system area\n\tor the application shadow area or an EPICS release area\n\tdest='%s'\n", path, resolved_path); - } - return; -} -/**************************************************************************** -GETAPPSYSPATH - returns -1 - error, 0 - OK -****************************************************************************/ -getAppSysPath() -{ - void *pt; - char resolved_path[MAXPATHLEN]; - - FILE *fp; - char *app_path_file = ".applShadowOrgin"; - char *epics_path_file = "current_rel"; - char app_path[MAXPATHLEN]; - char epics_path[MAXPATHLEN]; - resolved_path[0] = '\0'; - if ((fp = fopen(app_path_file, "r")) == NULL) { - fprintf(stdout, "apStatusSync: can't fopen %s\n", app_path_file); - fprintf(stdout, "Probably not at root of application shadow node\n"); - return (-1); - } - if ((fgets(app_path, MAXPATHLEN, fp)) == NULL) { - fprintf(stdout, "apStatusSync: FATAL ERROR - reading %s\n", app_path_file); - return (-1); - } - fclose(fp); - lenApplSys = strlen(app_path); - if (app_path[lenApplSys - 1] == '\n') { - app_path[lenApplSys - 1] = '\0'; - } - /* reset App SYS to real path if not on server */ - if ((pt = (void *) realpath(app_path, resolved_path)) == NULL) { - fprintf(stdout, "FATAL ERROR - failed link component of %s=%s\n", - app_path, resolved_path); - return (-1); - } - lenApplSys = strlen(pt); - pAppSysTop = (void *) calloc(1, lenApplSys + 1); - strcpy(pAppSysTop, pt); - if ((fp = fopen(epics_path_file, "r")) == NULL) { - fprintf(stdout, "apStatusSync: can't fopen %s\n", epics_path_file); - fprintf(stdout, "Probably not at root of application shadow node\n"); - return (-1); - } - if ((fgets(epics_path, MAXPATHLEN, fp)) == NULL) { - fprintf(stdout, "apStatusSync: FATAL ERROR - reading %s\n", epics_path_file); - return (-1); - } - fclose(fp); - lenEpicsPath = strlen(epics_path); - if (epics_path[lenEpicsPath - 1] == '\n') { - epics_path[lenEpicsPath - 1] = '\0'; - } - /* reset epics path to real path if not on server */ - if ((pt = (void *) realpath(epics_path, resolved_path)) == NULL) { - fprintf(stdout, "FATAL ERROR - failed link component of %s\n\t= %s\n", - epics_path, resolved_path); - return (-1); - } - lenEpicsPath = strlen(pt); - pEpicsRelease = (void *) calloc(1, lenEpicsPath + 1); - strcpy(pEpicsRelease, pt); - return (0); -} - -/**************************************************************************** -PROCDIRENTRIES - process directory entries -****************************************************************************/ -void -procDirEntries(name, dir) - char *name; /* entry name */ - char *dir; -{ - struct stat stbuf; - char *pbeg; /* beg of file pathname */ - char *pend; /* beg of filename */ - char *pendm1; /* beg of filename */ - int len; - int j; - char buffer[MAXNAMLEN]; - - if (lstat(name, &stbuf) == -1) { - fprintf(stdout, "procDirEntries: can't access %s\n", name); - return; - } - pbeg = name; - len = strlen(name); - if (len + 7 > MAXNAMLEN) { - fprintf(stdout, "processFile: pathname %s too long\n", name); - return ; - } - /* search for last slash '/' in pathname */ - for (j = len, pend = pbeg + len; j > 0; j--, pend--) { - if (*pend == '/') - break; - } - pend++; - pendm1 = pend; - pendm1--; - /* pend points to filename */ - if ((stbuf.st_mode & S_IFMT) == S_IFLNK) { - procLinkEntries(name); - return; - } - if ((stbuf.st_mode & S_IFMT) == S_IFREG) { - processFile(name, dir); - return; - } - if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { - /* if current directory is SCCS - ... */ - if ((strstr(pendm1, "SCCS")) != NULL) { - fprintf(stdout, "FATAL ERROR - directory ./%s should be a link\n", name); - sprintf(buffer, "#/bin/rm -fr ./%s\n", name); - if ((appendToScriptFile(buffer)) < 0) - return; - } - dirwalk(name, procDirEntries); - } - return; -} - -/**************************************************************************** -PROCESSFILE - for each regular file: - if s.dot !exist - skip file (private file) - else if p.dot exist && s.dot !exist - print error - else if p.dot exist && s.dot exist - print dir file and contents of p.dot -****************************************************************************/ -int -processFile(name, dir) - char *name; /* regular file */ - char *dir; /* current directory */ -{ - char sccsDir[MAXNAMLEN]; - char sdotName[MAXNAMLEN]; - char pdotName[MAXNAMLEN]; - char buffer[MAXNAMLEN]; - char *pbeg; /* beg of file pathname */ - char *pend; /* beg of filename */ - char *pendm1; /* beg of filename */ - char udotname[MAXNAMLEN+5]; /* took file out-for-edit user name */ - struct stat stbuf; - struct stat lstbuf; - FILE *fp; - char ibuf[MAXPATHLEN+5]; /* contents of 1st line of p.dot */ - int hasSccsDir = FALSE; - int hasPdot = FALSE; - int hasSdot = FALSE; - - int len, - j; - pbeg = name; - len = strlen(name); - if (len + 7 > MAXNAMLEN) { - fprintf(stdout, "processFile: pathname %s too long\n", name); - return (0); - } - /* search for last slash '/' in pathname */ - for (j = len, pend = pbeg + len; j > 0; j--, pend--) { - if (*pend == '/') - break; - } - pend++; - pendm1 = pend; - pendm1--; - /* pend points to filename */ - - /* skip some setup files */ - if ((strstr(pendm1, ".applShadow")) != NULL) - return; - if ((strstr(pendm1, ".applShadowOrgin")) != NULL) - return; - if ((strstr(pendm1, "apRemoveScript")) != NULL) - return; - /* determine if dir has an SCCS sub directory */ - strcpy(sccsDir, dir); - strcat(sccsDir, "/SCCS"); - - if (lstat(sccsDir, &lstbuf) == -1) { - hasSccsDir = FALSE; - } else { - hasSccsDir = TRUE; - } - /* form p.dot name */ - strcpy(pdotName, dir); - strcat(pdotName, "/"); - strcat(pdotName, pdot); - strcat(pdotName, pend); - if (stat(pdotName, &stbuf) == 0) - hasPdot = TRUE; - /* form s.dot name */ - strcpy(sdotName, dir); - strcat(sdotName, "/"); - strcat(sdotName, sdot); - strcat(sdotName, pend); - if (stat(sdotName, &stbuf) == 0) - hasSdot = TRUE; - if (hasPdot && hasSdot) { - if ((fp = fopen(pdotName, "r")) == NULL) { - fprintf(stdout, "processFile: can't fopen %s\n", pdotName); - return (-1); - } - if ((fgets(ibuf, MAXPATHLEN, fp)) != NULL) { - /* is this the original sccs out-for-edit owner ??? */ - strcpy(udotname, ibuf); - if ((strstr(udotname, plogname))==NULL) { - fclose(fp); - return (0); - } - /* else print status */ - fprintf(stdout, "%-20s %-25s EDIT - %s", dir, pend, ibuf); - } else { - fprintf(stdout, "FATAL ERROR - reading %s%s\n", pdot, pend); - } - fclose(fp); - } else if (hasPdot && !hasSdot) { - /* stray ??? somebody removed the s.dot */ - fprintf(stdout, "Warning - someone removed '%s' from sccs control\nw/o removing the lock file\n", name); - sprintf(buffer, "#/bin/rm -f ./%s\n", name); - if ((appendToScriptFile(buffer)) < 0) - return (-1); /* should not happen */ - } else if (!hasPdot && hasSdot) { - fprintf(stdout, "POSSIBLE FATAL ERROR - file ./%s should be a link\n", name); - sprintf(buffer, "#/bin/rm -f ./%s\n", name); - if ((appendToScriptFile(buffer)) < 0) - return (-1); - } else if (!hasPdot && !hasSdot) { - /* stray ??? regular files in directories */ - sprintf(buffer, "#/bin/rm -f ./%s\n", name); - if ((appendToScriptFile(buffer)) < 0) - return (-1); - } - return (0); -} -/**************************************************************************** -DIRWALK applies a function to each file in a directory -****************************************************************************/ -int -dirwalk(dir, fcn) - char *dir; - void (*fcn) (); -{ - char name[MAXNAMLEN]; - struct dirent *dp; - DIR *dfd; - struct stat sb; - char buffer[MAXNAMLEN]; - if ((dfd = opendir(dir)) == NULL) { - fprintf(stdout, "dirwalk: can't open %s\n", dir); - return(-1); - } - strcpy(name, pAppSysTop); - strcat(name, "/"); - strcat(name, dir); - if ((stat(name, &sb) != 0)) { - sprintf(buffer, "#/bin/rm -fr ./%s\n", dir); - if ((appendToScriptFile(buffer)) < 0) - return (-1); - } - while ((dp = readdir(dfd)) != NULL) { - if (strcmp(dp->d_name, ".") == 0 - || strcmp(dp->d_name, "..") == 0) - continue; /* skip self and parent */ - if (strlen(dir) + strlen(dp->d_name) + 2 > sizeof(name)) - fprintf(stdout, "dirwalk: name %s/%s too long\n", - dir, dp->d_name); - else { - sprintf(name, "%s/%s", dir, dp->d_name); - (*fcn) (name, dir); - } - } - closedir(dfd); -} -/**************************************************************************** -processTopDir - processes the top directory -****************************************************************************/ -processTopDir() -{ - DIR *dirp; - struct dirent *dp; - char *dir = "."; - if ((pDvlTop = (void *) getcwd((char *) NULL, 128)) == NULL) { - fprintf(stdout, "getcwd failed\n"); - return (-1); - } - lenDvlTop = strlen(pDvlTop); - if ((getAppSysPath()) < 0) - return (-1); - if ((dirp = opendir(dir)) == NULL) { - fprintf(stderr, "apStatusSync - main: can't open directory %s\n", dir); - return (-1); - } - while ((dp = readdir(dirp)) != NULL) { - if (strcmp(dp->d_name, ".") == 0 - || strcmp(dp->d_name, "..") == 0) - continue; /* skip self and parent */ - procDirEntries(dp->d_name, dir); - } - closedir(dirp); - return (0); -} - -/**************************************************************************** -initScriptFile -****************************************************************************/ -static int -initScriptFile() -{ - struct stat sb; -/* - * if apRemoveScript already exists - abort - * also - don't allow run in system area - * - */ - if (!(stat(".applShadow", &sb) == 0)) { - fprintf(stderr, - "\napStatusSync: - Can't find file: '.applShadow'\n"); - fprintf(stderr, - "You must be in the of your application shadow node\n"); - fprintf(stderr, - "to run this tool\n"); - return (-1); - } - if ((stat(pScriptFileName, &sb) == 0)) { - fprintf(stderr, - "\nThe previous output file '%s' still exists!\n", pScriptFileName); - fprintf(stderr, - "Please remove the file and try again\n"); - fprintf(stderr, - "\t/bin/rm apRemoveScript\n"); - return (-1); - } - if ((apRemoveScriptFp = fopen(pScriptFileName, "w")) == NULL) { - fprintf(stderr, "apStatusSync: can't fopen %s for writing\n", pScriptFileName); - return (-1); - } - return (0); -} -/**************************************************************************** -closeScriptFile -****************************************************************************/ -static int -closeScriptFile() -{ - if (!apRemoveScriptFp) { - fprintf(stderr, "apStatusSync: closeScriptFile() - %s not open\n", pScriptFileName); - return (-1); - } -chmod("apRemoveScript",0755); -close (apRemoveScriptFp); -return(0); -} -/**************************************************************************** -APPENDTOSCRIPTFILE -****************************************************************************/ -static int -appendToScriptFile(pstring) - char *pstring; -{ - if (!apRemoveScriptFp) { - fprintf(stderr, - "apStatusSync: appendToScriptFile() - %s not open\n", pScriptFileName); - return (-1); - } - if ((wrt_buf(apRemoveScriptFp, pstring, pScriptFileName) != 0)) - return (-1); - return (0); -} -/**************************************************************************** -wrt_buf - Writes buffer to file -****************************************************************************/ -static int -wrt_buf(fp, pstring, pfile) - FILE *fp; - char *pstring; - char *pfile; -{ - int len; - len = strlen(pstring); - if ((fwrite(pstring, len, 1, fp)) != 1) { - printf("apStatusSync: wrt_buf() fwrite error. errno=%i file=%s\n", - errno, pfile); - return (-1); - } - return (0); -} -postAmble() -{ -fprintf(stdout,"===========================================================\n"); -fprintf(stdout,"Status Completed \n"); -fprintf(stdout,"===========================================================\n"); -fprintf(stdout,"When you are satisfied with the above status - continue\n"); -fprintf(stdout," else - correct the situation and run apStatusSync again\n"); -fprintf(stdout,"\ncontinue below\n"); -fprintf(stdout,"\nNow please review the contents of the remove script file 'apRemoveScript'.\n"); -fprintf(stdout,"Enable each appropriate unix command by removing the leading '#'\n"); -fprintf(stdout,"character from the line\n"); -fprintf(stdout,"Then invoke the following unix commands:\n"); -fprintf(stdout,"\n"); -fprintf(stdout,"%%\tapRemoveScript\n"); -fprintf(stdout,"\tfollowed by\n"); -fprintf(stdout,"%%\tapCreateShadow\n"); -} diff --git a/src/util/bfRing.c b/src/util/bfRing.c deleted file mode 100644 index bf25e7d50..000000000 --- a/src/util/bfRing.c +++ /dev/null @@ -1,229 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 03-09-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 03-09-90 rac initial version - * .02 07-30-91 rac installed in SCCS - * - * make options - * -DvxWorks makes a version for VxWorks - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE bfRing.c - fixed size ring file 'manager' for text -* -* DESCRIPTION -* -*-***************************************************************************/ - -#include - -#ifdef vxWorks -# include -# include /* for O_RDWR and O_RDONLY definitions */ -# include -#else -# include -# include /* for O_RDWR and O_RDONLY definitions */ -#endif - - -#ifndef vxWorks - main(argc, argv) - int argc; /* number of command line args */ - char *argv[]; /* command line args */ - { - int stat=OK; /* status */ - char *name; /* pathname to file */ - char *command; /* command */ - int nBytes=0; /* number of bytes for file size */ - - if (argc >= 3) { /* must be command and >= 2 arg */ - name = argv[1]; - command = argv[2]; - } - else - stat = ERROR; - if (strcmp(command, "create") == 0) { - if (argc == 4) { - if (sscanf(argv[3], "%d", &nBytes) != 1) - stat = ERROR; - } - else if (argc != 3) - stat = ERROR; - } - if (stat == OK) { - stat = bfRing(name, command, nBytes); - } - if (stat != OK) { - printf("Usage: %s name command [nBytes]\n", argv[0]); - exit(1); - } - exit(0); - } -#endif - -/*+/subr********************************************************************** -* NAME bfRing - implement ring files -* -* DESCRIPTION -* Provide a 'shell' for using ring files -* -* RETURNS -* OK, or -* ERROR -* -*-*/ -int -bfRing(name, command, nBytes) -char *name; /* file name */ -char *command; /* command */ -int nBytes; /* number of bytes, for 'create' */ -{ - char message[80]; /* temp for status message */ - int stat; /* status return */ - - BF_DESC *pDesc=NULL; /* pointer to block file descriptor */ - - BF_BLOCK *pBuf; /* buffer for last read or acquired block */ - long blockNum; /* blockNum of last read or acquired block */ - long nBlocks; /* number of blocks to create */ - long blockSize; /* size of blocks */ - - if (strlen(name) >= GEN_FNAME_DIM) { - printf("bfRing: file name too long\n"); - return ERROR; - } - - if (strcmp(command, "create") == 0) { -/*---------------------------------------------------------------------------- -* create - create and initialize a named block file for a ring file; the -* file will be a BF_FLAG_GROW file, with no free blocks. -*---------------------------------------------------------------------------*/ - int i; - long fileFlags; /* flags */ - long maxBlocks; /* size limit */ - - blockSize = 1000; - if (nBytes < blockSize*2) { - printf("nBytes must be at least %d\n", blockSize*2); - return ERROR; - } - nBlocks = 1 + (nBytes-1)/blockSize; /* size for user info + block0 */ - - pDesc = bfCreate(name, BF_TYPE_RING, - 1, blockSize, BF_FLAG_GROW, nBlocks); - stat = bfClose(&pDesc); - } - else if (strcmp(command, "info") == 0) { -/*---------------------------------------------------------------------------- -* info - print some information about the file -*---------------------------------------------------------------------------*/ - pDesc = bfOpen(name, O_RDONLY, BF_TYPE_RING, 0); - if (pDesc == NULL) { - printf("bfRing: can't open %s\n", name); - return ERROR; - } - printf("bfRing: head, tail = %d %d\n", - BfB0RingHead(pDesc), BfB0RingTail(pDesc)); - } - else if (strcmp(command, "retrieve") == 0) { -/*---------------------------------------------------------------------------- -* retrieve - read the information from the file and write to stdout -*---------------------------------------------------------------------------*/ - char record[80]; - - pDesc = bfOpen(name, O_RDONLY, BF_TYPE_RING, 0); - if (pDesc == NULL) { - printf("bfRing: can't open %s\n", name); - return ERROR; - } - - while (bfRingFgets(record, 80, pDesc) != NULL) - fputs(record, stdout); - - stat = bfClose(&pDesc); - } - else if (strcmp(command, "store") == 0) { -/*---------------------------------------------------------------------------- -* store - store information from stdin into the file -* -* BUGS -* o need to address races between storing and retrieving -*---------------------------------------------------------------------------*/ - int i; - long flink; - char c; - char record[80]; - - pDesc = bfOpen(name, O_RDWR, BF_TYPE_RING, 0); - if (pDesc == NULL) { - printf("bfRing: can't open %s\n", name); - return ERROR; - } - - while (fgets(record, 80, stdin) != NULL) { - if (bfRingFputs(record, pDesc) == EOF) { - printf("error on bfRingFputs()\n"); - break; - } - } - - stat = bfClose(&pDesc); - } - else if (strcmp(command, "unlock") == 0) { -/*---------------------------------------------------------------------------- -* unlock - remove the file write lock for the file -*---------------------------------------------------------------------------*/ - if (strlen(name) > 0) { - char lockName[GEN_FNAME_DIM+5]; /* name of lock file */ - - sprintf(lockName, "%s.lock", name); - if ((stat = unlink(lockName)) != 0) - perror("bfRing: removing lock file"); - } - else { - printf("syntax error; "); - printf("usage: bfRing name unlock\n"); - } - } -/*---------------------------------------------------------------------------- -* -*---------------------------------------------------------------------------*/ - else { - printf("Legal commands are:\n"); - printf(" name create [nBytes]\n"); - printf(" name info\n"); - printf(" name retrieve\n"); - printf(" name store -#include -#include -#else -#include -#include -#endif - -#ifndef ERROR -#define ERROR -1 -#endif -#ifndef OK -#define OK 0 -#endif - -#define PUT 0 -#define GET 1 -#define MAXLINE 150 - -char errmsg[MAXLINE]; - -long calcPerform(); -long postfix(); -void calcTest(); -long doTestLine(); - -#ifndef vxWorks -main() -{ - - calcTest(); - -} -#endif - -void calcTest() -{ - char str[MAXLINE]; - - char expression[MAXLINE]; - char parmList[MAXLINE]; - char value[MAXLINE]; - int fieldCount; - long status; - double parm[12]; - short i; - - /* get test line */ - while ( gets(str)) { - /* print and skip null lines and comment lines */ - if ( str[0]==NULL || str[0] == '!' ) { - printf("%s\n",str); - continue; - } - - /* parse input line for fields */ - fieldCount=sscanf(str," \"%[^\"]\" \"%[^\"]\" %s ", - expression,parmList,value); - - /* check field count */ - if ( fieldCount < 2 || fieldCount > 3 ) { - printf("\n%s\n",str); - printf ("***** ERROR ***** input field count %d incorrect\n",fieldCount); - continue; - } - - /* parse parmList for parameters */ - status=sscanf(parmList,"%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", - &parm[0],&parm[1],&parm[2],&parm[3],&parm[4],&parm[5], - &parm[6],&parm[7],&parm[8],&parm[9],&parm[10],&parm[11]); - if( status == EOF ){ - printf("\n%s\n",str); - printf ("***** ERROR ***** Error in parameter list %s \n",parmList); - continue; - } - - /* zero out rest of parameters */ - for (i=status; i<12; i++) parm[i]=0.; - - - /* execute test line */ - status=doTestLine(expression,parm,value,fieldCount); - if ( status ){ - printf("\n%s\n",str); - printf ("***** ERROR ***** status=%d %s\n",status,errmsg); - } - - } - printf ("\ncalcTest ALL DONE\n\n\n"); -} - -long doTestLine(expression,parm,value,fieldCount) -char expression[]; -double parm[12]; -char value[]; -int fieldCount; -{ - long status=0; - short error_number=0; - /* rpbuf dimension must be >= 10*(dimension_of_CALC_field/2) */ - /* since each constant in the expression now takes 9 bytes (chars): 1(code)+8(double) */ - char rpbuf[184]; - char valString[80]; - double val; - - /* convert an algebraic expression to symbolic postfix */ - status=postfix(expression,rpbuf,&error_number); - if(status || error_number) { - sprintf(errmsg,"postfix error: status=%ld error_number=%d \n",status,error_number); - return ERROR; - } - - /* perform calculation */ - status=calcPerform(parm,&val,rpbuf); - if(status) { - sprintf(errmsg,"calcPerform error: status=%ld \n",status); - return ERROR; - } - - /* convert calcPerform result to string */ - sprintf(valString,"%-g",val); - - /* verify calcPerform result*/ - if ( fieldCount == 3 ){ - - status=strcmp(value,valString); - if (status) { - sprintf(errmsg,"verify failed: calcPerform result: val=%s",valString); - return ERROR; - } - } - else printf("calcPerform result: %s\n",valString); - - return OK; -} - diff --git a/src/util/checkDvlNode.c b/src/util/checkDvlNode.c deleted file mode 100644 index 66423b9d5..000000000 --- a/src/util/checkDvlNode.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * CHECKDVLNODE.C - * - * must be run from the top of an EPICS development node - * - * Reports to stdout: - * Regular files in this node that are out-for-edit. - * These are errors if uid doesn't agree. - * Regular files in this node that should be links to epics - * Links that point to a dest. outside of this node and the final - * dest. is not in an EPICS node (Note: vw should be excluded). - * Other Directories containing Regular files not under sccs control. - * These directories should be manually checked for private - * Imakefiles/Makefiles ... - * - * BUGS - only checks final destination of links. - * if a link points outside of the current node - * but the final real file/directory resides in epics - * it is not reported. Then if it is changed in the outside - * node you won't know it w/o running this tool again. - * - * distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * rcz - */ -#include -#include -#include -#include -#include -#include -#include -#include - -void procDirEntries(); -int processFile(); -int getRealEpicsPath(); -int checkLink(); -int dirwalk(); -int verbose; -extern int errno; - -#define BSIZE 128 -#define MAXMSG 256 -#define TRUE 1 -#define FALSE 0 -#define SAME 0 - -static char pdot[] = "SCCS/p."; -static char sdot[] = "SCCS/s."; -static char msgbuff[MAXMSG]; -static caddr_t pEpics = (caddr_t)NULL; -static caddr_t pDvl = (caddr_t)NULL; -static int lenEpics; -static int lenDev; - -static char *dirList[] = { - "share", - "Unix", - "Vx", - "config", - "release" -}; -#define DIR_COUNT (sizeof(dirList) / sizeof(caddr_t)) - - /**************************************************************************** - MAIN PROGRAM -****************************************************************************/ -main(argc, argv) - int argc; - char **argv; -{ - char *getcwd(); - char **pt; - char name[20]; - int i; - pt = dirList; - if ((argc > 1) && ((strncmp(argv[1], "-v", 2)) == 0)) - verbose = TRUE; - else - verbose = FALSE; - if ((pDvl = getcwd((char *)NULL, 128)) == NULL) { - fprintf(stdout, "getcwd failed\n"); - return; - } - lenDev = strlen(pDvl); - if ((getRealEpicsPath()) < 0 ) - return; - fprintf(stdout, "\n\n\n%s:\nSTARTING SEARCH FROM NODE: %s\n",argv[0], pDvl); - for (i = 0; i < DIR_COUNT; i++, pt++) { - strcpy(name, *pt); - fprintf(stdout, "Descending node --------------- %s\n",name); - procDirEntries(name, name); - } - return; -} - /**************************************************************************** -GETREALEPICSPATH - returns -1 - error, 0 - OK -****************************************************************************/ -getRealEpicsPath() -{ - caddr_t pt2; - char resolved_path[MAXPATHLEN]; - - FILE *fp; - char *epath_file = ".epicsShadowSrc"; - char epath[BSIZE];/* contents of 1st line of p.dot */ - - if ((fp = fopen(epath_file, "r")) == NULL) { - fprintf(stdout, "checkDvlNode: can't fopen %s\n", epath_file); - fprintf(stdout, "Probably not at root of shadow node\n"); - return(-1); - } - if ((fgets(epath, BSIZE, fp)) == NULL) { - fprintf(stdout, "checkDvlNode: FATAL ERROR - reading %s\n", epath_file); - return(-1); - } - fclose(fp); - lenEpics = strlen(epath); - if ( epath[lenEpics-1] == '\n' ) { - epath[lenEpics-1] = '\0'; - } - /* reset epics to real path if not on server */ - if(( pt2 = (caddr_t)realpath(epath, resolved_path)) == NULL) { - fprintf(stdout, "FATAL ERROR - failed link component of %s=%s\n", - epath, resolved_path); - return (-1); - } - lenEpics = strlen(pt2); - pEpics = (caddr_t)calloc(1,lenEpics+1); - strcpy(pEpics,pt2); - return(0); -} - /**************************************************************************** -PROCESSFILE - for each regular file: - if s.dot !exist - skip file - if s.dot exist && p.dot !exist - print error - else print dir file and contents of p.dot -****************************************************************************/ -int -processFile(name, dir, pfirstTime) - char *name; /* regular file */ - char *dir; /* current directory */ - int *pfirstTime; /* ptr to firstTime flag*/ -{ - char sccsDir[MAXNAMLEN]; - char dotName[MAXNAMLEN]; - char *pbeg; /* beg of file pathname */ - char *pend; /* beg of filename */ - struct stat stbuf; - struct stat lstbuf; - FILE *fp; - char ibuf[BSIZE];/* contents of 1st line of p.dot */ - int hasSccsDir = FALSE; - - int len, - j; - pbeg = name; - len = strlen(name); - if (len + 7 > MAXNAMLEN) { - fprintf(stdout, "processFile: pathname %s too long\n", name); - return (0); - } - /* search for last slash '/' in pathname */ - for (j = len, pend = pbeg + len; j > 0; j--, pend--) { - if (*pend == '/') - break; - } - pend++; /* points to filename */ - /* determine if dir has an SCCS sub directory */ - strcpy(sccsDir, dir); - strcat(sccsDir, "/SCCS"); - if (lstat(sccsDir, &lstbuf) == -1) { - hasSccsDir = FALSE; - } else - hasSccsDir = TRUE; - - if (!hasSccsDir) { - if (!verbose) { - if (*pfirstTime) { - fprintf(stdout, "WARNING regular files in dir: %s\n", dir); - *pfirstTime = FALSE; - } - } else { - fprintf(stdout, "WARNING regular file %s\n", name); - } - return; - } - /* form p.dot name */ - strcpy(dotName, dir); - strcat(dotName, "/"); - strcat(dotName, pdot); - strcat(dotName, pend); - if (stat(dotName, &stbuf) == -1) { /* no p.dot file */ - /* form s.dot name */ - strcpy(dotName, dir); - strcat(dotName, "/"); - strcat(dotName, sdot); - strcat(dotName, pend); - if (stat(dotName, &stbuf) == -1) { /* no s.dot file */ - if (verbose) { - fprintf(stdout, "WARNING regular file %s\n", name); - } - } else { /* has an s.dot */ - fprintf(stdout, "FATAL ERROR - file %s should be a link\n", name); - } - return; - } - if ((fp = fopen(dotName, "r")) == NULL) { - fprintf(stdout, "processFile: can't fopen %s\n", dotName); - return; - } - if ((fgets(ibuf, BSIZE, fp)) != NULL) { - fprintf(stdout, "%-20s %-25s EDIT - %s", dir, pend, ibuf); - } else - fprintf(stdout, "FATAL ERROR - reading %s%s\n", pdot, pend); - fclose(fp); - return; -} - /**************************************************************************** -PROCDIRENTRIES - process directory entries -****************************************************************************/ -void -procDirEntries(name, dir, pfirstTime) - char *name; /* entry name */ - char *dir; /* current directory */ - int *pfirstTime; /* ptr to firstTime flag*/ -{ - struct stat stbuf; - if (lstat(name, &stbuf) == -1) { - fprintf(stdout, "procDirEntries: can't access %s\n", name); - return; - } - if ((stbuf.st_mode & S_IFMT) == S_IFLNK) { - checkLink(name); - return; - } - if ((stbuf.st_mode & S_IFMT) == S_IFREG) { - processFile(name, dir, pfirstTime); - return; - } - if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { - dirwalk(name, procDirEntries); - } - return; -} - /**************************************************************************** -CHECKLINK - checks valid symbolic link for EPICS -****************************************************************************/ -int -checkLink(path) - char *path; -{ - char resolved_path[MAXPATHLEN]; - caddr_t pt; - /* skip any path with "/templates/" in it */ - if ((strstr(path,"/templates/")) != NULL ) - { - return; - } - if(( pt = (caddr_t)realpath(path, resolved_path)) == NULL) { - fprintf(stdout, "FATAL ERROR - failed link component of %s=%s\n", - path, resolved_path); - return; - } - /* compare $epics or beg of shadow with beg of dest */ - /* if neither present in dest - fail */ - if (((strncmp(pEpics, resolved_path, lenEpics)) == SAME ) - || ((strncmp(pDvl, resolved_path, lenDev)) == SAME )) { - return; - } else { - fprintf(stdout, - "FATAL ERROR - link '%s' must point to epics or shadow area\n\t dest='%s'\n",path,resolved_path); - } - return; -} - /**************************************************************************** -DIRWALK applies a function to each file in a directory -****************************************************************************/ -int -dirwalk(dir, fcn) - char *dir; - void (*fcn) (); -{ - char name[MAXNAMLEN]; - struct dirent *dp; - DIR *dfd; - int firstTime; - if ((dfd = opendir(dir)) == NULL) { - fprintf(stdout, "dirwalk: can't open %s\n", dir); - return; - } - firstTime = TRUE; - while ((dp = readdir(dfd)) != NULL) { - if (strcmp(dp->d_name, ".") == 0 - || strcmp(dp->d_name, "..") == 0) - continue; /* skip self and parent */ - if (strlen(dir) + strlen(dp->d_name) + 2 > sizeof(name)) - fprintf(stdout, "dirwalk: name %s/%s too long\n", - dir, dp->d_name); - else { - sprintf(name, "%s/%s", dir, dp->d_name); - (*fcn) (name, dir, &firstTime); - } - } - closedir(dfd); -} diff --git a/src/util/cmdClient.c b/src/util/cmdClient.c deleted file mode 100644 index 9137499b2..000000000 --- a/src/util/cmdClient.c +++ /dev/null @@ -1,321 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 11-26-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-26-90 rac initial version - * .02 07-30-91 rac installed in SCCS - * .03 09-11-91 joh updated for v5 vxWorks - * .03 11-07-91 rac be more forgiving of unexpected interactions - * .04 12-06-91 rac total rewrite, Unix-only, no LWP - * - * make options - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code, including checks on - * malloc'd memory - */ -/*+/mod*********************************************************************** -* TITLE cmdClient.c - general purpose client for command-based servers -* -* DESCRIPTION -* Connects to a text-command-based server. -* -* Usage on SunOS: -* % cmdClient hostName portNum -* or -* execl("cmdClient", "cmdClient", "hostName", "portNum", -* (char *)0); -* -* Usage on VxWorks: -* > cmdClient "hostName",portNum -* -* BUGS -* o the stdout stream from this program contains, intermixed, the -* server's stdout and stderr streams -* o not all signals are caught -*-***************************************************************************/ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - - - -/*----------------------------------------------------------------------------- -* prototypes -*----------------------------------------------------------------------------*/ -int cmdcl(); -void cmdclCmdProcess(); -char *cmdclInTask(); -long cmdclTask(); -void cmdclTaskSigHandler(); - -/*----------------------------------------------------------------------------- -* global definitions -*----------------------------------------------------------------------------*/ - -jmp_buf sigEnv; /* environment for longjmp at signal time */ - -main(argc, argv) -int argc; /* number of command line args */ -char *argv[]; /* command line args */ -{ - char *hostName; /* host name for server */ - int portNum; /* port number for server */ - - if (argc != 3) /* must be command and 2 args */ - goto mainUsage; - hostName = argv[1]; - if (sscanf(argv[2], "%d", &portNum) != 1) { - printf("error scanning port number\n"); - goto mainUsage; - } - - return cmdClient(hostName, portNum); - -mainUsage: - printf("Usage: %s serverHostName serverPortNumber\n", argv[0]); - return -1; -} - -/*+/subr********************************************************************** -* NAME cmdClient - shell callable interface for cmdClient -* -*-*/ -int -cmdClient(hostName, portNum) -char *hostName; /* I host name for server */ -int portNum; /* I port number for server */ -{ - long stat; /* status return from calls */ - int serverSock=-1; /* socket connected to server */ - char serverBuf[80]; - char *pBuf; - FILE *myIn=NULL; - FILE *myOut=NULL; - char *findNl; - char message[80]; - int i; - char keyboard[80]; /* line from keyboard */ - int eofFlag=0; - int discardNL=0; - - genSigInit(cmdclTaskSigHandler); - - if (setjmp(sigEnv) != 0) - goto cmdclTaskWrapup; - -/*----------------------------------------------------------------------------- -* attempt to connect to the server. If the connection is successful, -* print the message returned by the server. Then open two streams to -* the socket, one for characters from keyboard to server, the other -* for characters from server to stdout. -*----------------------------------------------------------------------------*/ - if ((i=ezsConnectToServer(&serverSock, portNum, hostName, serverBuf)) < 0) { - if (i == -1) { - (void)sprintf(message, "connect to %s port:%d", hostName, portNum); - perror(message); - } - else - printf("%s\n", serverBuf); - serverSock = -1; - goto cmdclTaskWrapup; - } - printf("%s\n", serverBuf); - if (ezsFopenToFd(&myIn, &serverSock) < 0) { - perror("myIn"); - myIn = NULL; - goto cmdclTaskWrapup; - } - setbuf(myIn, NULL); - if (ezsFopenToFd(&myOut, &serverSock) < 0) { - perror("myOut"); - myOut = NULL; - goto cmdclTaskWrapup; - } - -/*---------------------------------------------------------------------------- -* "processing loop" -* do the interactions with the server, attempting as much as possible -* to show the messages as they come in from the server. -*---------------------------------------------------------------------------*/ - while (!eofFlag) { - if (cmdclInTask(keyboard) != NULL) { - fputs(keyboard, myOut); - fflush(myOut); - } - - if (ezsCheckFpRead(myIn)) { - int i, c; - - i = 0; - while (ezsCheckFpRead(myIn)) { - if ((c = fgetc(myIn)) == EOF) { - eofFlag++; - break; - } - serverBuf[i++] = c; - if (i >= 79 || c == '\n') - break; - } - pBuf = serverBuf; - serverBuf[i] = '\0'; - if (i > 0) { - char *findChr; - if ((findChr = index(pBuf, '#')) != NULL) { - while (pBuf != findChr) { - putchar(*pBuf); - pBuf++; - } - if (strncmp(pBuf, "#p#r#", 5) == 0) { - pBuf += 5; - discardNL = 1; - } - } - else - pBuf = serverBuf; - if (discardNL) { - if ((findNl = index(pBuf, '\n')) != NULL) { - *findNl = '\0'; - discardNL = 0; - } - } - fputs(pBuf, stdout); - fflush(stdout); - } - else { - if (strncmp(keyboard, "quit", 4) == 0) - break; - else if (strncmp(keyboard, "close", 5) == 0) - break; - else if (strncmp(keyboard, "disconnect", 10) == 0) - break; - else - printf("null message from server\n"); - } - } - sleep(1); - } - -cmdclTaskWrapup: - if (myIn != NULL) - fclose(myIn); - if (myOut != NULL) - fclose(myOut); - if (serverSock >= 0) - close(serverSock); - - return 0; -} - -/*+/subr********************************************************************** -* NAME cmdclTaskSig - signal handling and initialization -* -* DESCRIPTION -* These routines set up for the signals to be caught for cmdclTask -* and handle the signals when they occur. -* -* RETURNS -* void -* -* BUGS -* o not all signals are caught -* o it's not clear how useful it is to catch the signals which originate -* from the keyboard -* -*-*/ -void -cmdclTaskSigHandler(signo) -int signo; -{ - printf("entered cmdclTaskSigHandler for signal:%d\n", signo); - signal(signo, SIG_DFL); - longjmp(sigEnv, 1); -} - -/*+/subr********************************************************************** -* NAME cmdclInTask - handle keyboard input -* -* DESCRIPTION -* Checks to see if input is available and reads it, if so. If -* there is EOF, then question is asked whether to shut down the -* server. -* -* RETURNS -* char *, or -* NULL -* -*-*/ -char * -cmdclInTask(buf) -char *buf; -{ - char *input; - char message[80]; - fd_set fdSet; /* set of fd's to watch with select */ - int fdSetWidth; /* width of select bit mask */ - struct timeval fdSetTimeout;/* timeout interval for select */ - - struct rlimit rlp; - -/* MDA - replace obsolete system call - fdSetWidth = getdtablesize(); -*/ - getrlimit(RLIMIT_NOFILE,&rlp); - fdSetWidth = rlp.rlim_cur; - - fdSetTimeout.tv_sec = 0; - fdSetTimeout.tv_usec = 0; - FD_ZERO(&fdSet); - FD_SET(fileno(stdin), &fdSet); - - if (select(fdSetWidth, &fdSet, NULL, NULL, &fdSetTimeout) == 0) - return NULL; - if (fgets(buf, 80, stdin) == NULL) { - strcpy(buf, "quit\n"); - clearerr(stdin); - } - if (strncmp(buf, "quit", 4) == 0) { - (void)printf("stop the server (y/n) ? "); - if (fgets(message, 80, stdin) == NULL) { - strcpy(message, "y"); - } - if (message[0] == 'y' || message[0] == 'Y') - strcpy(buf, "quit\n"); - else - strcpy(buf, "\n"); - } - - return buf; -} diff --git a/src/util/cmdProto.c b/src/util/cmdProto.c deleted file mode 100644 index a2024bfd0..000000000 --- a/src/util/cmdProto.c +++ /dev/null @@ -1,678 +0,0 @@ -/* share/src/util $Id$ - * Author: Roger A. Cole - * Date: 10-24-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 10-24-90 rac initial version - * .02 07-30-91 rac installed in SCCS; changed to use EPICS_ENV.. - * .03 09-11-91 joh updated for v5 vxWorks - * .04 12-08-91 rac rewrite for Unix-only, without LWP - * - * make options - * -DNDEBUG don't compile assert() checking - */ -/*+/mod*********************************************************************** -* TITLE cmdProto - prototype for a multi-threaded program with command interface -* -* DESCRIPTION -* This skeleton can be used as the basis for a multi-threaded program -* which interfaces to a user with text strings, as from a keyboard. -* Several generic capabilities are provided: -* -* o scanning of input control lines -* o re-directing of input to come from a file -* o running as a stand-alone program, or as a server or client, -* with socket-based communications -* o on-line help -* o handling cleanup on exception conditions (such as bus error) -* -* To run as a server, specify "server" as a command line option. -* -* To run as a client, specify "hostName" as a command line option. -* -* Under SunOS, running under dbx doesn't allow testing the error -* handling features of the code--the debugger catches the signals. -* To do such testing, run without dbx. -* -* To use this skeleton: -* -* Change Zzz, zzz, and ZZZ to a desired name -* Customize a context block -* Remove the "server" items, if they aren't going to be used -* Add additional commands in zzzCmdCrunch -* Add additional help info in zzzInitAtStartup. Usually, this -* will mean adding to helpCmdsSpec and helpUsage. For -* any commands needing an individual help topic, then a -* specific HELP_TOPIC will have to be defined. -* If you're using sockets, assign a port number in , and -* change glZzzIPPort to the IPPORT_xxx you've chosen. -* -* SunOS -* o link with genLib.a -* -* BUGS -* o this program should use tasks.h to establish priorities, stack -* sizes, etc. -* o not all signals are caught -* o using this skeleton, it isn't possible to have several invocations -* of the program running simultaneously -* -*-***************************************************************************/ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -/*/subhead ZZZ_CTX------------------------------------------------------- -* ZZZ_CTX - context information -* -* A zzz descriptor is the `master handle' which is used for -* handling business. -*----------------------------------------------------------------------------*/ - -typedef struct zzzCtx { - jmp_buf sigEnv; /* environment for longjmp at signal time */ - int listenSock; /* fd for server's "listen" socket */ - int inUse; /* 1 says "presently engaged" by a client */ - int inUseInit; /* 1 says initialized */ - char *inUseName; /* name of client's host */ - char *oldPrompt; /* prompt prior to socket connect */ - int stop; /* 1 says stop operations */ - int clientSock; /* fd for socket to client */ - int reopenIO; /* std... should be re-directed */ - int reopenIOoption; /* 0,1,2; option for arFreopenAllStd */ - int oldStdinFd; /* original fd for stdin, before redirect */ - int oldStdoutFd; /* original fd for stdout, before redirect */ - int oldStderrFd; /* original fd for stderr, before redirect */ -} ZZZ_CTX; - -/*----------------------------------------------------------------------------- -* prototypes -*----------------------------------------------------------------------------*/ -int zzz(); -void zzzCmdCrunch(); -void zzzListenCheck(); -void zzzListenSetReopen(); -void zzzSigHandler(); -long zzzInitAtStartup(); - -/*----------------------------------------------------------------------------- -* global definitions -*----------------------------------------------------------------------------*/ -static CX_CMD glZzzCxCmd; -static CX_CMD *pglZzzCxCmd=NULL; -static ZZZ_CTX glZzzCtx; -static ZZZ_CTX *pglZzzCtx=NULL; -static char *glZzzId="zzz 11/27/90"; -static int glZzzIPPort; -static int serverMode=0; -static chid pCh; - - -/*+/subr********************************************************************** -* NAME main -* -* DESCRIPTION -* This program is a prototype skeleton for building programs -* which interact with a keyboard/window environment. The program -* can be started with any of: -* -* % cmdProto (runs as normal interactive program) -* % cmdProto server (runs as a server) -* % cmdProto server& (runs as a server) -* % cmdProto hostName (runs as a client to cmdProto on hostName) -* -*-*/ -main(argc, argv) -int argc; /* number of command line args */ -char *argv[]; /* command line args */ -{ - long stat; /* status return from calls */ - char portText[10]; - int sigNum; - int gooseOutput=0; - - setbuf(stdout, NULL); - pglZzzCtx = &glZzzCtx; - pglZzzCxCmd = &glZzzCxCmd; - - stat = zzzInitAtStartup(pglZzzCtx, pglZzzCxCmd); - assertAlways(stat == OK); - - if (argc > 2) { - printf("Usage: %s [server or hostName]\n", argv[0]); - exit(1); - } - else if (argc == 2) { - if (envGetConfigParam(&EPICS_CMD_PROTO_PORT, 10, portText) == NULL) { - printf("error getting %s\n", EPICS_CMD_PROTO_PORT.name); - return ERROR; - } - sscanf(portText, "%d", &glZzzIPPort); - if (strcmp(argv[1], "server") != 0) { - execlp("cmdClient", "cmdClient", argv[1], portText, (char *)0); - (void)printf("couldn't exec to cmdClient\n"); - return ERROR; - } - serverMode = 1; - pglZzzCtx->inUseName = argv[1]; -/*----------------------------------------------------------------------------- -* establish a socket to use to listen for potential clients to connect -*----------------------------------------------------------------------------*/ - if (ezsCreateListenSocket(&pglZzzCtx->listenSock, glZzzIPPort) != 0) { - perror("create listen socket"); - exit(1); - } - } - else - pglZzzCtx->inUseName = "shell"; - -#if 1 - stat = ca_task_initialize(); - assert(stat == ECA_NORMAL); -#endif - - genSigInit(zzzSigHandler); - if ((sigNum = setjmp(pglZzzCtx->sigEnv)) != 0) { - (void)printf("zzzTask signal received: %d\n", sigNum); - goto zzzTaskWrapup; - } - - while (!pglZzzCtx->stop) { - if (serverMode) - zzzListenCheck(&pglZzzCxCmd); - if (!serverMode || pglZzzCtx->inUse) { -#if 0 - if (gooseOutput == 0) - gooseOutput = 30 * pglZzzCxCmd->promptFlag; -#endif - if (cmdRead(&pglZzzCxCmd) != NULL) { - if (serverMode && pglZzzCxCmd->inputEOF) { - pglZzzCxCmd->pCommand = "close"; - pglZzzCxCmd->inputEOF = 0; - } - zzzCmdCrunch(&pglZzzCxCmd, pglZzzCtx); - } -#if 0 - if (gooseOutput && serverMode && pglZzzCtx->inUse) { - if (gooseOutput % 2 == 0) { - (void)printf("\001"); - } - gooseOutput--; - } -#endif - } -#if 1 - stat = ca_pend_event(0.001); - assert(stat != ECA_EVDISALLOW); -#endif - fflush(stdout); /* flushes needed for socket I/O */ - fflush(stderr); - fflush(pglZzzCxCmd->dataOut); - sleep(1); -/* MDA - usleep isn't POSIX - usleep(100000); /* sleep .1 second */ -*/ - } - - return OK; - -zzzTaskWrapup: - if (pglZzzCtx->reopenIO) { - (void)zzzFreopenAllStd(pglZzzCtx,pglZzzCtx->reopenIOoption); - pglZzzCtx->reopenIO = 0; - } - zzzListenQuit(&pglZzzCxCmd); - - /* put code for cleanup here */ - -#if 1 - stat = ca_task_exit(); - if (stat != ECA_NORMAL) - (void)printf("zzz: ca_task_exit error: %s\n", ca_message(stat)); -#endif - - if (pglZzzCxCmd->dataOutRedir) - fclose(pglZzzCxCmd->dataOut); - - fflush(stdout); /* flushes needed for sockets */ - fflush(stderr); -} - -/*+/subr********************************************************************** -* NAME zzzSigHandler - signal handling -* -* DESCRIPTION -* These routines set up for the signals to be caught for zzzTask -* and handle the signals when they occur. -* -* RETURNS -* void -* -* BUGS -* o not all signals are caught -* o it's not clear how useful it is to catch the signals which originate -* from the keyboard -* -*-*/ -static void -zzzSigHandler(signo) -int signo; -{ - if (signo == SIGPIPE) { - if (serverMode) - zzzListenClose(&pglZzzCxCmd); - return; - } - printf("entered zzzSigHandler for signal:%d\n", signo); - signal(signo, SIG_DFL); - longjmp(pglZzzCtx->sigEnv, signo); -} - -/*+/subr********************************************************************** -* NAME zzzCmdCrunch - process a command line -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -*-*/ -static void -zzzCmdCrunch(ppCxCmd, pZzzCtx) -CX_CMD **ppCxCmd; /* IO ptr to pointer to command context */ -ZZZ_CTX *pZzzCtx; /* IO pointer to zzz context */ -{ - CX_CMD *pCxCmd; /* local copy of pointer, for convenience */ - - pCxCmd = *ppCxCmd; - if (strcmp(pCxCmd->pCommand, "assert0") == 0) { -/*----------------------------------------------------------------------------- -* under SunOS, this generates SIGABRT -*----------------------------------------------------------------------------*/ - assertAlways(0); - } - else if (strcmp(pCxCmd->pCommand, "quit") == 0) { - pZzzCtx->stop = 1; - if (serverMode) - zzzListenClose(ppCxCmd); - } - else if (strcmp(pCxCmd->pCommand, "trap") == 0) { - int *j; - j = (int *)(-1); - j = (int *)(*j); - } - else if (strcmp((*ppCxCmd)->pCommand, "close") == 0) { - if (*ppCxCmd != (*ppCxCmd)->pCxCmdRoot) - (void)printf("close illegal in source'd file\n"); - else if (strcmp(pglZzzCtx->inUseName, "shell") == 0) - (void)printf("close illegal--zzz not running as server\n"); - else if (serverMode) { - zzzListenClose(ppCxCmd); - } - } - else if (strcmp((*ppCxCmd)->pCommand, "dataOut") == 0) { - if ((*ppCxCmd)->dataOutRedir) - fclose ((*ppCxCmd)->dataOut); - (*ppCxCmd)->dataOutRedir = 0; - if (nextNonSpaceField( &(*ppCxCmd)->pLine, &(*ppCxCmd)->pField, - &(*ppCxCmd)->delim) < 1) - (*ppCxCmd)->dataOut = stdout; - else { - (*ppCxCmd)->dataOut = fopen((*ppCxCmd)->pField, "a"); - if ((*ppCxCmd)->dataOut == NULL) { - (void)printf("couldn't open %s\n", (*ppCxCmd)->pField); - (*ppCxCmd)->dataOut = stdout; - (*ppCxCmd)->dataOutRedir = 0; - } - else - (*ppCxCmd)->dataOutRedir = 1; - } - } - else if (strcmp((*ppCxCmd)->pCommand, "search") == 0) { - ca_search("jjj", &pCh); - ca_pend_io(.001); - } - else if (strcmp((*ppCxCmd)->pCommand, "clear") == 0) { - ca_clear_channel(pCh); - ca_pend_io(.001); - } - else if (strcmp((*ppCxCmd)->pCommand, "server") == 0) { - (void)printf( "\"server\" legal only on command line\n"); - (void)printf( "use help usage for more information\n"); - } - else if (strcmp((*ppCxCmd)->pCommand, "source") == 0) { - cmdSource(ppCxCmd); - } - else { -/*---------------------------------------------------------------------------- -* help (or illegal command) -*----------------------------------------------------------------------------*/ - (void)nextNonSpaceField(&pCxCmd->pLine, &pCxCmd->pField, - &pCxCmd->delim); - helpIllegalCommand(stdout, &pCxCmd->helpList, pCxCmd->pCommand, - pCxCmd->pField); - } - - return; -} - -/*+/subr********************************************************************** -* NAME zzzListenCheck - listen for client connections -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o cleanup of listen socket isn't dealt with. Under SunOS, the system -* seems to clean up OK. -* -* In fact, under SunOS, shutdown and/or close seem to inhibit proper -* cleanup by the system. -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -void -zzzListenCheck(ppCxCmd) -CX_CMD **ppCxCmd; /* IO ptr to pointer to command context */ -{ - long stat; - char clientName[30]; - static char sockPrompt[80]; - -/*----------------------------------------------------------------------------- -* check to see if a connect attempt has been made. If the server is -* already in use by a client, connect attempts will be rejected. -*----------------------------------------------------------------------------*/ - if (ezsListenExclusiveUse(&pglZzzCtx->clientSock, - &pglZzzCtx->listenSock, &pglZzzCtx->inUse, - clientName, glZzzId) < 0) { - perror("check for connect attempt"); - exit(1); - } - - if (pglZzzCtx->inUse && pglZzzCtx->inUseInit == 0) { -/*----------------------------------------------------------------------------- -* When a connect attempt succeeds, change stdin and stdout to use -* the socket, so that server I/O (i.e., I/O for this program) will -* automatically be re-directed to the client. This must be done -* for all tasks in this program. -* -* The prompt is changed to a special prompt which ends witn \n. This -* is done to avoid buffer flushing problems on some operating systems. -* A special prefix of "#p#r#" is added to the normal prompt so that -* the client knows that some massaging needs to be done before -* displaying the prompt to the user. -*----------------------------------------------------------------------------*/ - (void)printf("%s connected\n", clientName); - if (zzzFreopenAllStd(pglZzzCtx, 1) != OK) - assertAlways(0); - pglZzzCtx->oldPrompt = (*ppCxCmd)->prompt; - assert(strlen(pglZzzCtx->oldPrompt) < 72); - (void)sprintf(sockPrompt, "#p#r#%s\n", pglZzzCtx->oldPrompt); - (*ppCxCmd)->prompt = sockPrompt; - zzzListenSetReopen(2); /* reopen all other tasks to socket */ - pglZzzCtx->inUseInit = 1; - (*ppCxCmd)->promptFlag = 1; -#if 0 - stat = zzzStartup(serverMode, clientName); - assertAlways(stat == OK); -#endif - } - -} - -/*+/subr********************************************************************** -* NAME zzzListenClose -* -*-*/ -long -zzzListenClose(ppCxCmd) -CX_CMD **ppCxCmd; /* IO ptr to pointer to command context */ -{ - if (pglZzzCtx->inUse) { -#if 0 - shutdown(pglZzzCtx->clientSock, 2); -#endif - close(pglZzzCtx->clientSock); - pglZzzCtx->clientSock = -1; - pglZzzCtx->inUse = 0; - pglZzzCtx->inUseInit = 0; - if (zzzFreopenAllStd(pglZzzCtx, 0) != OK) - assertAlways(0); - (void)printf("%s disconnected\n", pglZzzCtx->inUseName); - (*ppCxCmd)->prompt = pglZzzCtx->oldPrompt; - zzzListenSetReopen(0); /* reopen all other tasks to std... */ - } -} - -/*+/subr********************************************************************** -* NAME zzzListenQuit -* -*-*/ -long -zzzListenQuit(ppCxCmd) -CX_CMD **ppCxCmd; /* IO ptr to pointer to command context */ -{ - if (pglZzzCtx->clientSock != -1) { - shutdown(pglZzzCtx->clientSock, 2); - close(pglZzzCtx->clientSock); - } -#if 0 - shutdown(pglZzzCtx->listenSock, 2); - close(pglZzzCtx->listenSock); -#endif - return OK; -} - -/*+/subr********************************************************************** -* NAME zzzListenSetReopen -* -*-*/ -void -zzzListenSetReopen(option) -int option; /* I option for reopen for use with zzzFreopenAllStd */ -{ - pglZzzCtx->reopenIOoption = option; - pglZzzCtx->reopenIO = 1; -} - -/*+/subr********************************************************************** -* NAME zzzFreopenAllStd - reopen stdin, stdout, and stderr -* -* DESCRIPTION -* -* RETURNS -* OK, or -* ERROR (an error message has been printed) -* -* BUGS -* o text -* -*-*/ -static int -zzzFreopenAllStd(pCtx, option) -ZZZ_CTX *pCtx; /* IO pointer to zzz context */ -int option; /* I activity selector: - 0 set back to use old fd's - 1 use client socket, save old fd's - 2 use client socket, don't save old fd's */ -{ - fflush(stdout); - fflush(stderr); - if (option == 0) { - if (ezsFreopenToFd(stdin, &pCtx->oldStdinFd, NULL) < 0) { - perror("restore stdin"); - return ERROR; - } - if (ezsFreopenToFd(stdout, &pCtx->oldStdoutFd, NULL) < 0) { - perror("restore stdout"); - return ERROR; - } - if (ezsFreopenToFd(stderr, &pCtx->oldStderrFd, NULL) < 0) { - perror("restore stderr"); - return ERROR; - } - } - else if (option == 1) { - if (ezsFreopenToFd(stdin, &pCtx->clientSock, &pCtx->oldStdinFd) < 0) { - perror("reopen stdin"); - return ERROR; - } - if (ezsFreopenToFd(stdout, &pCtx->clientSock, &pCtx->oldStdoutFd) < 0) { - perror("reopen stdout"); - return ERROR; - } - if (ezsFreopenToFd(stderr, &pCtx->clientSock, &pCtx->oldStderrFd) < 0) { - perror("reopen stderr"); - return ERROR; - } - } - else if (option == 2) { - if (ezsFreopenToFd(stdin, &pCtx->clientSock, NULL) < 0) { - perror("reopen stdin"); - return ERROR; - } - if (ezsFreopenToFd(stdout, &pCtx->clientSock, NULL) < 0) { - perror("reopen stdout"); - return ERROR; - } - if (ezsFreopenToFd(stderr, &pCtx->clientSock, NULL) < 0) { - perror("reopen stderr"); - return ERROR; - } - } - return OK; -} - -/*+/subr********************************************************************** -* NAME zzzInitAtStartup - initialization for zzz -* -* DESCRIPTION -* Perform several initialization duties: -* o initialize the zzz context -* o initialize the command context block -* o initialize the help information -* -* RETURNS -* OK, or -* ERROR -* -* BUGS -* o text -* -*-*/ -static long -zzzInitAtStartup(pZzzCtx, pCxCmd) -ZZZ_CTX *pZzzCtx; -CX_CMD *pCxCmd; -{ - /* code to initialize zzz context here */ - pZzzCtx->inUse = 0; - pZzzCtx->listenSock = -1; - pZzzCtx->clientSock = -1; - pZzzCtx->oldStdinFd = -1; - pZzzCtx->oldStdoutFd = -1; - pZzzCtx->oldStderrFd = -1; - - cmdInitContext(pCxCmd, " zzz: "); - -/*----------------------------------------------------------------------------- -* help information initialization -*----------------------------------------------------------------------------*/ - helpInit(&pCxCmd->helpList); -/*----------------------------------------------------------------------------- -* help info--generic commands -*----------------------------------------------------------------------------*/ - helpTopicAdd(&pCxCmd->helpList, &pCxCmd->helpCmds, "commands", "\n\ -Generic commands are:\n\ - bg\n\ - close (use help usage for more info)\n\ - dataOut [filePath] (default is to normal output)\n\ - help [topic]\n\ - quit (or ^D) (use help usage for more info)\n\ - source filePath\n\ -"); -/*----------------------------------------------------------------------------- -* help info--bg command -*----------------------------------------------------------------------------*/ - helpTopicAdd(&pCxCmd->helpList, &pCxCmd->helpBg, "bg", "\n\ -Under SunOS, no bg command is directly available. Instead, if zzz\n\ -is being run from the C shell (csh), it can be put in the background\n\ -using several steps from the keyboard (with the first % on each line being\n\ -the prompt from csh):\n\ - type ^Z, then type\n\ - % bg %zzz\n\ -\n\ -To move zzz to the foreground, type\n\ - % fg %zzz\n\ -"); -/*----------------------------------------------------------------------------- -* help info--zzz-specific commands -*----------------------------------------------------------------------------*/ - helpTopicAdd(&pCxCmd->helpList, &pCxCmd->helpCmdsSpec, "commands", "\n\ -zzz-specific commands are:\n\ - abcdef\n\ -\n\ -Output from commands flagged with * can be routed to a file by using the\n\ -\"dataOut filePath\" command. The present contents of the file are\n\ -preserved, with new output being written at the end.\n\ -"); -/*----------------------------------------------------------------------------- -* help info--zzz usage information -*----------------------------------------------------------------------------*/ - helpTopicAdd(&pCxCmd->helpList, &pCxCmd->helpUsage, "usage", "\n\ -zzz performs some functions. This is a skeleton program.\n\ -\n\ -For information on moving zzz into the background, use the \"help bg\"\n\ -command.\n\ -\n\ -zzz can be run as a server by:\n\ - under SunOS: % zzz server\n\ -\n\ -zzz can be run as a client connecting to a zzz server on \"hostName\" by:\n\ - under SunOS: % zzz hostName\n\ -\n\ - When running zzz as a client, two commands are of special interest:\n\ -\n\ - close shuts down the client but leaves the server running\n\ - quit shuts down both the client and the server\n\ -"); - return OK; -} diff --git a/src/util/extrDoc.c b/src/util/extrDoc.c deleted file mode 100644 index e6705ed1a..000000000 --- a/src/util/extrDoc.c +++ /dev/null @@ -1,195 +0,0 @@ -/* $Id$ - * Author: Roger A. Cole - * Date: 02-11-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 02-11-90 rac initial version - * - */ -/*+/mod*********************************************************************** -* TITLE extrDoc - extract source code documentation -* -* DESCRIPTION -* `extrDoc' processes a C source file with specially formatted embedded -* documentation, producing a text file containing the extracted -* documentation. -* -* Usage: % extrDoc < xxx.c >! xxx.doc -* -* The activities of `extrDoc' center around comment blocks of the -* general form shown below. (To avoid confusing the C compiler -* when it processes this source file, '* and *' are shown in the -* example when what is really meant are the usual C commend start -* and end characters, with / used instead of the ' character.) -* -* '*+/keyword**** -* * KEY -* * comments -* *-************' -* -* The +/ turns on extracting, with the action depending on the -* keyword. As the comments in the block are written to the output, -* the leading * is removed. If the character following the * is a -* blank followed by a printing character, the blank is also removed. -* -* The keywords and their actions are: -* /mod the block constitutes a module header. The comments are -* extracted as described above. Extracting stops when the -* *- is encountered. -* -* /subr the block is a subroutine header. The comments are extracted -* as described above. When the *- is encountered, a line with -* "SYNOPSIS" is printed to the output. The lines between the -* *- and a line with { in column 1 are taken to be the synopsis -* for the subroutine, and are written directly to the output. -* -* /macro the block is a description for one or more macros. The -* treatment is the same as for /subr, except that no SYNOPSIS -* processing is done. -* -* /internal the block is a description for an `internal' routine. The -* block is not extracted. -* -* WISH LIST -* o generate output in the usual man pages form -* o generate output for PostScript -* o generate headings and subheadings based on TITLE in /mod blocks -* and NAME in /subr and /macro blocks -* o generate a table of contents with NAME items as TOC entries -*-***************************************************************************/ -#include - -main(argc, argv) -int argc; /* number of command line args */ -char *argv[]; /* command line args */ -{ - char inputBuf[120]; /* input buffer */ - int extr=0; /* extract flag; - 0: no extracting - 1: extracting in progress - 2: initialize for extracting */ - int sendFf=0; /* send a form feed; 1 says send it */ - int subr=0; /* within /subr block */ - int macro=0; /* within /macro block */ - int synopsis=0; /* extracting synopsis following /subr */ - - while (fgets(inputBuf, 120, stdin) != NULL) { - if (strncmp(inputBuf, "/*+", 3) == 0) - extr = 2; - else if (strncmp(inputBuf, "*+", 2) == 0) - extr = 2; - else if (strncmp(inputBuf, "*-", 2) == 0) { - extr = 0; - sendFf = 1; - if (subr) { - synopsis = 1; - printf("SYNOPSIS\n\n"); - } - else if (macro) - macro = 0; - } - else if (extr) { - if (sendFf) - printf("\f\n"); - sendFf = 0; - if (inputBuf[1] == ' ' && !isspace(inputBuf[2])) - printf("%s", &inputBuf[2]); - else - printf("%s", &inputBuf[1]); - } - else if (synopsis) { - if (inputBuf[0] == '{') { - subr = 0; - synopsis = 0; - } - else - printf("%s", inputBuf); - } -/*---------------------------------------------------------------------------- -* see if need to initialize for extraction -*---------------------------------------------------------------------------*/ - if (extr == 2) { - extr = 1; - if (strIndex(inputBuf, "/mod*")) { - - } - else if (strIndex(inputBuf, "/subr*")) { - subr = 1; - } - else if (strIndex(inputBuf, "/macro*")) { - macro = 1; - } - else if (strIndex(inputBuf, "/internal*")) { - extr = 0; - } - else - sendFf = 0; /* don't send FF unless new section */ - } - } - return 0; -} - -/*+/subr********************************************************************** -* NAME strIndex - look for substring -* -* DESCRIPTION -* Search a string, looking for a specific substring. -* -* RETURNS -* 0 if the substring wasn't found, else -* 1 -* -*-*/ -strIndex(string, key) -char *string; /* I string to search */ -char *key; /* I key to look for */ -{ - int keyCol; /* column within key */ - int keyLen; /* length of key */ - int searchCol; /* current column in string */ - int strCol; /* column within string */ - int strLen; /* length of string */ - - strLen = strlen(string); - keyLen = strlen(key); - - strCol = 0; - next: { - searchCol = strCol++; - if (searchCol + keyLen > strLen) - return 0; /* FAILED!! */ - else { - keyCol = 0; - loop: { - if (string[searchCol++] != key[keyCol++]) - goto next; - else if (keyCol == keyLen) - return 1; - else - goto loop; - } - } - } -} diff --git a/src/util/guiSubr.c b/src/util/guiSubr.c deleted file mode 100644 index 918cb2148..000000000 --- a/src/util/guiSubr.c +++ /dev/null @@ -1,3446 +0,0 @@ -#ifndef sun - -#else -/* @(#)guiSubr.c 1.10 11/12/92 - * Author: Roger A. Cole - * Date: 02-08-91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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: - * ----------------- - * .00 02-08-91 rac initial version - * .01 07-30-91 rac installed in SCCS - * .02 08-14-91 rac add guiNoticeName; add more documentation - * .03 09-06-91 rac add GuiCheckbox..., guiGetNameFromSeln - * .04 10-23-91 rac allow window manager to position command - * frames; add file selector routine; add - * guiInit, guiFileSelect, guiShellCmd; add - * guiTextswXxx; don't specify position for - * frames - * .05 02-25-92 rac add a text editor command frame; guiInit - * now gets host name and user name; add a - * printer command frame and print routine; - * add "puts" for text subwindows - * .06 03-15-92 rac add guiLock as a locking mechanism - * .07 03-23-92 rac add guiTimer; fix guiEditorCreate for sane behavior; - * add guiXxxPrintf routines; assume make for XVIEW; - * add guiCanvas; rearrange guiEditor panel and add - * a status message; add guiCFshow and guiCFshowPin; - * change guiCFShow so that it will expose hidden - * command frames (this requires OpenWindows Version 3); - * for guiGetNameFromSeln, require that selection be - * in caller's window; - * .08 08-26-92 rac fix a bug in guiEditorUpdateSet; - * .09 09-30-92 rac allow a bigger buffer for browser; change extension - * on edit lock file - * - */ -#if 0 /* allow embedding comments in the header below */ -/*+/mod*********************************************************************** -* TITLE guiSubr.c - general gui routines for xview -* -* DESCRIPTION -* These routines comprise an initial attempt to provide gui capabilities -* in a generic way. At present, the routines are heavily xview -* oriented. The routines will probably evolve, especially with -* regard to xview item typedef usage (e.g., Panel, Xv_opaque, etc.). -* -* For more information, see USAGE, below. -* -* QUICK REFERENCE -* #include -* -* Textsw guiBrowser(parent, panel, nCol, nLines, fileName) -* Panel_item guiButton(label, panel, <>pX, pY, <>pHt, proc, menu, -* key1, val1, key2, val2) -* void guiButtonCenter(button1, button2, panel) -* Canvas guiCanvas(parentFrame, x, y, proc, >pBgColor, >pFgColor, -* key1, val1, key2, val2) -* void guiCFdismiss_xvo(item) -* void guiCFshow(frame) -* void guiCFshowPin(frame) -* void guiCFshow_mi(menu, menuItem) -* void guiCFshow_xvo(item) -* void guiCFshowPin_mi(menu, menuItem) -* void guiCFshowPin_xvo(item) -* Panel_item guiCheckbox(label, panel, nItems, <>pX, pY, <>pHt, proc, -* key1, val1, key2, val2) -* void guiCheckboxItem(label,checkbox,itemNum,dfltFlag,<>pX,pY,<>pHt) -* Panel_item guiChoice(label, item1, item2, ..., NULL, panel, excl, nRow, nCol, -* <>pX, pY, <>pHt, proc, key1, val1, key2, val2) -* GUI_EDIT *guiEditor(pGuiCtx, title, dirName, fileName, pPrtCtx, -* addExtrasFn, addExtrasArg) -* void addExtrasFn(pGuiCtx, pEdit, panel, pX,pY,pHt, addExtrasArg) -* char *guiEditorGets(pEditor, pBuf, dim, <>pCharPos) -* void guiEditorLoadFile(pEditor, dirName, fileName) -* void guiEditorNewEntry_pb(item) -* void guiEditorPrintf(pEditor, fmt, ...) -* int guiEditorPuts(pEditor, pBuf, <>pCharPos) -* void guiEditorReset(pEditor) -* void guiEditorShowCF(pEditor) -* void guiEditorShowCF_mi(menu, menuItem) -* void guiEditorShowCF_xvo(item) -* void guiEditorStatusPrintf(pEditor, fmt, ...) -* char *guiFileSelect(pGuiCtx, title, dir, file, dim, callbackFn, pArg) -* void callbackFn(pArg, newPath, newDir, newFileName); -* Frame guiFrame(label, x, y, width, height, >ppDisp, >pServer) -* Frame guiFrameCmd(label, parentFrame, pPanel, resizeProc) -* char *guiGetNameFromSeln(pGuiCtx, textSw, headFlag, tailFlag) -* char *guiGetSelnInTextsw(pGuiCtx, textSw) -* Icon guiIconCreate(frame, iconBits) -* Panel guiInit(pGuiCtx, pArgc, argv, label, x, y, width, height) -* int guiLock(pGuiCtx, text, lockPath, flag) -* flag is 0,1 to reset/set the lock -* Menu guiMenu(proc, key1, val1, key2, val2) -* Menu_item guiMenuItem(label, menu, proc, inact, dflt, -* key1, val1, key2, val2) -* Panel_item guiMessage(label, panel, <>pX, pY, <>pHt) -* void guiMessagePrintf(Panel_item, fmt, ...) -* void guiNotice(pGuiCtx, msg) -* void guiNoticeFile(pGuiCtx, msg, fName) -* void guiNoticeName(pGuiCtx, msg, name) -* void guiNoticePrintf(pGuiCtx, fmt, ...) -* GUI_PRT *guiPrinter(pGuiCtx, parentFrame, title, useEnscript) -* void guiPrinterShowCF_mi(menu, menuItem) -* void guiPrinterShowCF_xvo(Xv_opaque) -* void guiPrintFile(pPrtCtx, path) -* void guiPrintGetCmd(pPrtCtx, path, commandBuf) -* void guiShellCmd(pGuiCtx, cmdBuf, clientNum, callbackFn, callbackArg) -* void callbackFn(callbackArg, resultBuf) -* Panel_item guiTextField(label, panel, <>pX, pY, <>pHt, proc, nStr, nDsp, -* key1, val1, key2, val2) -* void guiTextFieldPrintf(Panel_item, fmt, ...) -* char *guiTextswGets(textsw, pBuf, dim, <>pCharPos) -* void guiTextswPrintf(textsw, fmt, ...) -* int guiTextswPuts(textsw, pBuf, <>pCharPos) -* void guiTextswReset(textsw) -* void guiTimer(seconds, callbackFn, callbackArg) -* -* NOTES -* 1. Many guiXxx routines have <>pX,pY,<>pHt as arguments. pX,pY specifies -* the desired position, in pixels, of the item within the panel. pX -* is modified to be a suitable x position for an item following on -* the same line. pHt is modified to be the height, in pixels, of the -* item, if its height exceeds the present value of pHt. -* -* BUGS -* o although they provide some isolation, these routines are still heavily -* XView specific -* o there is no "signal handler" routine to allow trapping a window -* manager forced exit -* -* USAGE -* In the synopsis for each routine, the `pGuiCtx' is intended to be -* &guiContext, (or whatever name is chosen for the GUI_CTX in the -* program). -* -* EXAMPLE PROGRAM -* This example shows some of the features of these routines. It -* produces a program which can be used as a computerized logbook. -* In addition to an editor and a "directory lister", the program -* has a button which starts a new logbook entry with time, date, -* and user name. -* -* This example assumes that the icon editor has been used to make -* an icon for the program. -* -* #include -* #include -* #include -* #include -* #include -* #include -* -* /*-------------------------------------------------------------------------- -* * This is a "context" structure for the program. It is used to -* * organize information about the gui operations. -* *-------------------------------------------------------------------------*/ -* typedef struct { -* GUI_CTX guiCtx; /* context block for the gui routines */ -* GUI_EDIT *pEditor; /* context block for the guiEditor */ -* GUI_PRT *pPrt; /* context block for the guiPrinter */ -* } TEST_CTX; -* -* /*-------------------------------------------------------------------------- -* * Some identifiers for XV_KEY_DATA arguments are usually needed. -* * The "user" identifiers can start at values of 100 and above. -* *-------------------------------------------------------------------------*/ -* typedef enum { -* PCTX=100, /* TEST context */ -* PCMD, /* TEST shell command string */ -* } TEST_XV_KEY_DATA; -* -* void edit_pb(); -* void quit_pb(); -* void extra(); -* -* /*-------------------------------------------------------------------------- -* * The main program -* *-------------------------------------------------------------------------*/ -* main(argc, argv) -* int argc; -* char *argv[]; -* { -* TEST_CTX testCtx; -* static short icon_bits[]={ -* #include "guiTest.icon" /* this file was created with the icon editor */ -* }; -* Panel panel; -* int y=5, x=5, ht=0; -* -* panel = guiInit(&testCtx.guiCtx, -* &argc, argv, "gui test program", 100, 100, 0,0); -* guiIconCreate(testCtx.guiCtx.baseFrame, icon_bits); -* -* testCtx.pEditor = NULL; -* testCtx.pPrt = guiPrinter(&testCtx.guiCtx, -* testCtx.guiCtx.baseFrame, "test: printer setup", 1); -* -* guiButton("Edit", panel, &x,&y,&ht, edit_pb, NULL, PCTX,&testCtx,0,NULL); -* guiButton("Quit", panel, &x,&y,&ht, quit_pb, NULL, PCTX,&testCtx,0,NULL); -* -* window_fit(panel); -* window_fit(testCtx.guiCtx.baseFrame); -* xv_main_loop(testCtx.guiCtx.baseFrame); -* printf("exiting\n"); -* return 0; -* } -* -* /*-------------------------------------------------------------------------- -* * subroutine to handle the "Edit" button. This routine asks guiEditor -* * to call the extra() function below to add a "New entry" button to -* * the editor panel. -* * -* * Common practice is to use suffixes on subroutine names when they -* * are called as a result of activating various gui items. This allows -* * signifying what sort of arguments are needed. -* * _pb indicates a routine called from a panel button -* * void subr_pb(item) -* * Panel_item item; -* * { -* * program statements -* * } -* * _mi indicates a routine called from a menu item -* * void subr_mi(menu, item) -* * Menu menu; -* * Menu_item item; -* * { -* * program statements -* * } -* * _xvo indicates a generic "one argument" callback routine -* * void subr_xvo(item) -* * Xv_opaque item; -* * { -* * program statements -* * } -* *-------------------------------------------------------------------------*/ -* static void edit_pb(item) -* Panel_item item; -* { TEST_CTX *pCtx=(TEST_CTX *)xv_get(item, XV_KEY_DATA, PCTX); -* if (pCtx->pEditor == NULL) { -* pCtx->pEditor = guiEditor(&pCtx->guiCtx, "test", -* pCtx->guiCtx.pwd, NULL, pCtx->pPrt, extra, pCtx); -* } -* -* guiEditorShowCF(pCtx->pEditor); -* } -* -* void extra(pGuiCtx, pEditor, panel, pX,pY,pHt, pCtx) -* GUI_CTX *pGuiCtx; -* GUI_EDIT *pEditor; -* Panel panel; -* int *pX,*pY,*pHt; -* TEST_CTX *pCtx; -* { -* *pX = 5; *pY += *pHt + 10; *pHt = 0; -* guiButton("New entry", panel, pX,pY,pHt, guiEditorNewEntry_pb, NULL, -* GUI_PCTX, pGuiCtx, GUI_PEDIT, pEditor); -* } -* -* /*-------------------------------------------------------------------------- -* * subroutine to handle the "Quit" button. This is where various -* * cleanup activities would normally occur. -* *-------------------------------------------------------------------------*/ -* static void quit_pb(item) -* Panel_item item; -* { TEST_CTX *pCtx=(TEST_CTX *)xv_get(item, XV_KEY_DATA, PCTX); -* -* xv_destroy_safe(pCtx->guiCtx.baseFrame); -* } -* -*-***************************************************************************/ -#endif - -#include -#include -#include -#include -#include -#include /* for use with notifier */ -#include -#include /* for use with notifier */ -#include /* for use with notifier */ - -#define XVIEW -#if defined XVIEW -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include /* for */ -#endif - -#include -#include - -void guiShellCmd_work(); -Notify_value guiCmdRead(), guiCmdSigchld(); - -static int callbackNum=-1; -struct callbackStruct { - Notify_client clientNum; - void (*callbackFn)(); - void *callbackArg; - char result[GUI_TDIM]; - int readDone; - int sigChldDone; - int pipe_io; -}; -static struct callbackStruct callback[100]; - -#if GUI_TEST -typedef struct { - GUI_CTX guiCtx; - GUI_EDIT *pEditor; - GUI_PRT *pPrt; -} TEST_CTX; - -typedef enum { - PCTX=100, /* TEST context */ - PCMD, /* TEST shell command string */ -} TEST_XV_KEY_DATA; - -void edit_pb(); -void quit_pb(); -void extra(); -void testTime(); - -/*+/subr********************************************************************** -* NAME main - test program -* -*-*/ -main(argc, argv) -int argc; -char *argv[]; -{ - TEST_CTX testCtx; - static short icon_bits[]={ -#include "guiTest.icon" - }; - Panel panel; - Panel_item choice; - int y=5, x=5, ht=0; - int x1; - - panel = guiInit(&testCtx.guiCtx, - &argc, argv, "gui test program", 100, 100, 0,0); - guiIconCreate(testCtx.guiCtx.baseFrame, icon_bits); - - testCtx.pEditor = NULL; - testCtx.pPrt = guiPrinter(&testCtx.guiCtx, - testCtx.guiCtx.baseFrame, "test: printer setup", 1); - - guiButton("Edit", panel, &x,&y,&ht, edit_pb, NULL, PCTX,&testCtx,0,NULL); - guiButton("Quit", panel, &x,&y,&ht, quit_pb, NULL, PCTX,&testCtx,0,NULL); - y += 5 + ht; x = 5; ht = 0; - choice = guiChoice("exclusive ", - "abc", "def", "ghi", "jkl", "mno", NULL, - panel, 1, 0, 2, &x,&y,&ht, NULL, 0,NULL,0,NULL); - y += 5 + ht; x = 5; ht = 0; - choice = guiChoice("non-exclusive", - "abc", "def", "ghi", "jkl", "mno", NULL, - panel, 0, 2, 0, &x,&y,&ht, NULL, 0,NULL,0,NULL); - y += 5 + ht; x = 5; ht = 0; - guiMessage("exclusive", panel, &x,&y,&ht); - x1 = 150; - choice = guiChoice("", - "abc", "def", "ghi", "jkl", "mno", NULL, - panel, 1, 0, 2, &x1,&y,&ht, NULL, 0,NULL,0,NULL); - y += 5 + ht; x = 5; ht = 0; - guiMessage("non-exclusive", panel, &x,&y,&ht); - x1 = 150; - choice = guiChoice("", - "abc", "def", "ghi", "jkl", "mno", NULL, - panel, 0, 2, 0, &x1,&y,&ht, NULL, 0,NULL,0,NULL); - - window_fit(panel); - window_fit(testCtx.guiCtx.baseFrame); - guiTimer(10., testTime, &testCtx); - xv_main_loop(testCtx.guiCtx.baseFrame); - printf("exiting\n"); - return 0; -} -static void edit_pb(item) -Panel_item item; -{ TEST_CTX *pCtx=(TEST_CTX *)xv_get(item, XV_KEY_DATA, PCTX); - if (pCtx->pEditor == NULL) { - pCtx->pEditor = guiEditor(&pCtx->guiCtx, - "test", pCtx->guiCtx.pwd, "test", pCtx->pPrt, extra, pCtx); - } - - guiEditorShowCF(pCtx->pEditor); -} - -void extra(pGuiCtx, pEditor, panel, pX,pY,pHt, pCtx) -GUI_CTX *pGuiCtx; -GUI_EDIT *pEditor; -Panel panel; -int *pX,*pY,*pHt; -TEST_CTX *pCtx; -{ - *pX = 5; *pY += *pHt + 10; *pHt = 0; - guiButton("New entry", panel, pX,pY,pHt, guiEditorNewEntry_pb, NULL, - GUI_PCTX, pGuiCtx, GUI_PEDIT, pEditor); -} -static void quit_pb(item) -Panel_item item; -{ TEST_CTX *pCtx=(TEST_CTX *)xv_get(item, XV_KEY_DATA, PCTX); - - xv_destroy_safe(pCtx->guiCtx.baseFrame); -} - -void testTime(pCtx, dummy) -TEST_CTX *pCtx; -int dummy; -{ - printf("timer %x\n", pCtx); -} -#endif - -/*+/internal****************************************************************** -* NAME guiAbove - move a frame "above" in the stacking order -* -* BUGS -* o this doesn't work under OpenWindows version 2; under version 3, -* the function can actually be invoked. -* -*-*/ -guiAbove(frame) -Frame frame; -{ -#if 0 - XWindowChanges chg; - Display *pDisp=(Display *)xv_get(frame, XV_DISPLAY); - Window win=(Window)xv_get(frame, XV_XID); - - chg.stack_mode = TopIf; - XConfigureWindow(pDisp, win, CWStackMode, &chg); -#if 0 - XRaiseWindow(pDisp, win); -#endif -#endif - if ((int)xv_get(frame, XV_SHOW) == 0) - xv_set(frame, XV_SHOW, TRUE, NULL); -} - - - -/*+/subr********************************************************************** -* NAME guiBrowser - create a browsing text subwindow -* -* DESCRIPTION -* -* RETURNS -* -* -*-*/ -Textsw -guiBrowser(parentFrame, panel, nCol, nLines, fileName) -Frame parentFrame; /* I parent of text subwindow */ -Panel panel; /* I panel preceding textsw */ -int nCol; /* I number of columns wide for text */ -int nLines; /* I number of lines long for text */ -char *fileName; /* I file to load, or NULL */ -{ - Textsw textsw; - - textsw = (Textsw)xv_create(parentFrame, TEXTSW, - XV_X, 0, WIN_BELOW, panel, - WIN_COLUMNS, nCol, WIN_ROWS, nLines, - TEXTSW_BROWSING, TRUE, - TEXTSW_DISABLE_CD, TRUE, - TEXTSW_DISABLE_LOAD, TRUE, - TEXTSW_MEMORY_MAXIMUM, 200000, - TEXTSW_FILE, fileName, - NULL); - if (textsw == NULL) { - (void)printf("error creating browser text subwindow\n"); - exit(1); - } - xv_set(textsw, WIN_WIDTH, WIN_EXTEND_TO_EDGE, NULL); - - return textsw; -} - -/*+/subr********************************************************************** -* NAME guiButton - create a button on a panel -* -* DESCRIPTION -* -* RETURNS -* Panel_item handle -* -*-*/ -Panel_item -guiButton(label, panel, pX, pY, pHt, proc, menu, key1, val1, key2, val2) -char *label; /* I label for button */ -Panel panel; /* I handle of panel containing button */ -int *pX; /* IO pointer to x position in panel, in pixels */ -int *pY; /* I pointer to y position in panel, in pixels */ -int *pHt; /* IO ptr to height used, in pixels, or NULL */ -void (*proc)(); /* I pointer to procedure to handle button push */ -Menu menu; /* I handle of button menu, or NULL */ -enum key1; /* I key for context information for object */ -void *val1; /* I value associated with key */ -enum key2; /* I key for context information for object */ -void *val2; /* I value associated with key */ -{ - Panel_item button; - int height; - - button = (Panel_item)xv_create(panel, PANEL_BUTTON, - PANEL_LABEL_STRING, label, XV_X, *pX, XV_Y, *pY, NULL); - if (button == NULL) { - (void)printf("error creating \"%s\" button\n", label); - exit(1); - } - if (proc != NULL) { - if (xv_set(button, PANEL_NOTIFY_PROC, proc, NULL) != XV_OK) { - (void)printf("error adding proc to \"%s\" button\n", label); - exit(1); - } - } - if (menu != NULL) { - if (xv_set(button, PANEL_ITEM_MENU, menu, NULL) != XV_OK) { - (void)printf("error adding menu to \"%s\" button\n", label); - exit(1); - } - } - if (key1 != 0) { - if (xv_set(button, XV_KEY_DATA, key1, val1, NULL) != XV_OK) { - (void)printf("error adding key1 to \"%s\" button\n", label); - exit(1); - } - } - if (key2 != 0) { - if (xv_set(button, XV_KEY_DATA, key2, val2, NULL) != XV_OK) { - (void)printf("error adding key2 to \"%s\" button\n", label); - exit(1); - } - } - *pX += (int)xv_get(button, XV_WIDTH) + 10; - if (pHt != NULL) { - height = xv_get(button, XV_HEIGHT); - if (height > *pHt) - *pHt = height; - } - - return button; -} - -/*+/subr********************************************************************** -* NAME guiButtonCenter - center one or two buttons within a panel -* -* DESCRIPTION -* -* RETURNS -* void -* -* EXAMPLE -* Panel_item button1, button2; -* -* button1 = guiButton(... -* button2 = guiButton(... -* -* window_fit(panel) -* guiButtonCenter(button1, button2, panel); -* -*-*/ -void -guiButtonCenter(button1, button2, panel) -Panel_item button1; /* I first button */ -Panel_item button2; /* I second button, or NULL */ -Panel panel; /* I panel containing button(s) */ -{ - int width1, width2, x, panelWidth, y; - panelWidth = (int)xv_get(panel, XV_WIDTH); - width1 = (int)xv_get(button1, XV_WIDTH); - y = (int)xv_get(button1, XV_Y); - if (button2 != NULL) { - width2 = (int)xv_get(button2, XV_WIDTH); - if ((x = (panelWidth - width1 - width2 - 20) / 2) > 0) { - xv_set(button1, XV_X, x, XV_Y, y, NULL); - x += width1 + 20; - xv_set(button2, XV_X, x, XV_Y, y, NULL); - } - } - else if ((x = (panelWidth - width1) / 2) > 0) - xv_set(button1, XV_X, x, XV_Y, y, NULL); -} - -/*+/subr********************************************************************** -* NAME guiCanvas - create a canvas within a frame -* -* DESCRIPTION -* -* RETURNS -* Canvas handle -* -* EXAMPLE -* Canvas canvas; -* -* canvas = guiCanvas(baseFrame, 0, 100, canvasEvent, NULL, NULL, -* 0,NULL,0,NULL); -* -* void -* canvasEvent(canvas, event) -* Canvas canvas; -* Event *event; -* { -* if (event_id(event) == WIN_REPAINT) { -* repaint activity -* } -* else if (event_id(event) == MS_LEFT && event_is_up(event)) { -* left mouse release activity -* } -* { -*-*/ -Canvas -guiCanvas(parentFrame, x, y, proc, pBgColor, pFgColor, key1, val1, key2, val2) -Frame parentFrame; /* I parent frame to contain canvas */ -int x; /* I x position in frame, in pixels */ -int y; /* I y position in frame, in pixels */ -void (*proc)(); /* I pointer to procedure to handle resize & events */ -unsigned long *pBgColor;/* O pointer to background pixel value, or NULL */ -unsigned long *pFgColor;/* O pointer to foreground pixel value, or NULL */ -enum key1; /* I key for context information for canvas */ -void *val1; /* I value associated with key */ -enum key2; /* I key for context information for canvas */ -void *val2; /* I value associated with key */ -{ - Canvas canvas; - Xv_window paintWin; - unsigned long *colors; - - canvas = (Canvas)xv_create(parentFrame, CANVAS, - XV_X, x, XV_Y, y, - CANVAS_X_PAINT_WINDOW, TRUE, - CANVAS_FIXED_IMAGE, FALSE, - WIN_RETAINED, FALSE, - CANVAS_AUTO_CLEAR, TRUE, - CANVAS_AUTO_SHRINK, TRUE, - CANVAS_AUTO_EXPAND, TRUE, - NULL); - if (canvas == NULL) { - (void)printf("error creating canvas\n"); - exit(1); - } - paintWin = canvas_paint_window(canvas); - if (xv_set(paintWin, WIN_COLLAPSE_EXPOSURES, TRUE, - WIN_CONSUME_EVENTS, WIN_MOUSE_BUTTONS, WIN_REPAINT, NULL, - NULL) != XV_OK) { - (void)printf("error setting events for canvas\n"); - exit(1); - } - if (proc != NULL) { - if (xv_set(paintWin, WIN_EVENT_PROC, proc, NULL) != XV_OK) { - (void)printf("error adding event procedure for canvas\n"); - exit(1); - } - } - if (key1 != 0) { - if (xv_set(paintWin, XV_KEY_DATA, key1, val1, NULL) != XV_OK) { - (void)printf("error adding key1 to canvas\n"); - exit(1); - } - } - if (key2 != 0) { - if (xv_set(paintWin, XV_KEY_DATA, key2, val2, NULL) != XV_OK) { - (void)printf("error adding key2 to canvas\n"); - exit(1); - } - } - - colors = (unsigned long *)xv_get(paintWin, WIN_X_COLOR_INDICES); - if (pBgColor != NULL) - *pBgColor=colors[(unsigned long)xv_get(paintWin,WIN_BACKGROUND_COLOR)]; - if (pFgColor != NULL) - *pFgColor=colors[(unsigned long)xv_get(paintWin,WIN_FOREGROUND_COLOR)]; - return canvas; -} - -/*+/subr********************************************************************** -* NAME guiCF - command frame dismiss and show routines -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* guiFrameCmd -* -* EXAMPLES -* guiButton("Dismiss", panel, ... -* guiCFdismiss_xvo, NULL, GUI_CF, cmdFrame, 0, NULL); -* -* menu = guiMenu(..., GUI_PCTX, pGuiCtx...); -* menuItem = guiMenuItem("label", menu, guiCFshow_mi, ..., -* GUI_CF, frame...); -* -* guiButton("Show...", panel, ..., guiCFshow_xvo, ..., -* GUI_PCTX, pGuiCtx, GUI_CF, frame); -* -* menu = guiMenu(..., GUI_PCTX, pGuiCtx...); -* menuItem = guiMenuItem("label", menu, guiCFshowPin_mi, ..., -* GUI_CF, frame...); -* -* guiButton("Show...", panel, ..., guiCFshowPin_xvo, ..., -* GUI_PCTX, pGuiCtx, GUI_CF, frame); -* -*-*/ -void -guiCFdismiss_xvo(item) -Xv_opaque item; -{ Frame frame=(Frame)xv_get(item, XV_KEY_DATA, GUI_CF); - xv_set(frame, XV_SHOW, FALSE, FRAME_CMD_PUSHPIN_IN, FALSE, NULL); -} -void -guiCFshow(frame) -Frame frame; -{ - if ((int)xv_get(frame, XV_SHOW) == TRUE) - guiAbove(frame); - else - xv_set(frame, XV_SHOW, TRUE, NULL); -} -void -guiCFshowPin(frame) -Frame frame; -{ - if ((int)xv_get(frame, XV_SHOW) == TRUE) - guiAbove(frame); - else - xv_set(frame, XV_SHOW, TRUE, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); -} - -void guiCFshow_mi(menu, menuItem) Menu menu; Menu_item menuItem; -{ guiCFshow_xvo(menuItem); } - -void guiCFshow_xvo(item) -Xv_opaque item; -{ GUI_CTX *pGuiCtx=(GUI_CTX *)xv_get(item, XV_KEY_DATA, GUI_PCTX); - Frame frame=(Frame)xv_get(item, XV_KEY_DATA, GUI_CF); - guiCFshow(frame); -} - -void guiCFshowPin_mi(menu, menuItem) Menu menu; Menu_item menuItem; -{ guiCFshowPin_xvo(menuItem); } - -void guiCFshowPin_xvo(item) -Xv_opaque item; -{ GUI_CTX *pGuiCtx=(GUI_CTX *)xv_get(item, XV_KEY_DATA, GUI_PCTX); - Frame frame=(Frame)xv_get(item, XV_KEY_DATA, GUI_CF); - guiCFshowPin(frame); -} - -/*+/subr********************************************************************** -* NAME guiCheckbox - create an empty checkbox list -* -* DESCRIPTION -* Creates the framework for an empty checkbox selection list. The -* actual checkbox items must be filled in by calls to -* guiCheckboxItem. -* -* Checkbox lists have a fixed number of items--the number of items -* can't be increased or decreased after the empty list is created. -* Individual items on a list can be changed at any time, however. -* -* RETURNS -* Panel_item for the checkbox -* -* BUGS -* o list can't dynamically grow and shrink -* o the maximum size for a checkbox list is 10 items -* -* SEE ALSO -* guiCheckboxItem -* -* EXAMPLE -* Set up a 3-item checkbox. Each of the first two items is to have -* an associated status message. The appearance of the setup will -* resemble the following: -* -* Retrieve from: -* [] text file ________status message________ -* [] binary file ________status message________ -* [] Channel Access -* -* The third item will be the default. When any of the items are -* selected, choose_xvo() is to be called; that routine uses a pointer -* to a `myStruct' structure for its operations. -* -* struct myStruct { -* Panel_item textStatus; status for text file -* Panel_item binStatus; status for binary file -* } context; -*#define PCTX 101 (a unique integer for identifying myStruct) -* Panel_item ckbx; -* int x=5, y=5, ht=0; -* int x1, x2, y1, y2; (for aligning buttons and status messages) -* -* ckbx = guiCheckbox("Retrieve from:", panel, 3, &x, &y, &ht, -* choose_xvo, PCTX, &context, 0, NULL); -* y += ht + 5; x = 5; ht = 0; -* guiCheckboxItem("text file", ckbx, 0, 0, &x, &y, &ht); -* x1 = x; y1 =y; -* y += ht + 5; x = 5; ht = 0; -* guiCheckboxItem("binary file", ckbx, 1, 0, &x, &y, &ht); -* x2 = x; y2 =y; -* y += ht + 5; x = 5; ht = 0; -* guiCheckboxItem("Channel Access", ckbx, 2, 1, &x, &y, &ht); -* y += ht + 5; x = 5; ht = 0; -* if (x1 < x2) x1 = x2; (which extends further right?) -* else x2 = x1; -* context.textStatus = guiMessage("", panel, &x1, &y1, &ht); -* context.binStatus = guiMessage("", panel, &x2, &y2, &ht); -* -*-*/ -Panel_item -guiCheckbox(label, panel, nItems, pX, pY, pHt, proc, key1, val1, key2, val2) -char *label; /* I label for checkbox list */ -Panel panel; /* I handle of panel containing checkbox list */ -int nItems; /* I the number of items to be held by the list */ -int *pX; /* IO pointer to x position in panel, in pixels */ -int *pY; /* I pointer to y position in panel, in pixels */ -int *pHt; /* IO ptr to height used by label, in pixels, or NULL */ -void (*proc)(); /* I pointer to procedure to handle making a choice */ -enum key1; /* I key for context information for object */ -void *val1; /* I value associated with key */ -enum key2; /* I key for context information for object */ -void *val2; /* I value associated with key */ -{ - Panel_item checkbox; - int height; - -/*----------------------------------------------------------------------------- -* NOTE: the kludgey way this is done is because XView in SunOS 4.1 can't -* seem to handle defining the number of items except at compile time -*----------------------------------------------------------------------------*/ -#define GUI_CHK checkbox=xv_create(panel,PANEL_CHECK_BOX,PANEL_CHOICE_STRINGS, - if (nItems == 1) GUI_CHK "", NULL,NULL); - else if (nItems == 2) GUI_CHK "","", NULL,NULL); - else if (nItems == 3) GUI_CHK "","","", NULL,NULL); - else if (nItems == 4) GUI_CHK "","","","", NULL,NULL); - else if (nItems == 5) GUI_CHK "","","","","", NULL,NULL); - else if (nItems == 6) GUI_CHK "","","","","","", NULL,NULL); - else if (nItems == 7) GUI_CHK "","","","","","","", NULL,NULL); - else if (nItems == 8) GUI_CHK "","","","","","","","", NULL,NULL); - else if (nItems == 9) GUI_CHK "","","","","","","","","", NULL,NULL); - else if (nItems == 10) GUI_CHK "","","","","","","","","","", NULL,NULL); - else { - (void)printf("guiCheckbox can only handle up to 10 items\n"); - exit(1); - } - if (checkbox == NULL) { - (void)printf("error creating \"%s\"s checkbox list\n", label); - exit(1); - } - xv_set(checkbox, - PANEL_LAYOUT, PANEL_VERTICAL, - PANEL_CHOOSE_ONE, TRUE, - PANEL_CHOOSE_NONE, TRUE, - NULL); - xv_set(checkbox, PANEL_VALUE, -1, NULL); - if (proc != NULL) { - if (xv_set(checkbox, PANEL_NOTIFY_PROC, proc, NULL) != XV_OK) { - (void)printf("error adding proc to \"%s\"s checkbox list\n", label); - exit(1); - } - } - if (key1 != 0) { - if (xv_set(checkbox, XV_KEY_DATA, key1, val1, NULL) != XV_OK) { - (void)printf("error adding key1 to \"%s\" checkbox list\n", label); - exit(1); - } - } - if (key2 != 0) { - if (xv_set(checkbox, XV_KEY_DATA, key2, val2, NULL) != XV_OK) { - (void)printf("error adding key2 to \"%s\" checkbox list\n", label); - exit(1); - } - } - guiMessage(label, panel, pX, pY, pHt); - return checkbox; -} - -/*+/subr********************************************************************** -* NAME guiCheckboxItem - create an item in a checkbox list -* -* DESCRIPTION -* Change one of the items in a checkbox list. This may be either -* setting the item following the creation of the list with guiCheckbox, -* or a subsequent change to an item. -* -* RETURNS -* void -* -* SEE ALSO -* guiCheckbox -* -*-*/ -void -guiCheckboxItem(label, checkbox, itemNum, dfltFlag, pX, pY, pHt) -char *label; /* I label for item */ -Panel_item checkbox; /* I handle of checkbox list */ -int itemNum; /* I number (starting with 0) within checkbox list */ -int dfltFlag; /* I if 1, then this item will be pre-selected */ -int *pX; /* IO pointer to x position in panel, in pixels */ -int *pY; /* I pointer to y position in panel, in pixels */ -int *pHt; /* IO ptr to height used by label, in pixels, or NULL */ -{ - Panel panel=(Panel)xv_get(checkbox, PANEL_PARENT_PANEL); - - xv_set(checkbox, - PANEL_CHOICE_X, itemNum, *pX, - PANEL_CHOICE_Y, itemNum, *pY-5, - NULL); - *pX += 40; - *pHt = 20; - guiMessage(label, panel, pX, pY, pHt); - if (dfltFlag) - xv_set(checkbox, PANEL_VALUE, itemNum, NULL); -} - -#if 0 -/*+/macros******************************************************************** -* NAME guiChoice - set up a choice list -* -* SYNOPSIS -* Panel_item -* guiChoice(label, item1, item2, ..., NULL, panel, excl, nRow, nCol, -* pX,pY,pHt, proc, key1, val1, key2, val2) -* char *label; /* I label for choice list */ -* char *item1; /* I label for first choice item */ -* char *item2; /* I label for second choice item */ -* ... -* Panel panel; /* I handle of panel containing choice list */ -* int excl; /* I 1 for exclusive choice list, else 0 */ -* int nRow; /* I number of rows for organizing buttons */ -* int nCol; /* I number of columns for organizing buttons */ -* int *pX; /* IO pointer to x position in panel, in pixels */ -* int *pY; /* I pointer to y position in panel, in pixels */ -* int *pHt; /* IO ptr to height used by label, in pixels, or NULL */ -* void (*proc)();/* I pointer to procedure to handle making a choice */ -* enum key1; /* I key for context information for object */ -* void *val1; /* I value associated with key */ -* enum key2; /* I key for context information for object */ -* void *val2; /* I value associated with key */ -* -*-*/ -#endif -Panel_item -guiChoice(va_alist) -va_dcl -{ - va_list pArg; - - Panel_item item; - int height, lastItem; - char *label, *I[100]; - Panel panel; - int excl, nRow, nCol; - int *pX; - int *pY; - int *pHt; - void (*proc)(); - int key1; - void *val1; - int key2; - void *val2; - typedef void FN(); - int type, df; - - va_start(pArg); - label = va_arg(pArg, char *); - for (lastItem=0; lastItem<100; lastItem++) { - I[lastItem] = va_arg(pArg, char *); - if (I[lastItem] == NULL) - break; - } - panel = va_arg(pArg, Panel); - excl = va_arg(pArg, int); - nRow = va_arg(pArg, int); - nCol = va_arg(pArg, int); - pX = va_arg(pArg, int *); - pY = va_arg(pArg, int *); - pHt = va_arg(pArg, int *); - proc = va_arg(pArg, FN *); - key1 = va_arg(pArg, int); - val1 = va_arg(pArg, void *); - key2 = va_arg(pArg, int); - val2 = va_arg(pArg, void *); - - va_end(pArg); - - if (excl == 1) type = TRUE, df = 0; - else type = FALSE, df = 1; -#define Ps xv_create(panel,PANEL_CHOICE,PANEL_CHOOSE_ONE,type,\ - PANEL_VALUE,df,PANEL_LABEL_STRING,label,PANEL_CHOICE_STRINGS, -#define Pe , NULL, XV_X, *pX, XV_Y, *pY, NULL); break; - switch (lastItem) { - case 1: item = Ps I[0] Pe - case 2: item = Ps I[0],I[1] Pe - case 3: item = Ps I[0],I[1],I[2] Pe - case 4: item = Ps I[0],I[1],I[2],I[3] Pe - case 5: item = Ps I[0],I[1],I[2],I[3],I[4] Pe - case 6: item = Ps I[0],I[1],I[2],I[3],I[4],I[5] Pe - case 7: item = Ps I[0],I[1],I[2],I[3],I[4],I[5],I[6] Pe - case 8: item = Ps I[0],I[1],I[2],I[3],I[4],I[5],I[6],I[7] Pe - case 9: item = Ps I[0],I[1],I[2],I[3],I[4],I[5],I[6],I[7],I[8] Pe - case 10: item = Ps I[0],I[1],I[2],I[3],I[4],I[5],I[6],I[7],I[8],I[9] Pe - dflt: - printf("can't handle more than 10 choices right now\n"); - exit(1); - } - if (item == NULL) { - (void)printf("error creating choice\n"); - exit(1); - } - if (nRow > 0) - xv_set(item, PANEL_CHOICE_NROWS, nRow, NULL); - else if (nCol > 0) - xv_set(item, PANEL_CHOICE_NCOLS, nCol, NULL); - - if (proc != NULL) { - if (xv_set(item, PANEL_NOTIFY_PROC, proc, NULL) != XV_OK) { - (void)printf("error adding proc to choice\n"); - exit(1); - } - } - if (key1 != 0) { - if (xv_set(item, XV_KEY_DATA, key1, val1, NULL) != XV_OK) { - (void)printf("error adding key1 to choice\n"); - exit(1); - } - } - if (key2 != 0) { - if (xv_set(item, XV_KEY_DATA, key2, val2, NULL) != XV_OK) { - (void)printf("error adding key2 to choice\n"); - exit(1); - } - } - - *pX += (int)xv_get(item, XV_WIDTH); - if (pHt != NULL) { - height = xv_get(item, XV_HEIGHT); - if (height > *pHt) - *pHt = height; - } - return item; -} - -void guiEditorCancelFile_mi(); -void guiEditorCreateFile_mi(); -char *guiEditorGetPath(); -void guiEditorLoadFile_1(); -void guiEditorLoadFile_mi(); -void guiEditorPickFile_mi(); -void guiEditorPick_callback(); -void guiEditorPrintFile_mi(); -void guiEditorSaveFile_mi(); -void guiEditorUpdateSet(); -void guiEditorUpdateRst(); -void guiEditorUpdate_mi(); - -/*+/subr********************************************************************** -* NAME guiEditor - create a text editor command frame -* -* DESCRIPTION -* Creates a text editor command frame with amenities to support good -* editing practice: -* o allow specifying directory and file -* o support easy access to a list of directory contents -* o easy choice of file name from directory list -* o "locking" of file under edit, with corresponding notification -* to users who try to edit a locked file -* o support for caller to add items to the text editor panel -* o check for write permission before allowing editing -* -* If the caller specifies a file name, then that file will be loaded -* automatically into the text subwindow. (If the file doesn't -* exist, a notice will pop up.) -* -* If the caller specifies a function to be called to add items to -* the editor panel, the function will be called as follows: -* -* void addExtrasFn(pGuiCtx, pEdit, panel, pX,pY,pHt, addExtrasArg) -* -* RETURNS -* GUI_EDIT *, or -* NULL -* -* BUGS -* o doesn't allow printing "memory" copy of file, and insists that user -* save the file if it has been modified -* o doesn't provide a way to save updates if the program aborts -* -*-*/ -GUI_EDIT * -guiEditor(pGuiCtx, title, dir, file, pPrtCtx, addExtrasFn, arg) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -char *title; /* I text for command frame title bar */ -char *dir; /* I directory of file to load, or NULL */ -char *file; /* I file to load, or NULL */ -GUI_PRT *pPrtCtx; /* I pointer to printer context, or NULL */ -void (*addExtrasFn)();/* I pointer to function to add extra stuff to - editor panel, or NULL*/ -void *arg; /* I argument to pass to addExtrasFn */ -{ - GUI_EDIT *pEdit; - Panel panel; - Menu menu; - Textsw textsw; - Panel_item ck; - int y=5, x=5, ht=0, ht1; - -/*----------------------------------------------------------------------------- -* Dir: [<]_____________________[>] File: [<]_______________[>] -* File v Edit v status...... -* load edit -* save read-only -* list dir... discard edits -* create -* print -* printer setup... -*----------------------------------------------------------------------------*/ - - if ((pEdit=(GUI_EDIT *)malloc(sizeof(GUI_EDIT))) == NULL) - return NULL; - bzero((char *)pEdit, sizeof(*pEdit)); - pEdit->pGuiCtx = pGuiCtx; - pEdit->pPrtCtx = pPrtCtx; - pEdit->edit_CF = guiFrameCmd(title, pGuiCtx->baseFrame, &panel, NULL); - pEdit->loaded = 0; - pEdit->updFlag = 0; - strcpy(pEdit->title, title); - - pEdit->dir_PT = guiTextField("Dir:", panel, &x,&y,&ht, - NULL, GUI_TDIM-1, 40, 0, NULL, 0, NULL); - pEdit->file_PT = guiTextField("File:", panel, &x,&y,&ht, - NULL, GUI_TDIM-1, 20, 0, NULL, 0, NULL); - if (dir == NULL) - dir = pGuiCtx->pwd; - xv_set(pEdit->dir_PT, PANEL_VALUE, dir, NULL); - xv_set(pEdit->file_PT, PANEL_VALUE, file, NULL); - y += ht + 5; x = 5; ht = 0; - - menu = guiMenu(NULL, 0, NULL, 0, NULL); - guiMenuItem("Load", menu, guiEditorLoadFile_mi, 0, 1, - GUI_PCTX, pGuiCtx, GUI_PEDIT, pEdit); - guiMenuItem("Save", menu, guiEditorSaveFile_mi, 0, 0, - GUI_PCTX, pGuiCtx, GUI_PEDIT, pEdit); - guiMenuItem("List dir...", menu, guiEditorPickFile_mi, 0, 0, - GUI_PCTX, pGuiCtx, GUI_PEDIT, pEdit); - guiMenuItem("Create", menu, guiEditorCreateFile_mi, 0, 0, - GUI_PCTX, pGuiCtx, GUI_PEDIT, pEdit); - if (pPrtCtx != NULL) { - guiMenuItem("Print file", menu, guiEditorPrintFile_mi, 0, 0, - GUI_PEDIT, pEdit, GUI_PPRT, pEdit->pPrtCtx); - guiMenuItem("Printer setup...", menu, guiPrinterShowCF_mi, 0, 0, - GUI_PPRT, pEdit->pPrtCtx, 0, NULL); - } - guiButton("File", panel, &x, &y, &ht, NULL, menu, 0,NULL,0,NULL); - - menu = guiMenu(NULL, 0, NULL, 0, NULL); - guiMenuItem("set edit mode", menu, guiEditorUpdate_mi, 0, 1, - GUI_PEDIT, pEdit, GUI_INT, 1); - guiMenuItem("set read-only mode", menu, guiEditorUpdate_mi, 0, 0, - GUI_PEDIT, pEdit, GUI_INT, 0); - guiMenuItem("discard edits", menu, guiEditorCancelFile_mi, 0, 0, - GUI_PCTX, pGuiCtx, GUI_PEDIT, pEdit); - guiButton("Edit", panel, &x, &y, &ht, NULL, menu, 0,NULL,0,NULL); - pEdit->status_PM = guiMessage("", panel, &x, &y, &ht); - y += ht + 5; x = 5; ht = 0; - - if (addExtrasFn != NULL) - addExtrasFn(pGuiCtx, pEdit, panel, &x,&y,&ht, arg); - - y += ht + 5; x = 5; ht = 0; - - window_fit(panel); - xv_set(panel, WIN_WIDTH, WIN_EXTEND_TO_EDGE, NULL); - pEdit->text_TSW = (Textsw)xv_create(pEdit->edit_CF, TEXTSW, - XV_X, 0, WIN_BELOW, panel, - WIN_COLUMNS, 80, WIN_ROWS, 40, - TEXTSW_BROWSING, TRUE, - TEXTSW_DISABLE_CD, TRUE, - TEXTSW_DISABLE_LOAD, TRUE, - NULL); - if (pEdit->text_TSW == NULL) { - (void)printf("error creating editor text subwindow\n"); - exit(1); - } - - guiEditorGetPath(pEdit, 0); - xv_set(pEdit->text_TSW, WIN_WIDTH, WIN_EXTEND_TO_EDGE, NULL); - window_fit(pEdit->edit_CF); - if (file != NULL && file[0] != '\0') - guiEditorLoadFile_1(pEdit); - return pEdit; -} - -/*+/internal****************************************************************** -* NAME guiEditorCancelFile_mi -* -*-*/ -static void -guiEditorCancelFile_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - - if (pEdit->loaded == 0) - return; - textsw_reset(pEdit->text_TSW, 0, 0); - guiEditorUpdateRst(pEdit); - guiEditorLoadFile_1(pEdit); - guiMessagePrintf(pEdit->status_PM, "updates discarded; read-only mode"); -} - -/*+/internal****************************************************************** -* NAME guiEditorCreateFile_mi -* -*-*/ -static void -guiEditorCreateFile_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - FILE *pFile; - int fd; - char path[GUI_TDIM*3]; - int upd=pEdit->updFlag; - - path[0] = '\0'; - textsw_append_file_name(pEdit->text_TSW, path); - -#if 0 - if (pEdit->loaded) - guiEditorUpdateRst(pEdit); - if (pEdit->updFlag) - goto createFail; -#endif - if (guiEditorGetPath(pEdit, 1) == NULL) - goto createFail; - if ((pFile = fopen(pEdit->path, "r")) != NULL) { - fclose(pFile); - guiNoticeFile(pEdit->pGuiCtx, "file already exists:", pEdit->path); - goto createFail; - } - if ((fd = open(pEdit->path, O_WRONLY|O_CREAT, 0664)) < 0) { - guiNoticeFile(pEdit->pGuiCtx, "couldn't create file:", pEdit->path); - goto createFail; - } - close(fd); - if (pEdit->updFlag == 1) { - pEdit->updFlag = 0; - guiLock(pEdit->pGuiCtx, pEdit->file, pEdit->lockFile, 0); - } - if (pEdit->loaded) - textsw_store_file(pEdit->text_TSW, pEdit->path, 0, 0); - guiEditorLoadFile_1(pEdit); - guiEditorUpdateSet(pEdit); - if (upd) { - guiMessagePrintf(pEdit->status_PM, "%s created from %s; edit mode", - pEdit->file, path); - } - else - guiMessagePrintf(pEdit->status_PM,"%s created; edit mode",pEdit->file); - return; -createFail: - guiMessagePrintf(pEdit->status_PM, "create failed"); -} - -/*+/internal****************************************************************** -* NAME guiEditorGetPath -* -*-*/ -static char * -guiEditorGetPath(pEdit, notice) -GUI_EDIT *pEdit; -int notice; /* 1 if want you want a notice issued on problems */ -{ - char *name, *dir; - - dir = (char *)xv_get(pEdit->dir_PT, PANEL_VALUE); - name = (char *)xv_get(pEdit->file_PT, PANEL_VALUE); - strcpy(pEdit->file, name); - strcpy(pEdit->dir, dir); - if (name[0] == '\0') { - if (notice) - guiNotice(pEdit->pGuiCtx, "no file name specified"); - return NULL; - } - strcpy(pEdit->path, dir); - if (strlen(pEdit->path) > 0) - strcat(pEdit->path, "/"); - strcat(pEdit->path, name); - return pEdit->path; -} - - -/*+/subr********************************************************************** -* NAME guiEditorGets - get the next '\n' terminated string from editor -* -* DESCRIPTION -* Reads the next string from the editor text subwindow into the caller's -* buffer. Reading stops when a newline is encountered or when the -* caller's buffer is full; the newline IS stored in the buffer. -* The string in the buffer is always null terminated. -* -* The caller must supply the character index (starting with 0) of -* the position in the textsw where reading is to start. On return, -* the caller's index is set to the next available character for -* reading. -* -* RETURNS -* pointer to string, or -* NULL if there are no more characters in text subwindow -* -*-*/ -char * -guiEditorGets(pEdit, pBuf, dim, pCharPos) -GUI_EDIT *pEdit; /* I pointer to guiEditor */ -char *pBuf; /* I pointer to buffer to receive string */ -int dim; /* I dimension of buffer */ -int *pCharPos; /* IO index of character to start reading */ -{ - Textsw textsw=pEdit->text_TSW; - Textsw_index nextPos; - int i; - char *pStr; - - if (pEdit->loaded == 0) { - guiNotice(pEdit->pGuiCtx, "no file loaded"); - return NULL; - } - nextPos = (Textsw_index)xv_get(textsw, TEXTSW_CONTENTS, *pCharPos, - pBuf, dim-1); - if (nextPos == *pCharPos) - return NULL; - for (i=0; i= nextPos) { - pBuf[i] = '\0'; - return pBuf; - } - (*pCharPos)++; - if (pBuf[i] == '\n') { - pBuf[i+1] = '\0'; - return pBuf; - } - } - pBuf[i] = '\0'; - return pBuf; -} - -/*+/internal****************************************************************** -* NAME guiEditorLoadFile_mi -* -*-*/ -static void -guiEditorLoadFile_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - guiEditorLoadFile_1(pEdit); -} -/*+/subr********************************************************************** -* NAME guiEditorLoadFile - load a file for editing -* -* DESCRIPTION -* Loads the specified file into the editor window. If the editor -* window already holds a file which has been edited, a notice pops -* up and the load of the new file is not performed. -* -*-*/ -void -guiEditorLoadFile(pEdit, dir, file) -GUI_EDIT *pEdit; /* I pointer to guiEditor */ -char *dir; /* I directory */ -char *file; /* I file name */ -{ - guiEditorShowCF(pEdit); - guiEditorUpdateRst(pEdit); - if (pEdit->updFlag == 1) { - guiMessagePrintf(pEdit->status_PM, "%s not loaded", file); - return; - } - xv_set(pEdit->dir_PT, PANEL_VALUE, dir, NULL); - xv_set(pEdit->file_PT, PANEL_VALUE, file, NULL); - guiEditorLoadFile_1(pEdit); -} -/*+/internal****************************************************************** -* NAME guiEditorLoadFile_1 -* -*-*/ -static void -guiEditorLoadFile_1(pEdit) -GUI_EDIT *pEdit; -{ - Textsw_status status; - - if ((int)xv_get(pEdit->text_TSW, TEXTSW_MODIFIED)) { - guiNotice(pEdit->pGuiCtx, - "text has been modified; use \"Save\" or \"discard edits\""); - goto loadFailed; - } - if (guiEditorGetPath(pEdit, 1) == NULL) - goto loadFailed; - if (pEdit->updFlag) { - guiEditorUpdateRst(pEdit); - pEdit->updFlag = 0; - } - xv_set(pEdit->text_TSW, TEXTSW_STATUS, &status, - TEXTSW_FILE, pEdit->path, NULL); - if (status == TEXTSW_STATUS_OKAY) { - guiEditorUpdateRst(pEdit); - pEdit->loaded = 1; - } - else { - guiNoticeFile(pEdit->pGuiCtx, "couldn't open file", pEdit->path); - pEdit->loaded = 0; - goto loadFailed; - } - guiMessagePrintf(pEdit->status_PM, - "%s loaded; read-only mode set", pEdit->file); - return; -loadFailed: - guiMessagePrintf(pEdit->status_PM, "load failed"); -} - -/*+/subr********************************************************************** -* NAME guiEditorNewEntry_pb -* -* DESCRIPTION -* -* RETURNS -* void -* -* void addExtrasFn(pGuiCtx, panel, pX,pY,pHt, addExtrasArg) -* -* EXAMPLE -* Add an extra button to a text editor to allow adding a new entry -* (as for a "log book") to a file. The new entry will have the form: -* -* == Mar 06, 1992 07:27:31 userName == -* -* -* TEST_CTX *pCtx; -* GUI_CTX *pGui; -* GUI_EDIT *pEdit; -* void extra(); -* -* pEdit = guiEditor(pGui, ".", NULL, NULL, extra, pCtx); -* -* -* -* void extra(pGuiCtx, pEditor, panel, pX,pY,pHt, pCtx) -* GUI_CTX *pGuiCtx; -* GUI_EDIT *pEditor; -* Panel panel; -* int *pX,*pY,*pHt; -* TEST_CTX *pCtx; -* { -* *pX = 5; *pY += *pHt + 10; *pHt = 0; -* guiButton("New entry", panel, pX,pY,pHt, guiEditorNewEntry_pb, NULL, -* GUI_PCTX, pGuiCtx, GUI_PEDIT, pEditor); -* } -*-*/ -void -guiEditorNewEntry_pb(item) -Panel_item item; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - Textsw tsw=pEdit->text_TSW; - TS_STAMP nowTs; - char now[32]; - int i; - - if (!pEdit->loaded) { - guiNotice(pEdit->pGuiCtx, "no file has been loaded"); - return; - } - if (pEdit->updFlag == 0) { - guiNotice(pEdit->pGuiCtx, "edit mode must be set"); - return; - } - xv_set(tsw, TEXTSW_INSERTION_POINT, TEXTSW_INFINITY, NULL); - textsw_possibly_normalize(tsw, - (Textsw_index)xv_get(tsw, TEXTSW_INSERTION_POINT)); - tsLocalTime(&nowTs); - tsStampToText(&nowTs, TS_TEXT_MONDDYYYY, now); - now[21] = '\0'; /* don't print fractions of sec */ - guiEditorPrintf(pEdit, "\n== %s %s ==\n", now, pEdit->pGuiCtx->user); -} - -/*+/internal****************************************************************** -* NAME guiEditorPickFile_mi -* -*-*/ -static void -guiEditorPickFile_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_CTX *pGuiCtx=(GUI_CTX *)xv_get(item, XV_KEY_DATA, GUI_PCTX); - GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - char title[GUI_TDIM*2]; - - sprintf(title, "%s: %s", pEdit->title, "List dir"); - guiEditorGetPath(pEdit, 0); - guiFileSelect(pGuiCtx, title, pEdit->dir, pEdit->file, - GUI_TDIM, guiEditorPick_callback, pEdit); -} - -/*+/internal****************************************************************** -* NAME guiEditorPick_callback -* -*-*/ -static void -guiEditorPick_callback(pEdit, newPath, newDir, newFileName) -GUI_EDIT *pEdit; -char *newPath; -char *newDir; -char *newFileName; -{ - xv_set(pEdit->dir_PT, PANEL_VALUE, newDir, NULL); - xv_set(pEdit->file_PT, PANEL_VALUE, newFileName, NULL); - guiEditorLoadFile_1(pEdit); - guiMessagePrintf(pEdit->status_PM, - "%s loaded; read-only mode set", newFileName); -} - -/*+/internal****************************************************************** -* NAME guiEditorPrintFile_mi -* -*-*/ -static void -guiEditorPrintFile_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - - if (!pEdit->loaded) { - guiNotice(pEdit->pGuiCtx, "no file has been loaded"); - goto printFailed; - } - if ((int)xv_get(pEdit->text_TSW, TEXTSW_MODIFIED)) { - guiNotice(pEdit->pGuiCtx, "file is modified; save before printing"); - goto printFailed; - } - guiPrintFile(pEdit->pPrtCtx, pEdit->path); - guiMessagePrintf(pEdit->status_PM, "printout sent to %s", - (char *)xv_get(pEdit->pPrtCtx->printer_PT, PANEL_VALUE)); - return; -printFailed: - guiMessagePrintf(pEdit->status_PM, "print failed"); -} - -#if 0 -/*+/macros******************************************************************** -* NAME guiEditorPrintf - do a printf to a guiEditor -* -* SYNOPSIS -* void -* guiEditorPrintf(pEdit, fmt, ...) -* GUI_EDIT *pEdit;/* I pointer to guiEditor */ -* char *fmt; /* I printf format string */ -* ... /* I other arguments, for printing */ -* -*-*/ -#endif -void guiEditorPrintf(va_alist) -va_dcl -{ - va_list pArgs; - GUI_EDIT *pEdit; - Textsw textsw; - char *fmt; - char message[500]; - int n, L; - - va_start(pArgs); - pEdit = va_arg(pArgs, GUI_EDIT *); - if (pEdit->loaded == 0) { - guiNotice(pEdit->pGuiCtx, "no file loaded"); - return; - } - textsw = pEdit->text_TSW; - fmt = va_arg(pArgs, char *); - vsprintf(message, fmt, pArgs); - va_end(pArgs); - L = strlen(message); - n = textsw_insert(textsw, message, L); - if (n != L) - return; - n = (int)xv_get(textsw, TEXTSW_INSERTION_POINT); - textsw_possibly_normalize(textsw, n); -} - -/*+/subr********************************************************************** -* NAME guiEditorPuts - write string to guiEditor -* -* DESCRIPTION -* Writes the string to the text subwindow of a guiEditor. -* -* The caller must supply the character index (starting with 0) of -* the position in the textsw where writing is to start. On return, -* the caller's index is set to the next available character for -* writing. -* -* RETURNS -* 0, or -* EOF if an error occurs during the write -* -*-*/ -int -guiEditorPuts(pEdit, pBuf, pCharPos) -GUI_EDIT *pEdit; /* I pointer to guiEditor */ -char *pBuf; /* I pointer to buffer to write to text subwindow */ -int *pCharPos; /* IO index of character position to start writing */ -{ - Textsw textsw=pEdit->text_TSW; - Textsw_index n; - int L=strlen(pBuf); - - if (pEdit->loaded == 0) { - guiNotice(pEdit->pGuiCtx, "no file loaded"); - return EOF; - } - xv_set(textsw, TEXTSW_INSERTION_POINT, *pCharPos, NULL); - n = textsw_insert(textsw, pBuf, L); - if (n != L) - return EOF; - *pCharPos = (int)xv_get(textsw, TEXTSW_INSERTION_POINT); - textsw_possibly_normalize(textsw, *pCharPos); - return 0; -} - -/*+/subr********************************************************************** -* NAME guiEditorReset - reset an editor text subwindow, discarding contents -* -* DESCRIPTION -* -* RETURNS -* void -* -*-*/ -void -guiEditorReset(pEdit) -GUI_EDIT *pEdit; /* I pointer to guiEditor */ -{ - Textsw textsw=pEdit->text_TSW; - - if (pEdit->loaded == 0) - return; - textsw_reset(textsw, 0, 0); - guiEditorUpdateRst(pEdit); -} - -/*+/internal****************************************************************** -* NAME guiEditorSaveFile_mi -* -*-*/ -static void -guiEditorSaveFile_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - unsigned stat; - - if (!pEdit->loaded) { - guiNotice(pEdit->pGuiCtx, "no file has been loaded"); - return; - } - if ((int)xv_get(pEdit->text_TSW, TEXTSW_MODIFIED)) { - if (guiEditorGetPath(pEdit, 1) != NULL) { - stat = textsw_store_file(pEdit->text_TSW, pEdit->path, 0, 0); - if (stat != 0) { - guiNoticeFile(pEdit->pGuiCtx,"unable to save in:",pEdit->path); - guiMessagePrintf(pEdit->status_PM, "save failed"); - return; - } - } - } - guiEditorUpdateRst(pEdit); - guiMessagePrintf(pEdit->status_PM, "saved in %s", pEdit->file); -} - -#if 0 -/*+/macros******************************************************************** -* NAME guiEditorShowCF - show the command frame containing the editor -* -* DESCRIPTION -* Make an editor command frame visible. There are several versions -* of this routine available, to accomodate the different methods of -* calling it: -* -* void guiEditorShowCF(pEdit) call directly -* GUI_EDIT *pEdit; /* I pointer to editor context */ -* -* void guiEditorShowCF_mi(menu, item) call from a menu item -* Menu menu; /* I menu handle */ -* Menu_item item; /* I menu item handle--must have -* XV_KEY_DATA of GUI_PEDIT, pEdit */ -* -* void guiEditorShowCF_xvo(item) call from a button item -* Xv_opaque item; /* I item handle--must have -* XV_KEY_DATA of GUI_PEDIT, pEdit */ -*-*/ -#endif -void -guiEditorShowCF(pEdit) -GUI_EDIT *pEdit; /* I pointer to editor context */ -{ - if ((int)xv_get(pEdit->edit_CF, XV_SHOW) == TRUE) - guiAbove(pEdit->edit_CF); - else - xv_set(pEdit->edit_CF, XV_SHOW, TRUE, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); -} -void -guiEditorShowCF_mi(menu, menuItem) -Menu menu; -Menu_item menuItem; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(menuItem, XV_KEY_DATA, GUI_PEDIT); - guiEditorShowCF(pEdit); -} -void -guiEditorShowCF_xvo(item) -Xv_opaque item; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - guiEditorShowCF(pEdit); -} - -#if 0 -/*+/macro********************************************************************* -* NAME guiEditorStatusPrintf - do a printf to the guiEditor status line -* -* SYNOPSIS -* void -* guiEditorStatusPrintf(pEdit, fmt, ...) -* GUI_EDIT *pEdit;/* I pointer to guiEditor */ -* char *fmt; /* I printf format string */ -* ... /* I other arguments, for printing */ -* -*-*/ -#endif -void guiEditorStatusPrintf(va_alist) -va_dcl -{ - GUI_EDIT *pEdit; - va_list pArgs; - Xv_opaque item; - char *fmt; - char message[500]; - - va_start(pArgs); - pEdit = va_arg(pArgs, GUI_EDIT *); - fmt = va_arg(pArgs, char *); - vsprintf(message, fmt, pArgs); - va_end(pArgs); - xv_set(pEdit->status_PM, PANEL_LABEL_STRING, message, NULL); -} - -/*+/internal****************************************************************** -* NAME guiEditorUpdate_mi -* -*-*/ -void guiEditorUpdate_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_EDIT *pEdit=(GUI_EDIT *)xv_get(item, XV_KEY_DATA, GUI_PEDIT); - int value=(int)xv_get(item, XV_KEY_DATA, GUI_INT); - if (value == 0) - guiEditorUpdateRst(pEdit); - else - guiEditorUpdateSet(pEdit); -} - -/*+/internal****************************************************************** -* NAME guiEditorUpdateRst -* -*-*/ -void guiEditorUpdateRst(pEdit) -GUI_EDIT *pEdit; -{ - if ((int)xv_get(pEdit->text_TSW, TEXTSW_MODIFIED)) - guiNotice(pEdit->pGuiCtx, - "text has been modified; use \"Save\" or \"discard edits\""); - else { - xv_set(pEdit->text_TSW, TEXTSW_BROWSING, TRUE, NULL); - if (pEdit->updFlag == 1) { - pEdit->updFlag = 0; - guiLock(pEdit->pGuiCtx, pEdit->file, pEdit->lockFile, 0); - } - } - if (pEdit->updFlag == 1) - guiMessagePrintf(pEdit->status_PM, "edit mode"); - else - guiMessagePrintf(pEdit->status_PM, "read-only mode"); -} - -/*+/internal****************************************************************** -* NAME guiEditorUpdateSet -* -*-*/ -void static -guiEditorUpdateSet(pEdit) -GUI_EDIT *pEdit; -{ - Textsw tsw=pEdit->text_TSW; - int top; - char lockFile[2*GUI_TDIM + 5]; - FILE *pFile; - - if (pEdit->updFlag == 1) { - guiEditorUpdateRst(pEdit); - goto updateDone; - } - if (!pEdit->loaded) { - guiNotice(pEdit->pGuiCtx, "no file has been loaded"); - guiEditorUpdateRst(pEdit); - return; - } - - if ((pFile = fopen(pEdit->path, "r+")) == NULL) { - guiNoticeFile(pEdit->pGuiCtx, "file isn't writeable:", pEdit->file); - guiEditorUpdateRst(pEdit); - goto updateDone; - } - fclose(pFile); - - top = (int)xv_get(tsw, TEXTSW_FIRST_LINE); - top += 2; - strcpy(lockFile, pEdit->path); - strcat(lockFile, ".editLock"); - if (guiLock(pEdit->pGuiCtx, pEdit->file, lockFile, 1) != 1) { - guiEditorUpdateRst(pEdit); /* lock attempt didn't succeed */ - goto updateDone; - } - xv_set(tsw, TEXTSW_FIRST_LINE, top, NULL); - xv_set(tsw, TEXTSW_BROWSING, FALSE, NULL); - pEdit->updFlag = 1; - strcpy(pEdit->lockFile, lockFile); -updateDone: - if (pEdit->updFlag == 1) - guiMessagePrintf(pEdit->status_PM, "edit mode"); - else - guiMessagePrintf(pEdit->status_PM, "read-only mode"); -} - - -void guiFileSelCom_mi(); -void guiFileSelLs_mi(); -void guiFileSelLsDone(); - -/*+/subr********************************************************************** -* NAME guiFileSelect - select a file from a group -* -* DESCRIPTION -* Present a list of files in a directory and allow the user to -* choose one of them. Support is given for changing directory. -* -* Only one file select command frame can be active at a given time-- -* each call to this routine will result in wrapping up any -* previous call to it. -* -* The callback routine will be called if the user requests a change -* in file path. The callback routine is called with 4 arguments: -* -* callback(pArg, newPath, newDir, newFileName); -* -* BUGS -* o doesn't support wildcard lists (e.g., ls *.c) -* -*-*/ -void -guiFileSelect(pGuiCtx, title, dir, file, dim, callback, pArg) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -char *title; /* I title for command frame title bar */ -char *dir; /* I directory */ -char *file; /* I file name */ -int dim; /* I dimension of the dir & file arrays */ -void (*callback)(); /* I routine to call if user changes file/dir */ -void *pArg; /* I argument to pass to callback routine */ -{ - Frame frame; - Panel panel; - Menu menu; - int x=5, y=5, ht=0; - char message[GUI_TDIM*3]; - - pGuiCtx->fsCallFn = callback; - pGuiCtx->fsCallArg = pArg; - - if (pGuiCtx->fsFrame != NULL) { - frame = pGuiCtx->fsFrame; - xv_set(frame, FRAME_LABEL, title, NULL); - } - else { - frame = guiFrameCmd(title, pGuiCtx->baseFrame, &panel, NULL); - xv_set(frame, XV_KEY_DATA, GUI_PCTX, pGuiCtx, NULL); - pGuiCtx->fsFrame = frame; - pGuiCtx->fsDir_PT = guiTextField("Dir:", panel, &x,&y,&ht, - NULL, dim-1, 40, 0, NULL, 0, NULL); - pGuiCtx->fsFile_PT = guiTextField("File:", panel, &x,&y,&ht, - NULL, dim-1, 20, 0, NULL, 0, NULL); - y += ht + 10; x = 5; ht = 0; - - menu = guiMenu(NULL, 0, NULL, 0, NULL); - guiMenuItem("Load", menu, guiFileSelCom_mi, 0, 1, - GUI_PCTX, pGuiCtx, 0, NULL); - guiMenuItem("List dir...", menu, guiFileSelLs_mi, 0, 0, - GUI_PCTX, pGuiCtx, 0, NULL); - guiButton("File", panel, &x, &y, &ht, NULL, menu, 0,NULL,0,NULL); - - pGuiCtx->fsStatus_PM = guiMessage(" ", panel, &x, &y, &ht); - y += ht + 5; x = 5; ht = 0; - - window_fit(panel); - pGuiCtx->fsTextsw = guiBrowser(frame, panel, 60, 30, NULL); - } - xv_set(pGuiCtx->fsDir_PT, PANEL_VALUE, dir, NULL); - xv_set(pGuiCtx->fsFile_PT, PANEL_VALUE, file, NULL); - window_fit(frame); - xv_set(frame, XV_SHOW, TRUE, NULL); - if (dir[0] == '\0') { - guiNotice(pGuiCtx, "directory must be specified"); - return; - } - sprintf(pGuiCtx->fsLsFile, "/tmp/guiFileSel%d.ls.tmp", getpid()); - unlink(pGuiCtx->fsLsFile); - sprintf(message, "cd %s; ls -l >%s", dir, pGuiCtx->fsLsFile); - guiShellCmd_work(pGuiCtx, message, GUI_FILE_SEL_CLIENT, - guiFileSelLsDone, pGuiCtx, 0); - sprintf(message, "processing names in %s", dir); - xv_set(pGuiCtx->fsStatus_PM, PANEL_LABEL_STRING, message, NULL); -} - -/*+/internal****************************************************************** -* NAME guiFileSelCom_mi -* -*-*/ -static void -guiFileSelCom_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_CTX *pGuiCtx=(GUI_CTX *)xv_get(item, XV_KEY_DATA, GUI_PCTX); - char *pSel, *dir, *file, path[240]; - -/*----------------------------------------------------------------------------- -* if there's selected text, use it for file name. If it's in the -* window listing the files, get the file name from the end of the -* line containing the selected text. -*----------------------------------------------------------------------------*/ - pSel = guiGetNameFromSeln(pGuiCtx, pGuiCtx->fsTextsw, 0, 1); - if (pSel != NULL) - xv_set(pGuiCtx->fsFile_PT, PANEL_VALUE, pSel, NULL); - - dir = (char *)xv_get(pGuiCtx->fsDir_PT, PANEL_VALUE); - file = (char *)xv_get(pGuiCtx->fsFile_PT, PANEL_VALUE); - if (strlen(file) > 0) { - sprintf(path, "%s/%s", dir, file); - pGuiCtx->fsCallFn(pGuiCtx->fsCallArg, path, dir, file); -#if 0 - xv_set(pGuiCtx->fsFrame, - XV_SHOW, FALSE, FRAME_CMD_PUSHPIN_IN, FALSE, NULL); -#endif - } - else - guiNotice(pGuiCtx, "file name is blank; select file or use Cancel"); -} - -/*+/internal****************************************************************** -* NAME guiFileSelLs_mi -* -*-*/ -static void -guiFileSelLs_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_CTX *pGuiCtx=(GUI_CTX *)xv_get(item, XV_KEY_DATA, GUI_PCTX); - char message[GUI_TDIM]; - char *dir=(char *)xv_get(pGuiCtx->fsDir_PT, PANEL_VALUE); - unlink(pGuiCtx->fsLsFile); - sprintf(message, "cd %s; ls -l >%s", dir, pGuiCtx->fsLsFile); - guiShellCmd_work(pGuiCtx, message, GUI_FILE_SEL_CLIENT, - guiFileSelLsDone, pGuiCtx, 0); - sprintf(message, "processing names in %s", dir); - xv_set(pGuiCtx->fsStatus_PM, PANEL_LABEL_STRING, message, NULL); -} - -/*+/internal****************************************************************** -* NAME guiFileSelLsDone -* -*-*/ -static void -guiFileSelLsDone(pGuiCtx) -GUI_CTX *pGuiCtx; -{ - char *dir=(char *)xv_get(pGuiCtx->fsDir_PT, PANEL_VALUE); - char message[GUI_TDIM]; - xv_set(pGuiCtx->fsTextsw, TEXTSW_FILE, pGuiCtx->fsLsFile, NULL); - unlink(pGuiCtx->fsLsFile); - if ((int)xv_get(pGuiCtx->fsTextsw, TEXTSW_LENGTH) <= 0) - sprintf(message, "there are no files in %s", dir); - else - sprintf(message, "size and modification date are shown"); - xv_set(pGuiCtx->fsStatus_PM, PANEL_LABEL_STRING, message, NULL); -} - -/*+/subr********************************************************************** -* NAME guiFrame - create a base frame -* -* DESCRIPTION -* Create a base frame. The frame will have have the specified label -* in its title bar, as well as for its icon. The frame will have -* resize corners. If height and width are specified, they will -* determine the size of the frame; otherwise, it will have a -* default size. -* -* If pointers are specified in the call, then the X11 display and -* the XView server are passed back to the caller. -* -* RETURNS -* Frame handle -* -* SEE ALSO -* guiFrameCmd, guiIconCreate -*-*/ -Frame -guiFrame(label, x, y, width, height, ppDisp, pServer) -char *label; /* I label for frame and icon */ -int x; /* I x coordinate for frame, in pixels */ -int y; /* I y coordinate for frame, in pixels */ -int width; /* I width of frame, in pixels, or 0 */ -int height; /* I height of frame, in pixels, or 0 */ -Display **ppDisp; /* O pointer to X display pointer, or NULL */ -Xv_server *pServer; /* O pointer to xview server handle, or NULL */ -{ - Icon icon; - Frame frame; - - icon = (Icon)xv_create(NULL, ICON, ICON_LABEL, label, NULL); - if (icon == NULL) { - (void)printf("error creating \"%s\" icon\n", label); - exit(1); - } - frame = (Frame)xv_create(NULL, FRAME, FRAME_LABEL, label, FRAME_ICON, icon, - WIN_X, x, WIN_Y, y, NULL); - if (frame == NULL) { - (void)printf("error creating \"%s\" frame\n", label); - exit(1); - } - if (width > 0) xv_set(frame, XV_WIDTH, width, NULL); - if (height > 0) xv_set(frame, XV_HEIGHT, height, NULL); - if (ppDisp != NULL) - *ppDisp = (Display *)xv_get(frame, XV_DISPLAY); - if (pServer != NULL) - *pServer = (Xv_server)xv_get(xv_get(frame, XV_SCREEN), SCREEN_SERVER); - - return frame; -} - -/*+/subr********************************************************************** -* NAME guiFrameCmd - create a command frame -* -* DESCRIPTION -* Create a command frame and an associated panel. -* -* If a procedure is specified for handling resize, then the frame -* is set to receive resize events. (The frame will have resize -* corners regardless of whether a procedure is specified.) -* -* RETURNS -* Frame handle -* -* NOTES -* 1. For command frames with text subwindows, the resize procedure can -* be omitted, and the text subwindow will be automatically resized -* when the command frame is resized. -* -*-*/ -Frame -guiFrameCmd(label, parentFrame, pPanel, resizeProc) -char *label; /* I label for command frame */ -Frame parentFrame; /* I parent frame for command frame */ -Panel *pPanel; /* O ptr to default panel of command frame, or NULL */ -void (*resizeProc)();/* I function to handle resize, or NULL */ -{ - Frame frame; - - if (resizeProc == NULL) { - frame = (Frame)xv_create(parentFrame, FRAME_CMD, FRAME_LABEL, label, - FRAME_SHOW_RESIZE_CORNER, TRUE, - XV_SHOW, FALSE, NULL); - } - else { - frame = (Frame)xv_create(parentFrame, FRAME_CMD, FRAME_LABEL, label, - FRAME_SHOW_RESIZE_CORNER, TRUE, - WIN_EVENT_PROC, resizeProc, - WIN_CONSUME_EVENTS, WIN_RESIZE, NULL, - XV_SHOW, FALSE, NULL); - } - if (frame == NULL) { - (void)printf("error creating \"%s\" command frame\n", label); - exit(1); - } - if (pPanel != NULL) { - *pPanel = (Panel)xv_get(frame, FRAME_CMD_PANEL); - if (*pPanel == NULL) { - (void)printf("error getting default panel for \"%s\"\n", label); - exit(1); - } - xv_set(*pPanel, WIN_WIDTH, WIN_EXTEND_TO_EDGE, NULL); - } - return frame; -} - -/*+/subr********************************************************************** -* NAME guiGetNameFromSeln - get a name from a line of selected text -* -* DESCRIPTION -* Examines the selected text to extract a name to return to the caller. -* A `name' is considered to be a string of characters delimited by -* white space. The entire line containing the selection is treated -* as being selected. -* -* The selected text must be within the caller's text subwindow. -* -* The actual action taken depends on the arguments: -* -* head tail pointer is returned to: -* ---- ---- ----------------------------------------------- -* 0 0 entire line containing selection -* 1 0 first word of line containing selection -* 0 1 last word of line containing selection -* -* RETURNS -* char * to name -* -* BUGS -* o this routine isn't reentrant -* o if the caller wants a permanent copy of the name, it must be copied -* prior to the next call to guiGetNameFromSeln -* -*-*/ -char * -guiGetNameFromSeln(pGuiCtx, textSw, headFlag, tailFlag) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -Textsw textSw; /* I handle to text subwindow to treat special */ -int headFlag; /* I 1 to return only the head of the line */ -int tailFlag; /* I 1 to return only the tail of the line */ -{ - int i, bufLen; - char *pSel, *buf; - - buf = pSel = guiGetSelnInTextsw(pGuiCtx, textSw); - if (pSel == NULL) - return NULL; - bufLen = strlen(pSel); - if (headFlag) { -/*----------------------------------------------------------------------------- -* skip leading blanks, then look for the first white space; return -* what's in between to the caller -*----------------------------------------------------------------------------*/ - pSel = buf; - while (*pSel == ' ') { - pSel++; /* skip leading blanks */ - bufLen--; - } - i = 0; - while (i < bufLen-1) { - if (isspace(pSel[i])) - break; - i++; - } - pSel[i] = '\0'; - } - else if (tailFlag) { -/*----------------------------------------------------------------------------- -* looking backward from end, find the first white space; return the -* "tail" of the line to the caller -*----------------------------------------------------------------------------*/ - i = bufLen - 1; - while (i > 0) { - if (buf[i] == '\n') - buf[i] = '\0'; - else if (isspace(buf[i])) { - i++; - break; - } - i--; - } - pSel = &buf[i]; - } - - return pSel; -} - -/*+/subr********************************************************************** -* NAME guiGetSelnInTextsw - get selected text if it's in callers textsw -* -* DESCRIPTION -* Checks to see if there's a text selection in the caller's text -* subwindow. If so, a pointer to it is returned. -* -* RETURNS -* char * to selected text -* -* BUGS -* o this routine isn't reentrant -* o if the caller wants a permanent copy of the name, it must be copied -* prior to the next call to guiGetSelnInTextsw -* -*-*/ -char * -guiGetSelnInTextsw(pGuiCtx, textSw) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -Textsw textSw; /* I handle to text subwindow to treat special */ -{ - Seln_holder holder; - Seln_request *pResponse; - static char buf[GUI_TDIM*2]; - int bufLen; - char *pSel; - - holder = selection_inquire(pGuiCtx->server, SELN_PRIMARY); - pResponse = selection_ask(pGuiCtx->server, &holder, - SELN_REQ_CONTENTS_ASCII, NULL, - NULL); - pSel = pResponse->data + sizeof(SELN_REQ_CONTENTS_ASCII); - bufLen = strlen(pSel); - if (bufLen == 0) - pSel = NULL; /* no selection */ - else if (seln_holder_same_client(&holder, textSw)) { - pResponse = selection_ask(pGuiCtx->server, &holder, - SELN_REQ_FAKE_LEVEL, SELN_LEVEL_LINE, - SELN_REQ_CONTENTS_ASCII, NULL, - NULL); - pSel = pResponse->data; - pSel += sizeof(SELN_REQ_FAKE_LEVEL); - pSel += sizeof(SELN_LEVEL_LINE); - pSel += sizeof(SELN_REQ_CONTENTS_ASCII); - bufLen = strlen(pSel); - if (bufLen > sizeof(buf)-1) { - guiNotice(pGuiCtx, "too much text selected"); - return (char *)NULL; - } - strcpy(buf, pSel); - } - else - pSel = NULL; - return pSel; -} - -/*+/subr********************************************************************** -* NAME guiIconCreate - create an icon to attach to a frame -* -* DESCRIPTION -* Using the bit image for an icon, creates the internal structure -* needed to draw the icon. The icon is then associated with the -* specified frame. -* -* RETURNS -* Icon handle -* -* BUGS -* o assumes an icon size of 64x64 -* -* EXAMPLE -* Associate the icon in "../src/myIcon.icon" with the base frame. -* (myIcon.icon was produced with the OpenLook "iconedit" program.) -* -* #include -* -* myIcon_bits[]={ -* #include "../src/myIcon.icon" -* }; -* -* Icon myIcon; -* -* myIcon = (Icon)guiIconCreate(pGuiCtx->baseFrame, myIcon_bits); -* -*-*/ -Icon -guiIconCreate(frame, iconBits) -Frame frame; /* I handle for frame to receive the icon */ -short *iconBits; /* I array of bits for the icon (64 by 64 assuemd) */ -{ - Server_image icon_image; - Icon icon; - - icon_image = (Server_image)xv_create(NULL, SERVER_IMAGE, - XV_WIDTH, 64, - XV_HEIGHT, 64, - SERVER_IMAGE_BITS, iconBits, - NULL); - icon = (Icon)xv_create(frame, ICON, ICON_IMAGE, icon_image, - ICON_TRANSPARENT, TRUE, NULL); - xv_set(frame, FRAME_ICON, icon, NULL); - - return icon; -} - -/*+/subr********************************************************************** -* NAME guiInit - initialize the gui routines -* -* DESCRIPTION -* Sets up for gui operations, including: -* o connecting to X11 -* o assimilating X11 options from the command line -* o creating a base frame -* o creating a panel within the base frame -* o initializing the gui context block with: -* .user user name -* .host host name (or X server name if different) -* .pwd working directory -* .baseFrame Xview Frame of main program window -* .pDisp the X Display pointer -* .server the Xview server handle -* -* RETURNS -* Panel handle -* -*-*/ -Panel -guiInit(pGuiCtx, pArgc, argv, label, x, y, width, height) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -int *pArgc; /* I pointer to number of command line args */ -char *argv[]; /* I command line args */ -char *label; /* I label for frame and icon */ -int x; /* I x coordinate for frame, in pixels */ -int y; /* I y coordinate for frame, in pixels */ -int width; /* I width of frame, in pixels, or 0 */ -int height; /* I height of frame, in pixels, or 0 */ -{ - char *user, *pwd; - - xv_init(XV_INIT_ARGC_PTR_ARGV, pArgc, argv, 0); - pGuiCtx->baseFrame = guiFrame(label, x, y, width, height, - &pGuiCtx->pDisp, &pGuiCtx->server); - pGuiCtx->fsFrame = NULL; - strcpy(pGuiCtx->host, pGuiCtx->pDisp->display_name); - pwd = getenv("PWD"); - strncpy(pGuiCtx->pwd, pwd, GUI_TDIM-1); - user = getenv("USER"); - strncpy(pGuiCtx->user, user, GUI_TDIM-1); - if (pGuiCtx->host[0] == '\0' || pGuiCtx->host[0] == ':' || - strncmp(pGuiCtx->host, "unix", 4) == 0) { - gethostname(pGuiCtx->host, GUI_TDIM); - } - - return (Panel)xv_create(pGuiCtx->baseFrame, PANEL, - XV_X, 0, XV_Y, 0, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL); -} - -/*+/subr********************************************************************** -* NAME guiLock - provide a "global" lock and unlock mechanism -* -* DESCRIPTION -* -* RETURNS -* 1 if lock succeeds -* 0 if unlock succeeds -* -1 if either operation fails -* -*-*/ -int -guiLock(pGuiCtx, text, lockPath, lock) -GUI_CTX *pGuiCtx; /* I pointer to gui context block */ -char *text; /* I name or description for error messages */ -char *lockPath; /* I pointer to path for lock file */ -int lock; /* I 0,1 to reset,set the lock */ -{ - FILE *pFile; - char msgLock[2*GUI_TDIM]; - char msgWho[2*GUI_TDIM]; - TS_STAMP ts; - char tsText[32]; - int noticeVal; - - if (lock) { - if ((pFile = fopen(lockPath, "r+")) != NULL) { - fread(msgWho, GUI_TDIM, 1, pFile); - fclose(pFile); - if (strncmp(msgWho, "unlocked", 8) != 0) { - sprintf(msgLock, "%s is locked:", text); - noticeVal = notice_prompt(pGuiCtx->baseFrame, NULL, - NOTICE_MESSAGE_STRINGS, msgLock, msgWho, - "you can cancel the operation or force an unlock", NULL, - NOTICE_BUTTON_YES, "Cancel", - NOTICE_BUTTON_NO, "Unlock", - NULL); - if (noticeVal == NOTICE_YES) - return -1; - } - } - } - if ((pFile = fopen(lockPath, "w+")) == NULL) { - guiNoticeFile(pGuiCtx, "couldn't open lock file", lockPath); - return -1; - } - if (lock) { - tsLocalTime(&ts); - tsStampToText(&ts, TS_TEXT_MONDDYYYY, tsText); - sprintf(msgWho, "by:%s on:%s at:%.21s", - pGuiCtx->user, pGuiCtx->host, tsText); - fwrite(msgWho, strlen(msgWho)+1, 1, pFile); - fclose(pFile); - return 1; - } - else { - fwrite("unlocked", 9, 1, pFile); - fclose(pFile); - unlink(lockPath); - return 0; - } -} - -/*+/subr********************************************************************** -* NAME guiMenu - create a menu -* -* DESCRIPTION -* -* RETURNS -* Menu handle -* -*-*/ -Menu -guiMenu(proc, key1, val1, key2, val2) -void (*proc)(); /* I pointer to procedure to handle menu selection */ -enum key1; /* I key for context information for object */ -void *val1; /* I value associated with key */ -enum key2; /* I key for context information for object */ -void *val2; /* I value associated with key */ -{ - Menu menu; - - menu = (Menu)xv_create(NULL, MENU, NULL); - if (menu == NULL) { - (void)printf("error creating menu\n"); - exit(1); - } - if (proc != NULL) { - if (xv_set(menu, MENU_NOTIFY_PROC, proc, NULL) != XV_OK) { - (void)printf("error adding proc to menu\n"); - exit(1); - } - } - if (key1 != 0) { - if (xv_set(menu, XV_KEY_DATA, key1, val1, NULL) != XV_OK) { - (void)printf("error adding key1 to menu\n"); - exit(1); - } - } - if (key2 != 0) { - if (xv_set(menu, XV_KEY_DATA, key2, val2, NULL) != XV_OK) { - (void)printf("error adding key2 to menu\n"); - exit(1); - } - } - - return menu; -} - -/*+/subr********************************************************************** -* NAME guiMenuItem - add a menu item to a menu -* -* DESCRIPTION -* -* RETURNS -* Menu_item handle -* -*-*/ -Menu_item -guiMenuItem(label, menu, proc, inact, dflt, key1, val1, key2, val2) -char *label; /* I label for menu item */ -Menu menu; /* I menu on which to add item */ -void (*proc)(); /* I pointer to procedure to handle menu selection */ -int inact; /* I 0,1 for item active,inactive */ -int dflt; /* I 0,1 for item isn't,is the default */ -enum key1; /* I key for context information for object */ -void *val1; /* I value associated with key */ -enum key2; /* I key for context information for object */ -void *val2; /* I value associated with key */ -{ - Menu_item menuItem; - - menuItem = (Menu_item)xv_create(NULL, MENUITEM, - MENU_STRING, label, MENU_RELEASE, NULL); - if (menuItem == NULL) { - (void)printf("error creating \"%s\" menu item\n", label); - exit(1); - } - if (xv_set(menu, MENU_APPEND_ITEM, menuItem, NULL) != XV_OK) { - (void)printf("error adding \"%s\" menu item to menu\n", label); - exit(1); - } - if (proc != NULL) { - if (xv_set(menuItem, MENU_NOTIFY_PROC, proc, NULL) != XV_OK) { - (void)printf("error adding proc to \"%s\" menu item\n", label); - exit(1); - } - } - if (inact) { - if (xv_set(menuItem, MENU_INACTIVE, TRUE, NULL) != XV_OK) { - (void)printf("error setting \"%s\" menu item inactive\n", label); - exit(1); - } - } - if (dflt) { - if (xv_set(menu, MENU_DEFAULT_ITEM, menuItem, NULL) != XV_OK) { - (void)printf("error setting \"%s\" menu item default\n", label); - exit(1); - } - } - if (key1 != 0) { - if (xv_set(menuItem, XV_KEY_DATA, key1, val1, NULL) != XV_OK) { - (void)printf("error adding key1 to \"%s\" menu item\n", label); - exit(1); - } - } - if (key2 != 0) { - if (xv_set(menuItem, XV_KEY_DATA, key2, val2, NULL) != XV_OK) { - (void)printf("error adding key2 to \"%s\" menu item\n", label); - exit(1); - } - } - - return menuItem; -} - -/*+/subr********************************************************************** -* NAME guiMessage - create a text message object -* -* DESCRIPTION -* -* RETURNS -* Panel_item handle to message -* -* BUGS -* o text -* -* SEE ALSO -* guiMessagePrintf -* -* EXAMPLE -* -*-*/ -Panel_item -guiMessage(label, panel, pX, pY, pHt) -char *label; /* I label for button */ -Panel panel; /* I handle of panel containing message */ -int *pX; /* IO pointer to x position in panel, in pixels */ -int *pY; /* I pointer to y position in panel, in pixels */ -int *pHt; /* IO ptr to height of message, in pixels, or NULL */ -{ - Panel_item item; - int height; - - item = (Panel_item)xv_create(panel, PANEL_MESSAGE, - PANEL_LABEL_STRING, label, XV_X, *pX, XV_Y, *pY, NULL); - if (item == NULL) { - (void)printf("error creating message object\n"); - exit(1); - } - *pX += (int)xv_get(item, XV_WIDTH) + 10; - if (pHt != NULL) { - height = xv_get(item, XV_HEIGHT); - if (height > *pHt) - *pHt = height; - } - - return item; -} - -#if 0 -/*+/macro********************************************************************* -* NAME guiMessagePrintf - do a printf to a guiMessage object -* -* SYNOPSIS -* void -* guiMessagePrintf(panelMessage, fmt, ...) -* Panel_item panelMessage;/* I handle from guiMessage */ -* char *fmt; /* I printf format string */ -* ... /* I other arguments, for printing */ -* -*-*/ -#endif -void guiMessagePrintf(va_alist) -va_dcl -{ - va_list pArgs; - Xv_opaque item; - char *fmt; - char message[500]; - - va_start(pArgs); - item = va_arg(pArgs, Xv_opaque); - fmt = va_arg(pArgs, char *); - vsprintf(message, fmt, pArgs); - va_end(pArgs); - xv_set(item, PANEL_LABEL_STRING, message, NULL); -} - -/*+/macro********************************************************************* -* NAME guiNotice - display a pop-up notice -* -* DESCRIPTION -* Display a pop-up notice with a "continue" button. Several different -* routines are available: -* -* guiNotice(pGuiCtx, message) simply displays the message -* -* guiNoticeFile(pGuiCtx, message, filePath) calls "perror()" to print -* the Unix error message and file name to stdout, then -* displays the message and file path in the pop-up -* -* guiNoticeName(pGuiCtx, message, name) displays the message and the -* name (usually for a channel or file) in the pop-up -* -* In each case, the first argument is a GUI_CTX * pointing to a -* gui context block. The other arguments are char * pointing to -* text strings. -* -* RETURNS -* void -* -*-*/ -void -guiNotice(pGuiCtx, msg) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -char *msg; -{ - notice_prompt(pGuiCtx->baseFrame, NULL, NOTICE_MESSAGE_STRINGS, msg, NULL, - NOTICE_BUTTON_YES, "Continue", NULL); - return; -} -void -guiNoticeFile(pGuiCtx, msg, fName) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -char *msg; -char *fName; -{ - perror(fName); - notice_prompt(pGuiCtx->baseFrame, NULL, - NOTICE_MESSAGE_STRINGS, msg, fName, NULL, - NOTICE_BUTTON_YES, "Continue", NULL); - return; -} -void -guiNoticeName(pGuiCtx, msg, name) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -char *msg; -char *name; -{ - char myName[GUI_TDIM], *pName; - if (strlen(name) < GUI_TDIM-3){ - sprintf(myName, "\"%s\"", name); - pName = myName; - } - else - pName = name; - notice_prompt(pGuiCtx->baseFrame, NULL, - NOTICE_MESSAGE_STRINGS, msg, pName, NULL, - NOTICE_BUTTON_YES, "Continue", NULL); - return; -} - -#if 0 -/*+/macro********************************************************************* -* NAME guiNoticePrintf - do a printf to a guiNotice -* -* SYNOPSIS -* void -* guiNoticePrintf(pGuiCtx, fmt, ...) -* GUI_CTX *pGuiCTx;/* I pointer to gui context */ -* char *fmt; /* I printf format string */ -* ... /* I other arguments, for printing */ -* -*-*/ -#endif -void guiNoticePrintf(va_alist) -va_dcl -{ - va_list pArgs; - GUI_CTX *pCtx; - char *fmt; - char message[500]; - - va_start(pArgs); - pCtx = va_arg(pArgs, GUI_CTX *); - fmt = va_arg(pArgs, char *); - vsprintf(message, fmt, pArgs); - va_end(pArgs); - guiNotice(pCtx, message); -} - -/*+/subr********************************************************************** -* NAME guiPrinter - create a printer context and command frame -* -* DESCRIPTION -* Create a printer context block and command frame for handling -* printer operations. The amenities provided include: -* -* o grabbing the PRINTER environment variable to set the default -* printer to use -* o allowing user to choose point size of font -* o allowing user to choose page orientation -* o allowing user to choose whether to use enscript or lpr for -* the printing operation -* -* The printer context block can be used in the guiEditor call to -* enable the "Print" button for the editor. -* -* RETURNS -* GUI_PRT *, or -* NULL -* -* SEE ALSO -* guiPrintFile, guiPrinterShowCF_mi, guiPrinterShowCF_xvo -* guiEditor -* -*-*/ -GUI_PRT * -guiPrinter(pGuiCtx, parentFrame, title, useEnscript) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -Frame parentFrame; /* I parent of editor command frame */ -char *title; /* I text for command frame title bar */ -int useEnscript; /* I 0,1 to use lpr,enscript for printing */ -{ - GUI_PRT *pPrt; - Panel panel; - Panel_item item; - char *printer; - Panel_item ck; - int y=10, x=5, ht=0; - -/*----------------------------------------------------------------------------- -* Printer: ______ point size: __ v portrait v enscript -* landscape lpr -* ..................status message.............................. -*----------------------------------------------------------------------------*/ - - if ((pPrt=(GUI_PRT *)malloc(sizeof(GUI_PRT))) == NULL) { - return NULL; - } - bzero((char *)pPrt, sizeof(GUI_PRT)); - pPrt->pGuiCtx = pGuiCtx; - pPrt->print_CF = guiFrameCmd(title, parentFrame, &panel, NULL); - - pPrt->printer_PT = guiTextField("Printer:", panel, &x,&y,&ht, - NULL, 19, 8, 0, NULL, 0, NULL); - xv_set(pPrt->printer_PT, PANEL_VALUE, getenv("PRINTER"), NULL); - pPrt->point_PT = guiTextField("point size:", panel, &x,&y,&ht, - NULL, 2, 2, 0, NULL, 0, NULL); - xv_set(pPrt->point_PT, PANEL_VALUE, "8", NULL); - pPrt->landscape_PCS = item = xv_create(panel, PANEL_CHOICE_STACK, - PANEL_LAYOUT, PANEL_VERTICAL, - PANEL_CHOICE_STRINGS, "portrait","landscape",NULL, - PANEL_VALUE, 0, - XV_X, x, XV_Y, y-5, NULL); - x += (int)xv_get(item, XV_WIDTH) + 5; - pPrt->prog_PCS = item = xv_create(panel, PANEL_CHOICE_STACK, - PANEL_LAYOUT, PANEL_VERTICAL, - PANEL_CHOICE_STRINGS, "enscript","lpr",NULL, - PANEL_VALUE, 0, - XV_X, x, XV_Y, y-5, NULL); - x += (int)xv_get(item, XV_WIDTH) + 5; - y += ht + 5; x = 5; ht = 0; - - window_fit(panel); - window_fit(pPrt->print_CF); - return pPrt; -} - -/*+/subr********************************************************************** -* NAME guiPrintFile -* -* DESCRIPTION -* Print a file using the settings in the printer context block. -* -* RETURNS -* void -* -* SEE ALSO -* guiPrinter -* -*-*/ -void -guiPrintFile(pPrtCtx, path) -GUI_PRT *pPrtCtx; /* I pointer to printer context */ -char *path; /* I pathname of file to be printed */ -{ - char command[GUI_TDIM*3]; - - guiPrintGetCmd(pPrtCtx, path, command); - guiShellCmd(pPrtCtx->pGuiCtx, command, GUI_PRINT_CLIENT, NULL, NULL); -} - -/*+/subr********************************************************************** -* NAME guiPrintGetCmd -* -* DESCRIPTION -* Get a print command, using the settings in the printer context block. -* -* RETURNS -* void -* -* SEE ALSO -* guiPrinter -* -*-*/ -void -guiPrintGetCmd(pPrtCtx, path, command) -GUI_PRT *pPrtCtx; /* I pointer to printer context */ -char *path; /* I pathname of file to be printed, or NULL */ -{ - char mode[8]; - - - if ((int)xv_get(pPrtCtx->landscape_PCS, PANEL_VALUE) == 0) - strcpy(mode, ""); /* portrait mode */ - else - strcpy(mode, "-r"); /* rotate to landscape mode */ - if ((int)xv_get(pPrtCtx->prog_PCS, PANEL_VALUE) == 0) { - sprintf(command, "enscript -fCourier%s -q -P%s %s %s", - (char *)xv_get(pPrtCtx->point_PT, PANEL_VALUE), - (char *)xv_get(pPrtCtx->printer_PT, PANEL_VALUE), - mode, path); - } - else { - if (mode[0] != '\0') - guiNotice(pPrtCtx->pGuiCtx, "landscape is ignored when using lpr"); - sprintf(command, "lpr -P%s %s", - (char *)xv_get(pPrtCtx->printer_PT, PANEL_VALUE), path); - } -} - -/*+/macros******************************************************************** -* NAME guiPrinterShowCF_... - make printer command frame visible -* -* DESCRIPTION -* Make the printer setup command frame visible, so that the user -* can modify print parameters. -* -* There are two forms of this routine. The first is to be called -* from a menu; the second is to be called from other objects, such -* as a button. -* guiPrinterShowCF_mi(menu, item); -* guiPrinterShowCF_xvo(item); -* -* RETURNS -* void -* -* SEE ALSO -* guiPrinter, guiPrintFile -* -* EXAMPLE -* Set up a button with a two-item menu--the first item will print -* a file (whose name is in the program's context block), and the -* second item will call this routine. Make the first item the -* default. -* -* Menu menu; -* void print_mi(); -* -* menu = guiMenu(NULL, 0, NULL, 0, NULL); -* guiMenuItem("Print file", menu, print_mi, 0,1, -* PCTX, pCtx, GUI_PPRT, pEdit->pPrtCtx); -* guiMenuItem("Printer setup...", menu, guiPrinterShowCF_mi, 0,0, -* GUI_PPRT, pEdit->pPrtCtx, 0, NULL); -* guiButton("Print", panel, &x, &y, &ht, NULL, menu, 0, NULL, 0, NULL); -* -* -* void print_mi(menu, item) -* Menu menu; -* Menu_item item; -* { GUI_PRT *pPrt=(GUI_PRT *)xv_get(item, XV_KEY_DATA, GUI_PPRT); -* TEST_CTX *pCtx=(TEST_CTX *)xv_get(item, XV_KEY_DATA, PCTX); -* -* guiPrintFile(pPrt, pCtx->file); -* } -* -*-*/ -void -guiPrinterShowCF_mi(menu, item) -Menu menu; -Menu_item item; -{ GUI_PRT *pPrtCtx=(GUI_PRT *)xv_get(item, XV_KEY_DATA, GUI_PPRT); - if ((int)xv_get(pPrtCtx->print_CF, XV_SHOW) == TRUE) - guiAbove(pPrtCtx->print_CF); - else - xv_set(pPrtCtx->print_CF, XV_SHOW, TRUE, NULL); -} - -/*+/internal****************************************************************** -* NAME guiPrinterShowCF_xvo -* -*-*/ -void -guiPrinterShowCF_xvo(item) -Xv_opaque item; -{ GUI_PRT *pPrtCtx=(GUI_PRT *)xv_get(item, XV_KEY_DATA, GUI_PPRT); - if ((int)xv_get(pPrtCtx->print_CF, XV_SHOW) == TRUE) - guiAbove(pPrtCtx->print_CF); - else - xv_set(pPrtCtx->print_CF, XV_SHOW, TRUE, NULL); -} - -/*+/subr********************************************************************** -* NAME guiShellCmd - issue a shell command, cooperating with the notifier -* -* DESCRIPTION -* This routine issues a shell command under the auspices of the -* xview notifier. The command is issued following a fork, with a -* popen call. The critical issue is that the fork results in a -* SIGCHLD signal which the notifier must handle. -* -* The callback routine has the following form: -* void callback(callbackArg, resultBuf) - -* resultBuf is a pointer to the text produced by the command (limited to -* a single line) -* -* RETURNS -* void -* -* BUGS -* o when running under dbx, the child process always results in a -* core dump -* -*-*/ -void -guiShellCmd(pGuiCtx, cmdBuf, clientNum, callbackFn, callbackArg) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -char *cmdBuf; /* I the command string to give the shell */ -Notify_client clientNum;/* I a unique value in the range 100 to 200 to - be used by guiCmdSigchld when the child - is done processing the command */ -void (*callbackFn)();/* I pointer to function for guiCmdSigchld to call */ -void *callbackArg; /* I arg to pass to callbackFn */ -{ - guiShellCmd_work(pGuiCtx, cmdBuf, clientNum, callbackFn, callbackArg, 0); -} -void -guiShellCmd_execv_argv(pGuiCtx, argv, clientNum, callbackFn, callbackArg) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -char *argv; /* I arguments to give the shell */ -Notify_client clientNum;/* I a unique value in the range 100 to 200 to - be used by guiCmdSigchld when the child - is done processing the command */ -void (*callbackFn)();/* I pointer to function for guiCmdSigchld to call */ -void *callbackArg; /* I arg to pass to callbackFn */ -{ - guiShellCmd_work(pGuiCtx, argv, clientNum, callbackFn, callbackArg, 2); -} -void -guiShellCmd_work(pGuiCtx, cmdBuf, clientNum, callbackFn, callbackArg, mode) -GUI_CTX *pGuiCtx; /* I pointer to gui context */ -char *cmdBuf; /* I the command string to give the shell (or - pointer to argv list if mode==2)*/ -Notify_client clientNum;/* I a unique value in the range 100 to 200 to - be used by guiCmdSigchld when the child - is done processing the command */ -void (*callbackFn)();/* I pointer to function for guiCmdSigchld to call */ -void *callbackArg; /* I arg to pass to callbackFn */ -int mode; /* I 0,1,2 for popen,execvp,execvp_with_argv */ -{ - FILE *fp; - int i, pid, cbNum; - int pipe_io[2][2]; - char resultBuf[GUI_TDIM]; - char *argv[20], *buf, *pBuf, dlm; - - cbNum = callbackNum; - while (cbNum >= 0 && callback[cbNum].clientNum != clientNum) - cbNum--; - if (cbNum < 0) { - if (++cbNum < 100) { - callbackNum = cbNum; - callback[cbNum].clientNum = clientNum; - } - else { - guiNotice(pGuiCtx, "guiShellCmd: overflow of client number table"); - return; - } - } - callback[cbNum].callbackFn = callbackFn; - callback[cbNum].callbackArg = callbackArg; - callback[cbNum].result[0] = '\0'; - callback[cbNum].readDone = 0; - callback[cbNum].sigChldDone = 0; - -/*----------------------------------------------------------------------------- -* blatantly stolen from "XView Programming Manual", Dan Heller, O'Reilly & -* Associates, Inc., July 1990, pp.386-389; section 19.8.2, Reading and -* Writing on Pipes; Example 19-4. The ntfy_pipe.c program -* -* child reads: |<=========== pipe_io[0] <===========| parent writes: -* pipe_io[0][0] pipe_io[0][1] -* -* parent reads: |<=========== pipe_io[1] <===========| child writes: -* pipe_io[1][0] pipe_io[1][1] -*----------------------------------------------------------------------------*/ - - if (mode == 1) { - pBuf = buf = (char *)malloc(strlen(cmdBuf)+1); - strcpy(pBuf, cmdBuf); - for (i=0; i<19; i++) { - if (nextNonSpaceField(&pBuf, &argv[i], &dlm) <= 1) - break; - } - argv[i] = NULL; - } - - pipe(pipe_io[0]); - pipe(pipe_io[1]); - if ((pid = fork()) == -1) { - perror("error executing shell command"); - close(pipe_io[0][0]); - close(pipe_io[0][1]); - close(pipe_io[1][0]); - close(pipe_io[1][1]); - if (mode == 1) - free(buf); - return; - } - else if (pid == 0) { /* child process */ - dup2(pipe_io[0][0], 0); /* stdin */ - dup2(pipe_io[1][1], 1); /* stdout */ - dup2(pipe_io[1][1], 2); /* stderr */ - for (i=getdtablesize(); i>2; i--) - close(i); /* close the pipe fd's */ - for (i=0; i 0) - fwrite(resultBuf, 1, i, stdout); - _exit(0); - } - } - if (mode == 1) - free(buf); - close(pipe_io[0][0]); - close(pipe_io[0][1]); - close(pipe_io[1][1]); - callback[cbNum].pipe_io = pipe_io[1][0]; - notify_set_input_func(clientNum, guiCmdRead, pipe_io[1][0]); - notify_set_wait3_func(clientNum, guiCmdSigchld, pid); -} -Notify_value -guiCmdRead(client, fd) -Notify_client client; -int fd; -{ - char buf[GUI_TDIM]; - int nBytes, i; - int j, thisNum=-1; - - - for (j=0; j<=callbackNum; j++) { - if (client == callback[j].clientNum) { - thisNum = j; - break; - } - } - - if (ioctl(fd, FIONREAD, &nBytes) == 0) { - while (nBytes > 0) { - if ((i = read(fd, buf, sizeof(buf)-1)) > 0) { - buf[i] = '\0'; - if (thisNum >= 0) - strcpy(callback[thisNum].result, buf); - nBytes -= i; - } - } - } - if (thisNum >= 0) { - callback[thisNum].readDone = 1; - notify_set_input_func(client, NOTIFY_FUNC_NULL, - callback[thisNum].pipe_io); - close(fd); - if (callback[thisNum].sigChldDone) { - if (callback[thisNum].callbackFn != NULL) { - callback[thisNum].callbackFn(callback[thisNum].callbackArg, - callback[thisNum].result); - } - } - } - return NOTIFY_DONE; -} - -/*/subhead guiCmdSigchld------------------------------------------------------- -* When the child process gets done creating a file, it will die, -* producing SIGCHLD. At that time, call the callback function. -*----------------------------------------------------------------------------*/ -Notify_value -guiCmdSigchld(client, pid, status) -Notify_client client; -int pid; -union wait *status; -{ - Notify_value i=NOTIFY_IGNORED; - int j; - - - for (j=0; j<=callbackNum; j++) { - if (client == callback[j].clientNum) { - callback[j].sigChldDone = 1; - if (WIFEXITED(*status)) { - if (callback[j].readDone) { - if (callback[j].callbackFn != NULL) { - callback[j].callbackFn(callback[j].callbackArg, - callback[j].result); - } - } - i = NOTIFY_DONE; - } - - return i; - } - } - return i; -} - -/*+/subr********************************************************************** -* NAME guiTextField - create a text entry field -* -* DESCRIPTION -* -* RETURNS -* Panel_item handle for text field -* -*-*/ -Panel_item -guiTextField(label, panel, pX, pY, pHt, proc, nStored, nShown, - key1, val1, key2, val2) -char *label; /* I label for text field */ -Panel panel; /* I handle of panel containing text field */ -int *pX; /* IO pointer to x position in panel, in pixels */ -int *pY; /* I pointer to y position in panel, in pixels */ -int *pHt; /* IO ptr to height used by field, in pixels, or NULL */ -void (*proc)(); /* I pointer to procedure to handle carriage return */ -int nStored; /* I number of characters to store in field */ -int nShown; /* I number of characters to show on screen */ -enum key1; /* I key for context information for object */ -void *val1; /* I value associated with key */ -enum key2; /* I key for context information for object */ -void *val2; /* I value associated with key */ -{ - Panel_item item; - int height; - - item = (Panel_item)xv_create(panel, PANEL_TEXT, - PANEL_LABEL_STRING, label, - PANEL_VALUE_STORED_LENGTH, nStored, - PANEL_VALUE_DISPLAY_LENGTH, nShown, - XV_X, *pX, XV_Y, *pY, NULL); - if (item == NULL) { - (void)printf("error creating \"%s\" text field\n", label); - exit(1); - } - if (proc != NULL) { - if (xv_set(item, PANEL_NOTIFY_LEVEL, PANEL_SPECIFIED, - PANEL_NOTIFY_PROC, proc, NULL) != XV_OK) { - (void)printf("error setting PANEL_SPECIFIED for \"%s\"\n",label); - exit(1); - } - } - if (key1 != 0) { - if (xv_set(item, XV_KEY_DATA, key1, val1, NULL) != XV_OK) { - (void)printf("error setting XV_KEY_DATA for \"%s\"\n",label); - exit(1); - } - } - if (key2 != 0) { - if (xv_set(item, XV_KEY_DATA, key2, val2, NULL) != XV_OK) { - (void)printf("error setting XV_KEY_DATA for \"%s\"\n",label); - exit(1); - } - } - *pX += (int)xv_get(item, XV_WIDTH) + 10; - if (pHt != NULL) { - height = (int)xv_get(item, XV_HEIGHT); - if (height > *pHt) - *pHt = height; - } - - return item; -} - -#if 0 -/*+/macro********************************************************************* -* NAME guiTextFieldPrintf - do a printf to a text entry field -* -* SYNOPSIS -* void -* guiTextFieldPrintf(panelItem, fmt, ...) -* Panel_item panelItem;/* I handle from guiTextField */ -* char *fmt; /* I printf format string */ -* ... /* I other arguments, for printing */ -* -*-*/ -#endif -void guiTextFieldPrintf(va_alist) -va_dcl -{ - va_list pArgs; - Xv_opaque item; - char *fmt; - char message[500]; - - va_start(pArgs); - item = va_arg(pArgs, Xv_opaque); - fmt = va_arg(pArgs, char *); - vsprintf(message, fmt, pArgs); - va_end(pArgs); - xv_set(item, PANEL_VALUE, message, NULL); -} - -/*+/subr********************************************************************** -* NAME guiTextswGets - get the next '\n' terminated string from textsw -* -* DESCRIPTION -* Reads the next string from the text subwindow into the caller's -* buffer. Reading stops when a newline is encountered or when the -* caller's buffer is full; the newline IS stored in the buffer. -* The string in the buffer is always null terminated. -* -* The caller must supply the character index (starting with 0) of -* the position in the textsw where reading is to start. On return, -* the caller's index is set to the next available character for -* reading. -* -* RETURNS -* pointer to string, or -* NULL if there are no more characters in text subwindow -* -*-*/ -char * -guiTextswGets(textsw, pBuf, dim, pCharPos) -Textsw textsw; /* I the text subwindow */ -char *pBuf; /* I pointer to buffer to receive string */ -int dim; /* I dimension of buffer */ -int *pCharPos; /* IO index of character to start reading */ -{ - Textsw_index nextPos; - int i; - char *pStr; - - nextPos = (Textsw_index)xv_get(textsw, TEXTSW_CONTENTS, *pCharPos, - pBuf, dim-1); - if (nextPos == *pCharPos) - return NULL; - for (i=0; i= nextPos) { - pBuf[i] = '\0'; - return pBuf; - } - (*pCharPos)++; - if (pBuf[i] == '\n') { - pBuf[i+1] = '\0'; - return pBuf; - } - } - pBuf[i] = '\0'; - return pBuf; -} - -#if 0 -/*+/macro********************************************************************* -* NAME guiTextswPrintf - do a printf to a guiTextsw -* -* SYNOPSIS -* void -* guiTextswPrintf(textsw, fmt, ...) -* Textsw textsw; /* I handle from guiTextsw */ -* char *fmt; /* I printf format string */ -* ... /* I other arguments, for printing */ -* -*-*/ -#endif -void guiTextswPrintf(va_alist) -va_dcl -{ - va_list pArgs; - Textsw textsw; - char *fmt; - char message[500]; - int n, L; - - va_start(pArgs); - textsw = va_arg(pArgs, Textsw); - fmt = va_arg(pArgs, char *); - vsprintf(message, fmt, pArgs); - va_end(pArgs); - L = strlen(message); - n = textsw_insert(textsw, message, L); - if (n != L) - return; - n = (int)xv_get(textsw, TEXTSW_INSERTION_POINT); - textsw_possibly_normalize(textsw, n); -} - -/*+/subr********************************************************************** -* NAME guiTextswPuts - write string into textsw -* -* DESCRIPTION -* Writes the string to the text subwindow. -* -* The caller must supply the character index (starting with 0) of -* the position in the textsw where writing is to start. On return, -* the caller's index is set to the next available character for -* writing. -* -* RETURNS -* 0, or -* EOF if an error occurs during the write -* -*-*/ -int -guiTextswPuts(textsw, pBuf, pCharPos) -Textsw textsw; /* I the text subwindow */ -char *pBuf; /* I pointer to buffer to write to text subwindow */ -int *pCharPos; /* IO index of character position to start writing */ -{ - Textsw_index n; - int L=strlen(pBuf); - - xv_set(textsw, TEXTSW_INSERTION_POINT, *pCharPos, NULL); - n = textsw_insert(textsw, pBuf, L); - if (n != L) - return EOF; - *pCharPos = (int)xv_get(textsw, TEXTSW_INSERTION_POINT); - textsw_possibly_normalize(textsw, *pCharPos); - return 0; -} - -/*+/subr********************************************************************** -* NAME guiTextswReset - reset a text subwindow, discarding its contents -* -* DESCRIPTION -* -* RETURNS -* void -* -*-*/ -void -guiTextswReset(textsw) -Textsw textsw; /* I the text subwindow */ -{ - textsw_reset(textsw, 0, 0); -} - -/*+/subr********************************************************************** -* NAME guiTimer - create a timer -* -* DESCRIPTION -* Creates and starts an interval timer. The interval may include -* fractions of seconds. -* -* The timer callback function has the form of the usual Unix itimer -* function: -* -* void callbackFn(callbackArg, dummy) -* void *callbackArg -* int dummy; -* { -* } -* -* BUGS -* o a mechanism for cancelling the timer or changing its interval isn't -* yet part of guiSubr -* -*-*/ -void -guiTimer(seconds, callbackFn, callbackArg) -double seconds; /* I number of seconds for timer interval */ -void (*callbackFn)();/* I name of callback function */ -void *callbackArg; /* I argument to pass to callback function */ -{ - struct itimerval t; - - t.it_interval.tv_sec = t.it_value.tv_sec = (int)aint(seconds); - t.it_interval.tv_usec = t.it_value.tv_usec = - (int)(fmod(seconds, 1.)*1000000.); - notify_set_itimer_func(callbackArg, callbackFn, ITIMER_REAL, &t, NULL); -} - -#endif diff --git a/src/util/guiTest.icon b/src/util/guiTest.icon deleted file mode 100644 index 9e673b918..000000000 --- a/src/util/guiTest.icon +++ /dev/null @@ -1,66 +0,0 @@ -/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16 - */ - 0xBFFF,0xFFFF,0xFFFF,0xFFFE, - 0x6000,0x0000,0x0000,0x0007, - 0xC000,0x0000,0x0000,0x0003, - 0x8F00,0x0000,0x0000,0x0003, - 0x9F80,0x0000,0x0001,0x0003, - 0x9980,0x0000,0x0003,0x0003, - 0x9800,0x0000,0x0005,0x0003, - 0x9BC0,0x0000,0x0009,0x0003, - 0x9BC0,0x0000,0x0011,0x0003, - 0x9980,0x0000,0x0021,0x0003, - 0x9F80,0x0000,0x0041,0x0003, - 0x8F00,0x0000,0x0081,0x0003, - 0x8000,0x0040,0x0101,0x0003, - 0x8000,0x0040,0x00E1,0x0003, - 0x9F80,0x0020,0x031D,0x0003, - 0x9F80,0x0020,0x020B,0x0003, - 0x8600,0x0010,0x0406,0x0003, - 0x8600,0x0010,0x0405,0x0003, - 0x8600,0x0010,0x0405,0x0003, - 0x8600,0x0008,0x0209,0x0003, - 0x8600,0x0008,0x031C,0x8003, - 0x8600,0x0004,0x01E2,0x8003, - 0x8600,0x0007,0x0112,0x0003, - 0x8000,0x0008,0x8213,0x4003, - 0x8000,0x0008,0x82E9,0x0003, - 0x8F00,0x0009,0x4319,0x4003, - 0x9F80,0x0006,0x3508,0x0003, - 0x9980,0x0001,0x0E18,0x0003, - 0x9F80,0x0000,0x8624,0x0003, - 0x9F80,0x0000,0x4044,0x0003, - 0x9980,0x0000,0x4044,0x0003, - 0x9980,0x0000,0x2082,0x0003, - 0x9980,0x0000,0x1102,0x0003, - 0x9980,0x0000,0x1E02,0x0003, - 0x8000,0x0000,0x1002,0x0003, - 0x8000,0x0000,0x1001,0x0003, - 0x8000,0x0000,0x2001,0x0003, - 0x8000,0x0000,0x2001,0x0003, - 0x8000,0x0000,0x2000,0x8003, - 0x8000,0x0000,0x4000,0x8003, - 0x8000,0x0000,0x4000,0x8003, - 0x8000,0x0000,0x4000,0x8003, - 0x8000,0x0000,0x8000,0x4003, - 0x8000,0x0000,0xFFFF,0xC003, - 0x8000,0x0000,0x0000,0x0003, - 0x8000,0x0000,0x0000,0x0003, - 0x8000,0x0000,0x0000,0x0003, - 0x8000,0x0000,0x0000,0x0003, - 0x8000,0x0000,0x0000,0x0003, - 0x8000,0x0008,0x0000,0x0003, - 0x8000,0x0001,0xF000,0x4003, - 0x8000,0x7248,0x4186,0xF003, - 0x8000,0x9248,0x4248,0x4003, - 0x8000,0x9248,0x43CC,0x4003, - 0x8000,0x9248,0x4206,0x4003, - 0x8000,0xB2C8,0x4202,0x4003, - 0x8000,0x5148,0x41CC,0x3003, - 0x8000,0x1000,0x0000,0x0003, - 0x8000,0x6000,0x0000,0x0003, - 0x8000,0x0000,0x0000,0x0003, - 0x8000,0x0000,0x0000,0x0003, - 0xC000,0x0000,0x0000,0x0003, - 0xFFFF,0xFFFF,0xFFFF,0xFFFE, - 0x7FFF,0xFFFF,0xFFFF,0xFFFD diff --git a/src/util/in.calcTest b/src/util/in.calcTest deleted file mode 100644 index c8495e783..000000000 --- a/src/util/in.calcTest +++ /dev/null @@ -1,333 +0,0 @@ -! ***************************************************** -! TEST OF -! calcPerform -! -! ------------- TEST CALCULATION ALGORITHM ------------- -! -! ***************************************************** -! -! ld = - -calcTest "(a+b+c)>=d" "1 2 3 4 5 6 7 8 9 10 11 12" 1 VERIFY -calcTest "(a+b+c)>=(d+e)" "1 2 3 4 5 6 7 8 9 10 11 12" 0 VERIFY - -! --------------------------------------Greater than > - -calcTest "(e+f+g)>(h+i)" "1 2 3 4 5 6 7 8 9 10 11 12" 1 VERIFY -calcTest "(e+f+g)>(h+i+k)" "1 2 3 4 5 6 7 8 9 10 11 12" 0 VERIFY - -! --------------------------------------Less than or equal to <= - -calcTest "(e+f+g)<=(i+k)" "1 2 3 4 5 6 7 8 9 10 11 12" 1 VERIFY -calcTest "(e+f+g+h)<=(i+k)" "1 2 3 4 5 6 7 8 9 10 11 12" 0 VERIFY - -! --------------------------------------Less than < -calcTest "(a+b) -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static VOID lopi_init(); -static VOID create_menu(); -static VOID get_displays(); -static struct mon_node *mon_alloc(); /* Allocates memory for an update.*/ -static struct txt_node *txt_alloc(); /* Allocates memory for a test label. */ -static struct ev_node *ev_alloc(); /* Allocates memory for an event node. */ -static struct except_node *except_alloc(); /* Allocates memory for an exception node. */ -static struct window_node *win_alloc(); /* Allocates memory for a window structure. */ -static VOID init_monitors (); -static VOID print_menu(); -static VOID mv_cursor(); -static VOID get_key(); -static char get_esc_seq(); -static VOID make_box(); -static VOID get_value(); -static VOID blank_fill(); -static VOID mv_cursor(); -static char *skipblanks(); -static int getline(); -static VOID lopi_conn_handler(); -static VOID lopi_exception_handler(); -static VOID add_ctl(); -static VOID add_mon(); -static VOID add_txt(); -static char *skip_to_digit(); -static int int_to_short(); -static VOID read_disp_lst(); -static VOID display_text(); -static VOID display_file(); -static VOID display_monitors(); -static VOID stop_monitors(); -static VOID lopi_ev_handler(); -static VOID lopi_exception_handler(); -static VOID lopi_conn_handler(); -static VOID free_mem(); -static struct mon_node *find_channel(); -static VOID put_value(); -static int to_short(); - -#define FN_LEN 24 -#define LIST_END -1 -#define NEWLINE '\n' -#define MXMENU 34 -#define ESC '\33' -#define L_BRACKET '[' -#define RETURN '\15' -#define CR '\13' -#define DELETE '\177' -#define BLANK ' ' -#define UNDERSC '_' -#define MINUS '-' -#define COLON ':' -#define TILDE '~' -#define ASTER '*' /* Legal text character. */ -#define L_ARROW '$' -#define R_ARROW '%' -#define U_ARROW '!' -#define D_ARROW '@' -#define ILL_CHR '#' -#define F6 '^' /* Permits exit back to main menu. */ -#define F7 '&' -#define DOT '.' - -/* VT220 Escape secquences */ - -#define CLEAR_SCREEN fdprintf(lopi_fd,"%c", '\33'); \ - fdprintf(lopi_fd,"%s","[2J"); -#define INIT_CURSOR fdprintf(lopi_fd,"%c", '\33'); \ - fdprintf(lopi_fd,"%s", "[?25h"); -#define ERASE_LINE fdprintf(lopi_fd,"%c",ESC); \ - fdprintf(lopi_fd,"%s","[2K"); -#define ESCAPE fdprintf(lopi_fd,"%c",'\33'); -#define REVERSE_VIDEO fdprintf(lopi_fd,"%s","[7;5m"); -#define ATR_OFF fdprintf(lopi_fd,"%s","[0m"); - -#define CTL 1 -#define MON 0 -#define DEBUG 0 -#define OFF 0 -#define ON 1 -#define NO_CMD "\0" -#define NEW_DATA 1 -#define NO_NEW_DATA 0 -#define NOTHING_SELECTED -1 /* Flag to indicate that lopi is waiting - for the user to make a selection. */ -#define STRT_TTLE_ROW 1 /* Title row position. */ -#define STRT_TTLE_COL 30 /* Title column position. */ -#define STRT_MENU_ROW 7 /* Row position of first menu item. */ -#define STRT_MENU_COL 20 /* Column position of first menu item. */ -#define MAX_DISP_NUM 10 /* Maximum number of displays. */ -#define MAX_LIN_LEN 80 /* Maximum number of characters in a line of a - display file. */ -#define BUFF_SIZE 10 -#define MAX_SCREEN_HEIGHT 24 -#define MAX_SCREEN_WIDTH 78 -#define CHAN_NM_SIZE 40 -#define MAX_FIELD_SIZE 8 - -#define ERR_MSG_ROW 20 -#define ERR_MSG_COL 0 -#define BOX_IN_ROW 2 -#define BOX_IN_COL 43 -#define BEG_BOX 1 -#define END_BOX 3 -#define UNDEF 8 -#define FOUND 1 -#define NOT_FOUND 0 - - -struct except_node{ - long status; /* Channel access standard status code. */ - char msg[MAX_LIN_LEN]; /* Character string containing context information. */ - short flg; /* Flag to indicate the arrival of an exception. */ - }; - -struct ev_node{ - short data_flg; /* Flag to indicate that new data has been added. */ - short status ; /* Status returned from function calls. */ - short severity; - char str[MAX_STRING_SIZE]; - short prev_size; /* Size of string. */ - }; - - -struct mon_node{ /* Structure to hold update information. */ - short l_crn_row; /* Row location of upper left hand corner. */ - short l_crn_col; /* Col location of upper left hand corner. */ - short r_crn_row; /* Row location of lower right hand corner. */ - short r_crn_col; /* Col location of lower right hand corner. */ - char chan[CHAN_NM_SIZE]; /* Channel name. */ - chid chan_id; /* Channel id for channel access. */ - short chan_type; - short prev_size; - struct ev_node *ev_ptr; /* Pointer to event handler info. */ - short conn_flg; /* Pointer to connection handler info. */ - struct mon_node *next; /* Pointer to next node in the linked list. */ - struct mon_node *prev; /* Pointer to previous node in the linked list. */ - }; - -struct txt_node{ /* Structure to hold text label information. */ - short l_crn_row; /* Row location of upper left hand corner. */ - short l_crn_col; /* Col location of upper left hand corner. */ - char txt_str[MAX_LIN_LEN]; /* Text string to be displayed. */ - struct txt_node *next; /* Pointer to next node. */ - }; - -struct window_node{ /* Structure which will hold all window information. There - will be a linked list of each kind of structure possible. - This structure will contain a pointer to the first node on - that list. */ - struct mon_node *c_head; - struct mon_node *m_head; - struct txt_node *t_head; - }; - -static SEM_ID mon_sem,key_sem; /* Semaphores for protection of monitor and control - linked lists, the key board and screen, and the - exception handler's structure */ - -static struct window_node *wind_array[MAX_DISP_NUM]; /* Array of windows available. */ - -static char disp_lst[FN_LEN] = "lopi.dat"; /* Array for name of file containing list of display files. */ -static char *d_menu[MXMENU]; -static short nxt_ln = 0; /* Counter. */ -static short data_flg; /* Global Flag to indicate a monitor has received data. Set in event handler. - Reset in display_monitors when data has been displayed. */ -static short m_row; /* Current row number . */ -static short m_col; /* Current column number. */ -static int n_lines = 0; /* Number of Menu lines read in. */ - -static int tid1,tid2; /* Task id's */ -static short screen = OFF; -static short init = TRUE; /* Flag which indicates first pass through the menu. */ -static char key_buff[BUFF_SIZE],*rd_ptr,*wr_ptr; /* Buffer which will accumulate keyboard input while - waiting for a chance to update the screen. Pointers showing where - next available spot is for reading and for writing. */ -static char val_in[MAX_STRING_SIZE]; /* Global buffer for user input value to be written to data base. */ -static short q_num; /* Number of items waiting to be output from input queue. */ -static int status; - -static int err_fd; /* Fd to which logMsg will write during the course of this - subroutine. */ -static int lopi_fd; /* File descriptor for serial port. */ -struct except_node *except_ptr; -static int num_times = 0;; -extern shellTaskId; - - -shell_init() -{ - ioctl(1,FIOSETOPTIONS,OPT_RAW); -} - -/* - * CA_SIGNAL() - * - * - */ - -lopi_signal(ca_status,message) -int ca_status; -char *message; -{ - short row = ERR_MSG_ROW; - short col = ERR_MSG_COL; - char prefix[MAX_LIN_LEN]; - char txt_str[MAX_LIN_LEN]; - - static char *severity[] = - { - "Warning", - "Success", - "Error", - "Info", - "Fatal", - "Fatal", - "Fatal", - "Fatal" - }; - - strcpy(txt_str, "CA.Diagnostic.........."); - mv_cursor(&row,&col,txt_str); - - - if(message){ - strcpy(prefix,"Severity:[%s] Error:[%s]Context: [%s]"); - sprintf(txt_str,prefix,severity[CA_EXTRACT_SEVERITY(ca_status)], - ca_message_text[CA_EXTRACT_MSG_NO(ca_status)],message); - mv_cursor(&row,&col,txt_str); - } - else{ - strcpy(prefix,"Severity:[%s],Error:[%s]"); - sprintf(txt_str,prefix,severity[CA_EXTRACT_SEVERITY(ca_status)], - ca_message_text[CA_EXTRACT_MSG_NO(ca_status)]); - mv_cursor(&row,&col,txt_str); - } - /* - * - * - * Terminate execution if unsuccessful - * - * - */ - if( !(ca_status & CA_M_SUCCESS) ){ -# ifdef VMS - lib$signal(0); -# endif -# ifdef vxWorks - ti(VXTHISTASKID); - tt(VXTHISTASKID); -# endif - /* abort(ca_status); */ - } - -} - -VOID lopi() - -{ - - /* Create and initialize semaphores protecting the keyboard and the - monitor linked list. */ - mon_sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - key_sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - data_flg = NO_NEW_DATA;; - except_ptr = except_alloc(); - - /* Initialize buffer for keyboard input. */ - - blank_fill(key_buff,BUFF_SIZE); - - /* Open file in which errrors will be recorded. */ - SEVCHK(ca_task_initialize(),"Unable to initialize."); - - q_num = 0; - - tid1 = taskSpawn("lopi_init",210,VX_STDIO||VX_FP_TASK,20000,lopi_init,&screen,&q_num,&data_flg, - key_buff,val_in); - tid2 = taskSpawn("get_key",208,VX_STDIO||VX_FP_TASK,5000,get_key,&q_num, - key_buff,&screen,val_in); - - /* Suspend shell to allow lopi the use of the keyboard. */ - taskSuspend(shellTaskId); - } - -/**********************************************************************************/ -/* Entry point for local terminal. Reads a file called lopi.dat which contains a */ -/* list of display files. Reads in the display names and the display files and */ -/* makes a menu from which the user can select the display he wants to see. */ -/* Display information is kept in an array of window structures. Displays the */ -/* selected display. -/**********************************************************************************/ - -static VOID lopi_init(screen,que_num,pdata_flg,k_buff,val_in) - short *screen; - short *que_num; /* Number of items in keyboard buffer waiting to be read. */ - short *pdata_flg; /* Flag to indicate that monitor had received new data. */ - char k_buff[BUFF_SIZE]; /* Buffer for key board entries and pointer - to the next empty space in the buffer */ - char val_in[MAX_STRING_SIZE]; - { - char *read_ptr, *write_ptr; /* Pointers to next available places for reading and - writing in the keyboard input buffer. */ - short selected; - char prefix[MAX_LIN_LEN]; - char txt_str[MAX_LIN_LEN]; - register short display = ON; - int disp_nm[FN_LEN]; - short t_row, t_col = 0; - int new_fd; /* Fd to which standard error is now writing. This is the fd - to which logMsg will be reset as this subroutine terminates. */ - - read_ptr = k_buff; - write_ptr = k_buff; - err_fd = creat("lopi_err",0666); - if((err_fd = open("lopi_err",UPDATE,0666)) == ERROR){ - printf("Aborting. Unable to open error file.\n"); - taskResume(shellTaskId); - new_fd = ioGlobalStdGet(0,STD_ERR); - ca_task_exit(); - semDelete(key_sem); - semDelete(mon_sem); - taskDelete(tid2); - taskDelete(tid1); - exit(1); - } - - - - /* Build menu a from file called lopi.dat. Count the lines read in. This - is the number of display files read in. */ - - create_menu(d_menu,&n_lines); - get_displays(d_menu,n_lines,wind_array); - - /* Gives user a chance to read error messages generated by get_displays. */ - - - /* Open a file descriptor for the serial terminal. - Set it to raw mode. */ - if ((lopi_fd = open("/tyCo/0",UPDATE,0)) == ERROR){ - printf("Aborting. Unable to open serial port file.\n"); - taskResume(shellTaskId); - ca_task_exit(); - status = ioctl(lopi_fd,FIOSETOPTIONS,OPT_TERMINAL); - new_fd = ioGlobalStdGet(0,STD_ERR); - semDelete(key_sem); - semDelete(mon_sem); - taskDelete(tid2); - taskDelete(tid1); - exit(1); - } - - logFdSet(err_fd); - - if ((status = ioctl(lopi_fd,FIOSETOPTIONS,OPT_RAW)) == ERROR){ - printf("Aborting. Unable to set I/O mode.\n"); - taskResume(shellTaskId); - ca_task_exit(); - new_fd = ioGlobalStdGet(0,STD_ERR); - status = ioctl(lopi_fd,FIOSETOPTIONS,OPT_TERMINAL); - semTake(key_sem); - semGive(key_sem); - semDelete(key_sem); - semDelete(mon_sem); - taskDelete(tid2); - taskDelete(tid1); - exit(1); - } - - CLEAR_SCREEN - INIT_CURSOR - selected = NOTHING_SELECTED; - - while (display == ON) - { - if (n_lines == 0) - printf("No displays to open"); - else if (n_lines == 1) - { - selected = 0; - init = FALSE; - *screen = ON; - CLEAR_SCREEN - display_file(wind_array,selected,screen,que_num,pdata_flg,k_buff,val_in); - selected = NOTHING_SELECTED; - } - - else if (((*screen) == OFF) && (n_lines >1)) - { - - /* Task delay allows display_monitors to finish writing - to screen before clearing the screen and printing the - menu. */ - - if (!init) - taskDelay(100); - CLEAR_SCREEN - print_menu(d_menu,n_lines); - m_row = STRT_MENU_ROW; - m_col = STRT_MENU_COL-1; - *que_num = 0; - write_ptr = k_buff; - - /* Move cursor upper left hand corner of menu. */ - mv_cursor(&m_row,&m_col,NO_CMD); - - } - - /* Get cursor movement from the screen. */ - - /* Move cursor only along edge of menu while menu is - being displayed. Semaphores are not necessary - no other task is competing for screen or linked lists at - this time. */ - - while ((selected) == NOTHING_SELECTED && (n_lines > 1) ) - { - - while ((*que_num) > 0) - { - switch (*write_ptr) - { - case U_ARROW: - m_row++; - if (m_row > n_lines + STRT_MENU_ROW ) - m_row = STRT_MENU_ROW; - mv_cursor(&m_row,&m_col,NO_CMD); - break; - case D_ARROW: - m_row--; - if ( m_row < STRT_MENU_ROW) - m_row = n_lines + STRT_MENU_ROW; - mv_cursor(&m_row,&m_col,NO_CMD); - break; - case RETURN: - selected = m_row - STRT_MENU_ROW; - t_row++; - break; - - default: - break; - - } /* End switch. */ - - /* If a legal restart occurs reset buffer pointer - back to the first space in the buffer. and data to be - processed back to 0.*/ - - if ((*write_ptr == F6) || (*write_ptr == RETURN) || (*write_ptr == F7)) - { - semTake(key_sem); - (*que_num) = 0; - write_ptr = k_buff; - semGive(key_sem); - } - else - { - semTake(key_sem); - write_ptr++; - (*que_num)--; - if(*write_ptr == NULL) - write_ptr = k_buff; - semGive(key_sem); - } - } /*end while *que_num > 0 */ - - - - } /* End while selected == NOTHING_SELECTED . */ - - - /* User has chosen to exit the menu and the program. */ - - if (( selected == n_lines) || (n_lines == 1) ) - { - display = OFF; - CLEAR_SCREEN - status = ioctl(lopi_fd,FIOSETOPTIONS,OPT_TERMINAL); - taskResume(shellTaskId); - } - - else if ((selected >= 0) && (selected < n_lines)) - { - init = FALSE; - *screen = ON; - CLEAR_SCREEN - display_file(wind_array,selected,screen,que_num,pdata_flg,k_buff,val_in); - selected = NOTHING_SELECTED; - semTake(key_sem); - *screen = OFF; - semGive(key_sem); - } - - } /* End while display. */ - - /* Reset terminal to terminal mode. */ - - close(err_fd); - new_fd = ioGlobalStdGet(0,STD_ERR); - logFdSet(new_fd); - semTake(key_sem); - taskDelete(tid2); - taskDelete(tid1); - ca_task_exit(); - semGive(key_sem); - taskDelay(100); - free_mem(wind_array,d_menu,n_lines); - semDelete(key_sem); - semDelete(mon_sem); - close(lopi_fd); - - } /* End lopi. */ - -/******************************************************************************************/ -/* Uses NFS to read in a list of displays kept in a file called lopi.dat in the application */ -/* directory. */ -/******************************************************************************************/ - -static VOID create_menu(menu,nlines) - char *menu[MXMENU]; - int *nlines; - { - FILE *fp; - int ltr; - char item[40],*m_ptr; - short chr_ctr = 0; /* Counter. */ - - /* Open file. Return error message if that is impossible. */ - - if ((fp = fopen(disp_lst, "r")) == NULL) - { - printf("Can't open %s \n", disp_lst); - exit(1); - } - - /* Otherwise create a menu of displays for this application. */ - - else - { - - *nlines = 0; - - /* Read in characters from display file one by one.*/ - while ((ltr = getc(fp)) != EOF) - { - item[chr_ctr] = ltr; - chr_ctr++; - - /* At the end of each line, enter the display title into the display - memory array. */ - - if ((ltr == NEWLINE) && (chr_ctr != 0)) - { - item[chr_ctr-1] = NULL; - if (( m_ptr = (char *) malloc(chr_ctr + 1)) == NULL) - { - printf("Not enough memory in create_menu\n"); - exit(1); - } - - if (*nlines <= MXMENU) - { - strcpy(m_ptr,item); - d_menu[nxt_ln++] = m_ptr; - (*nlines)++; - chr_ctr = 0; /* Reset the character counter. */ - } - else /* Error message for too many display names. */ - printf("Maximum number of displays exceeded."); - } - } /* End while. */ - } /* End else. */ - - fclose(fp); /* Close the file. */ - } /* End create_menu. */ - - - /************************************************************************/ - /* Prints to the screen the menu passed to it in the array menu as */ - /* well as the instructions. Positions cursor in front of the first */ - /* menu item. */ - /************************************************************************/ - - static VOID print_menu(menu,nlines) - char *menu[MXMENU]; /* Array of menu items. */ - int nlines; /* Number of items in the array. */ - { - short mrow; - short mcol; - short b_ctr; - mrow = STRT_TTLE_ROW; - mcol = STRT_TTLE_COL; - mv_cursor(&mrow,&mcol,"DISPLAY MENU"); - mrow++; - mcol -= 3; - mv_cursor(&mrow,&mcol,NO_CMD); - mrow++; - mv_cursor(&mrow,&mcol,"Move cursor with arrow keys."); - mrow++; - mv_cursor(&mrow,&mcol,"Select with carriage return."); - mrow = STRT_MENU_ROW; - mcol = STRT_MENU_COL; - for (b_ctr = 0; b_ctr < nlines; b_ctr++) - { - mv_cursor(&mrow,&mcol,menu[b_ctr]); - mrow++; - } - mv_cursor (&mrow,&mcol,"EXIT"); - mrow++; - mrow = STRT_MENU_ROW; - mcol = STRT_MENU_COL - 1; - } - - -/***********************************************************************************/ -/* Gets keystrokes from the screen,translates them to lopi opi commands and */ -/* puts them in a buffer which is read by lopi, display_file and display_monitors. */ -/* Reads up arrow,down arrow,right arrow, left arrow, F6, F7 and carriage */ -/* return. When it reads an escape it calls get_esc_seq to complete the job of */ -/* getting the escape sequence from the screen and translating it into a lopi */ -/* command. */ -/***********************************************************************************/ - -static VOID get_key(cue_num,k_buff,pScreen,val_in) - - short *cue_num; /* Contains the number of letters in the queue ends the message - to getkey that the buffer has been read. */ - char k_buff[BUFF_SIZE]; - short *pScreen; - char val_in[MAX_STRING_SIZE]; - { - char *in_ptr; /* Pointer to next place for in put and next place - for output. */ - short ctr; /* Counter. */ - char ltr; - int nmbr; - - int mon_row = 0; /* For debug only. */ - int mon_col = 0; - int t_row = 0; /* For debug only. */ - int t_col = 0; - char txt_str[MAX_LIN_LEN]; - char prefix[MAX_LIN_LEN]; - - semTake(key_sem); - *pScreen = OFF; - in_ptr = k_buff; - *cue_num = 0; - semGive(key_sem); - - FOREVER - { - - /* Read characters from keyboard and put them in a buffer until - the buffer has been read.If an escape is reached continue to read - input until one of the supported escape sequences has been completed. - Convert those keystrokes to a code and return it. */ - nmbr = read(lopi_fd,<r,1); - - do - { - /* If the letter is an escape sequence, do more reads to get - the rest of the sequence. Then convert it to a single character - and put it in the buffer. */ - - if(ltr == ESC) - { - semTake(key_sem); - ltr = get_esc_seq(); - semGive(key_sem); - - switch(ltr) - { - case U_ARROW: - semTake(key_sem); - (*in_ptr) = U_ARROW; - (*cue_num)++; - semGive(key_sem); - in_ptr++; - break; - - case D_ARROW: - semTake(key_sem); - (*in_ptr) = D_ARROW; - (*cue_num)++; - semGive(key_sem); - in_ptr++; - break; - - case F6: - semTake(key_sem); - (*in_ptr) = F6; - *pScreen = OFF; - in_ptr = k_buff; - semGive(key_sem); - break; - - case F7: - if (*pScreen == ON) - { - make_box(); - get_value(val_in); - taskDelay(30); - } - semTake(key_sem); - (*in_ptr) = F7; - (*cue_num)++; - in_ptr = k_buff; - semGive(key_sem); - ltr = NULL; - break; - default: - break; - - } /* End switch. */ - } /* End if ltr == ESC. */ - if ((ltr == RETURN) || (ltr == CR)) - { - semTake(key_sem); - (*in_ptr) = RETURN; - (*cue_num)++; - semGive(key_sem); - in_ptr = k_buff; - } - - if ((*in_ptr) == NULL) - in_ptr = k_buff; - nmbr = read(lopi_fd,<r,1); - taskDelay(1); - } /* End do while. */ - while ((*cue_num) <= (BUFF_SIZE -1) ); /* Exit this loop if buffer is filled. */ - - - } /* End FOREVER */ - - } /* End get_key. */ - - -/********************************************************************************/ -/* Gets escape sequences from screen and returns their meaning to get key. */ -/* Returns up arrow, down arrow, right arrow, left arrow, F6 and F7. For */ -/* all other letters returns ILL_CHR . */ -/********************************************************************************/ - -static char get_esc_seq() - { - char lttr; - int nbr; - - nbr = read(lopi_fd,<tr,1); - if (lttr ==L_BRACKET) - { - nbr = read(lopi_fd,<tr,1); - switch(lttr) - { - case 'A': - return D_ARROW; - case 'B': - return U_ARROW; - case '1': - nbr = read(lopi_fd,<tr,1); - if (lttr == '7') - { - nbr = read(lopi_fd,<tr,1); - if (lttr == TILDE) - return F6; - } - if (lttr == '8') - { - nbr = read(lopi_fd,<tr,1); - if (lttr == TILDE) - return F7; - } - default: - /* If an illegal escape sequence has been read - then the legal character flag will not be set - and buffer write pointer will not be advanced. */ - - return ILL_CHR; - } /* End switch */ - - } /* End if ltter == L_BRACKET. */ - else - return ILL_CHR; - } /* End get_esc_seq. */ - -/*****************************************************************************/ -/* Draws a box on the screen for user to enter the value he wishes to write. */ -/*****************************************************************************/ -static VOID make_box() - { - char str[MAX_STRING_SIZE]; - short row = BEG_BOX; - short col = BEG_BOX; - - strcpy(str, "***************************************"); - mv_cursor(&row,&col,str); - row+=2; - strcpy(str, "***************************************"); - row = END_BOX; - mv_cursor(&row,&col,str); - row--; - col = BOX_IN_COL; - mv_cursor(&row,&col,NO_CMD); - } - -/************************************************************************/ -/* Gets value from user input from screen. Echos user's input back. */ -/* A null in the first location in the array indicates no value was */ -/* entered. */ -/************************************************************************/ - -static VOID get_value(val_in) - char val_in[MAX_STRING_SIZE]; /* Array into which letters will be placed as they - are read in from screen. */ - { - char numb, *chr_ptr; /* Variable into which ltrs are read before putting - them into field_array. */ - VOID mv_cursor(); - - short row = BOX_IN_ROW; - short col = BEG_BOX; - int nmbr; - short ctr; - char prefix[40]; - char txt_str[MAX_STRING_SIZE]; - - blank_fill(val_in,MAX_STRING_SIZE); - strcpy(val_in, "* Enter value: *"); - mv_cursor(&row,&col,val_in); - col = 16; - blank_fill(val_in,MAX_STRING_SIZE); - mv_cursor(&row,&col,NO_CMD); - - /* Initialize pointer to first location in array. */ - - chr_ptr = val_in; - - /* Read input from screen until a return is entered. */ - nmbr = read(lopi_fd,&numb,1); - - while ((numb != RETURN) && (numb != CR) && (*chr_ptr != NULL )) - { - /* If value is legal enter it in value array. */ - - if (( isalpha(numb)) || (isdigit(numb)) || (numb == DOT) || (numb == MINUS )) - { - *chr_ptr = numb; - chr_ptr++; - mv_cursor(&row,&col,val_in); - nmbr = read(lopi_fd,&numb,1); - } /* End if isalpha */ - else if ((numb == DELETE) && (chr_ptr != val_in)) - { - chr_ptr--; - *chr_ptr = BLANK; - mv_cursor(&row,&col,val_in); - nmbr = read(lopi_fd,&numb,1); - } - else if ((numb != RETURN) || (numb != CR)) - { - nmbr = read(lopi_fd,&numb,1); - } - - } /* End while numb != return. */ - - *chr_ptr = NULL; - col = BEG_BOX; - - /* Erase the box and data. */ - - for (ctr = BEG_BOX; ctr <= END_BOX; ctr++) - { - row = ctr; - mv_cursor(&row,&col,NO_CMD); - ERASE_LINE; - } - } - -/**************************************************************************************/ -/* Takes the character array passed to it and fills it with blanks and terminates it */ -/* with a NULL. */ -/**************************************************************************************/ - -static VOID blank_fill(chr_array,chr_size) - char chr_array[MAX_LIN_LEN]; - short chr_size; - { - short c_ctr = 0; /* Index to array being filled. */ - - while(c_ctr < (chr_size - 1)) - chr_array[c_ctr++] = BLANK; - chr_array[chr_size -1] = NULL; - - } - -/****************************************************************************/ -/* Moves cursor to row and column passed to it. Prints a string after the */ -/* cursor if one is sent to it. */ -/****************************************************************************/ - - -static VOID mv_cursor(mrow,mcol,str) - short *mrow; - short *mcol; - char str[100]; /* String to be printed after cursor has a been - moved. */ - { - char command[140]; - - /* Create a string containing the proper VT220 commands - to move the cursor to the location desired. */ - - bzero(command,sizeof(command)); - sprintf(command,"[%d;%dH %s",*mrow,*mcol,str); - - /* Send command to the terminal. */ - - semTake(mon_sem); - - fdprintf(lopi_fd,"%c",ESC); - fdprintf(lopi_fd,"%s",command); - - semGive(mon_sem); - } - - - /****************************************************************************/ - /* Strips away blanks from the string to which it */ - /* points. Returns a pointer to the first non-blank character. */ - /****************************************************************************/ - - -static char *skipblanks(str) - char *str; - { - - while ( (*str == BLANK)) - str++; - - return (str); - } - - -/****************************************************************************/ -/* Reads in a line from a file and puts it in an array. */ -/* Strips off newline character. Terminates string with a NULL. */ -/* Returns the number of characters read in or EOF. */ -/****************************************************************************/ - - -static int fgetline(disp_ln,d_fp) - - FILE *d_fp; /* File pointer to the file being read in. */ - char disp_ln[MAX_LIN_LEN]; - { - int c; - char *lnptr; - - for (lnptr = disp_ln; lnptr - disp_ln < MAX_LIN_LEN - 1 && - (c = getc(d_fp)) != EOF && c != NEWLINE; lnptr++) - *lnptr = (char) c; - - *lnptr = NULL; - - if ( c == EOF) - return EOF; - else - return lnptr - disp_ln; - } - - -/****************************************************************************/ -/* Reads in the files listed in disp_files one by one. It builds a */ -/* structure called a window for each display file it reads in. It builds */ -/* linked lists of controls, monitors and texts. These lists will later be */ -/* used to display the dynamic information as it comes in. */ -/****************************************************************************/ - - - static VOID get_displays(disp_files,nfiles,disp_array) - - char *disp_files[FN_LEN]; /* Array for list of filenames to be selected by the user. */ - int nfiles; /* Number of files read in. */ - struct window_node *disp_array[MAX_DISP_NUM]; /* Array of windows available. */ - - { - FILE *disp_fp; - char *lptr,dline[MAX_LIN_LEN]; /* Array to hold the contents of a line from the - display file as it is read in. */ - struct mon_node *ctl_ptr; - int flg; /* Flag for EOF. */ - int disp_ctr; /* Counters. */ - for (disp_ctr = 0; disp_ctr < nfiles; disp_ctr++) - { - if ((disp_fp = fopen(disp_files[disp_ctr], "r")) == NULL){ - printf("Can't open %s \n", disp_files[disp_ctr]); - disp_array[disp_ctr] = NULL; - } - else - { - disp_array[disp_ctr] = win_alloc(); - disp_array[disp_ctr]->c_head = NULL; - disp_array[disp_ctr]->m_head = NULL; - disp_array[disp_ctr]->t_head = NULL; - flg = 0; - do - { - flg = fgetline(dline,disp_fp); - lptr = skipblanks(dline); /* Skip any leading blanks if any. */ - switch (*lptr) - { - case 'c': - add_ctl(disp_array,disp_ctr,lptr); - break; - - case 'm': - add_mon(disp_array,disp_ctr,lptr); - break; - - case 't': - add_txt(disp_array,disp_ctr,lptr); - break; - - default: - break; - } /* End switch. */ - bzero(dline,sizeof(dline)); - - } while(flg != EOF); - - status = fclose(disp_fp); - - } /* End else. */ - - } /* End for.*/ - - /* it(DEBUG) - read_disp_lst(wind_array,n_lines); */ - - } /* End get_displays */ - - - -/****************************************************************************/ -/* Allocates memory for a monitor. */ -/****************************************************************************/ - -static struct mon_node *mon_alloc() - { - struct mon_node *monptr; - - if (( monptr = (struct mon_node *)malloc(sizeof(struct mon_node))) == NULL) - { - logMsg("Insufficient memory in mon_alloc.\n "); - close(err_fd); - abort(); - return NULL; - } - else - return monptr; - } - -/****************************************************************************/ -/* Allocates memory for a text label. */ -/****************************************************************************/ - -static struct txt_node *txt_alloc() - { - struct txt_node *txtptr; - - if (( txtptr = (struct txt_node *)malloc(sizeof(struct txt_node))) == NULL) - { - logMsg("Insufficient memory in tx_alloc.\n "); - close(err_fd); - abort(); - return NULL; - } - else - return txtptr; - } - -/****************************************************************************/ -/* Allocates memory for an event node. */ -/****************************************************************************/ - -static struct ev_node *ev_alloc() - { - struct ev_node *evptr; - - if (( evptr = (struct ev_node *)malloc(sizeof(struct ev_node))) == NULL) - { - logMsg("Insufficient memory in ev_alloc.\n "); - close(err_fd); - abort(); - return NULL; - } - else - return evptr; - } - -/****************************************************************************/ -/* Allocates memory for an exception node. */ -/****************************************************************************/ - -static struct except_node *except_alloc() - { - struct except_node *ex_ptr; - - if (( ex_ptr = (struct except_node *)malloc(sizeof(struct except_node))) == NULL) - { - logMsg("Insufficient memory in except_alloc.\n "); - close(err_fd); - abort(); - return NULL; - } - else - return ex_ptr; - } - -/****************************************************************************/ -/* Allocates memory for a window structure. */ -/****************************************************************************/ - -static struct window_node *win_alloc() - { - struct window_node *winptr; - - if (( winptr = (struct window_node *)malloc(sizeof(struct window_node))) == NULL) - { - logMsg("Insufficient memory in win_alloc.\n "); - close(err_fd); - abort(); - return NULL; - } - else - return winptr; - } - -/*****************************************************************************/ -/* This function attaches a control node to the linked list headed by */ -/* win_array->ctl. It returns the pointer to the head of the list which now */ -/* points to the new node. */ -/*****************************************************************************/ - -static void add_ctl(win_array,win_ctr,c_line) - struct window_node *win_array[MAX_DISP_NUM]; - short win_ctr; /* Counters. */ - char *c_line; - { - struct mon_node *c_ptr,*new_ptr; - char chan_nm[CHAN_NM_SIZE],*chan_ptr; /* Array to hold channel name as it is parsed - from line and a pointer to it. */ - register short l_crn_row = 0,l_crn_col = 0; - register short r_crn_row = 0,r_crn_col = 0; - short r_loc_flg = OFF; /* Flag which is set when location is found in element file. */ - short c_loc_flg = OFF; /* Flag which is set when location is found in element file. */ - - chan_ptr = chan_nm; - bzero(chan_nm,sizeof(chan_nm)); - - *chan_ptr = NULL; - - /* Move past any characters at beginning of display element. */ - - while (isalpha(*c_line)) - c_line++; - c_line = skip_to_digit(c_line); - - /* If there is no channel location, omit the channel from the linked list. */ - - if ((*c_line) && (isdigit(*c_line))) - { - l_crn_row = to_short(c_line); - while(isdigit(*c_line)) - c_line++; - r_loc_flg = ON; - c_line = skip_to_digit(c_line); - - if (*c_line) - { - l_crn_col = to_short(c_line); - c_loc_flg = ON; - while (isdigit(*c_line) ) - c_line++; - } - } - - /* Advance pointer past the left corner location in element array. */ - - while ((*c_line)&& (isdigit(*c_line))) - c_line++; - - /* Advance pointer to next digit or alpha character. */ - - while ((*c_line) && (!isdigit(*c_line)) && (!isalpha(*c_line))) - c_line ++; - - /* Return a pointer to the next non-blank character in the element array. */ - - if ((*c_line) && (isdigit(*c_line))) - { - r_crn_row = to_short(c_line); - while(isdigit(*c_line)) - c_line++; - c_line = skip_to_digit(c_line); - r_crn_col = to_short(c_line); - while ((!isalpha(*c_line)) && (*c_line)) - c_line++; - } - - /* If there is no channel name give appropriate error message. */ - - - if (!(*c_line)) - printf("No channel name for control. Channel omitted.\n"); - - /* Otherwise copy channel name to the channel name array. */ - if (isalpha(*c_line)) - { - while( (isalpha(*c_line)) || (isdigit(*c_line)) || (*c_line == UNDERSC) ||(*c_line == COLON) - || (*c_line == DOT)) - *chan_ptr++ = *c_line++; - *chan_ptr = NULL; - } - - /* Allocate and initialize header for doubly linked list. Initialize header's - l_crn_row field to -1. */ - - if (win_array[win_ctr]->c_head == NULL) - { - win_array[win_ctr]->c_head = mon_alloc(); - win_array[win_ctr]->c_head->next = win_array[win_ctr]->c_head; - win_array[win_ctr]->c_head->prev = win_array[win_ctr]->c_head; - strcpy(win_array[win_ctr]->c_head->chan,"head"); - win_array[win_ctr]->c_head->l_crn_row = -1; - c_ptr = win_array[win_ctr]->c_head; - } - - - /* If the channel has a name and locations for the left corner and the right - corner, add the node immediately after the head of the list. */ - - c_ptr = win_array[win_ctr]->c_head->next; - - if ((*chan_nm) && (r_loc_flg) && (c_loc_flg)) - { - while((c_ptr->next->l_crn_row != -1) && (c_ptr->l_crn_row < l_crn_row)) - { - c_ptr = c_ptr->next; - } - c_ptr = win_array[win_ctr]->c_head->next; - while((c_ptr->next->l_crn_row != -1) && (c_ptr->l_crn_row == l_crn_row) && - (c_ptr->l_crn_col < l_crn_col)) - { - c_ptr = c_ptr->next; - } - new_ptr = mon_alloc(); - new_ptr->next= c_ptr->next; /* Set pointer to the head to point at the new node. */ - new_ptr->prev = c_ptr; - c_ptr->next = new_ptr; - new_ptr->next->prev = new_ptr; - strcpy(new_ptr->chan,chan_nm); - new_ptr->l_crn_row = l_crn_row; - new_ptr->l_crn_col = l_crn_col; - new_ptr->r_crn_row = r_crn_row; - new_ptr->r_crn_col = r_crn_col; - } - - return; - - } - -/************************************************************************************/ -/* This function attaches a monitor node to the linked list headed by win_array-> */ -/* mon. It returns the pointer to the head of the list which now points to the new */ -/* node. */ -/************************************************************************************/ - -static VOID add_mon(win_array,win_ctr,m_line) - struct window_node *win_array[MAX_DISP_NUM]; - short win_ctr; /* Counters. */ - char *m_line; - { - struct mon_node *node_ptr; - char chan_nm[CHAN_NM_SIZE],*chan_ptr; /* Array to hold channel name as it is parsed - from line and a pointer to it. */ - register short l_crn_row = 0,l_crn_col = 0; - short r_loc_flg = OFF; /* Flag which is set when location is found in element file. */ - short c_loc_flg = OFF; /* Flag which is set when location is found in element file. */ - - chan_ptr = chan_nm; - bzero(chan_nm,sizeof(chan_nm)); - - *chan_ptr = NULL; - - /* Move past any characters at beginning of display element. */ - - while (isalpha(*m_line)) - m_line++; - - m_line = skip_to_digit(m_line); - - /* If there is no channel location, omit the channel from the linked list. */ - - - if ((*m_line) && (isdigit(*m_line))) - { - l_crn_row = to_short(m_line); - r_loc_flg = ON; - /* Move past left row number. */ - - while(isdigit(*m_line)) - m_line++; - - /* Move to column location. */ - - m_line = skip_to_digit(m_line); - - if ((*m_line) && (isdigit(*m_line))) - { - l_crn_col = to_short(m_line); - c_loc_flg = ON; - while (isdigit (*m_line)) - m_line++; - } - - } - - while ( (*m_line) && (!isalpha(*m_line))) - m_line++; - - if (isalpha(*m_line)) - { - while( (isalpha(*m_line)) || (isdigit(*m_line)) || (*m_line == UNDERSC) || (*m_line == COLON)) - *chan_ptr++ = *m_line++; - *chan_ptr = NULL; - } - chan_ptr = chan_nm; - - /* Enter channel name and location for monitor in monitor linked list. */ - - if (win_array[win_ctr]->m_head == NULL) - { - if ((*chan_nm) && (c_loc_flg) && (r_loc_flg)) - { - win_array[win_ctr]->m_head = mon_alloc(); - win_array[win_ctr]->m_head->next = NULL; - if (*chan_nm) - strcpy(win_array[win_ctr]->m_head->chan,chan_nm); - win_array[win_ctr]->m_head->l_crn_row = l_crn_row; - win_array[win_ctr]->m_head->l_crn_col = l_crn_col; - } - else if (!(*chan_nm)) - printf("No channel name for monitor. Channel omitted.\n"); - else if ((! (c_loc_flg)) || (! (r_loc_flg)) ) - printf("Incomplete location information for display.\n"); - } - - - /* Otherwise, add the node immediately after the head of the list. */ - - else - { - if ((*chan_nm) && (c_loc_flg) && (r_loc_flg)) - { - node_ptr = mon_alloc(); /* Set the new node's next pointer to point at - the head of the list. */ - node_ptr->next= win_array[win_ctr]->m_head; /* Set pointer to the head to point at the new node. */ - win_array[win_ctr]->m_head = node_ptr; - if (*chan_nm) - strcpy(win_array[win_ctr]->m_head->chan,chan_nm); - win_array[win_ctr]->m_head->l_crn_row = l_crn_row; - win_array[win_ctr]->m_head->l_crn_col = l_crn_col; - } - else if (!(*chan_nm)) - printf("No channel name for monitor. Channel omitted.\n"); - else if ((! (c_loc_flg)) || (! (r_loc_flg)) ) - printf("Incomplete location information for display. Channel omitted.\n"); - } - return; - } - -/************************************************************************************/ -/* This function attaches a text node to the linked list headed by win_array-> */ -/* txt. It returns the pointer to the head of the list which now points to the new */ -/* node. */ -/************************************************************************************/ - -static VOID add_txt(win_array,win_ctr,t_line) - struct window_node *win_array[MAX_DISP_NUM]; - short win_ctr; /* Counters. */ - char *t_line; - { - struct txt_node *node_ptr; - char txt_str[MAX_LIN_LEN],*txt_ptr; /* Array to hold text string as it is parsed - from line and a pointer to it. */ - - register short l_crn_row = 0,l_crn_col = 0; - short r_loc_flg = OFF; /* Flag which is set when location is found in element file. */ - short c_loc_flg = OFF; /* Flag which is set when location is found in element file. */ - - txt_ptr = txt_str; - bzero(txt_str,sizeof(txt_str)); - - *txt_ptr = NULL; - - /* Move past any characters at beginning of display element. */ - - while (isalpha(*t_line)) - t_line++; - - /* Move to next digit in display element. */ - - t_line = skip_to_digit(t_line); - - - /* If there is no text location, omit the string from the linked list. */ - - if (*t_line) - { - l_crn_row = to_short(t_line); - r_loc_flg = ON; - while (isdigit(*t_line)) - t_line++; - t_line = skip_to_digit(t_line); - - if ((*t_line) && (isdigit (*t_line))) - { - l_crn_col = to_short(t_line); - c_loc_flg = ON; - - /* Skip past digit. */ - - while (isdigit(*t_line)) - t_line++; - - } - - } - - - /* Skip digits and blanks and illegal characters then read in text string. */ - - while ( (*t_line) && (!isalpha(*t_line)) && (!isdigit(*t_line)) && (*t_line != UNDERSC) - && (*t_line != COLON) && (*t_line != ASTER)) - t_line++; - - /* Text string must begin with an alphanumeric character, and underscore,a colon, or an - asterisk. After the first character blanks will be legal for text strings. */ - - if ((isalpha(*t_line)) || (isdigit(*t_line)) || (*t_line == UNDERSC) || (*t_line == COLON) || - (*t_line == ASTER)) - { - while( (isalpha(*t_line)) || (isdigit(*t_line)) || (*t_line == UNDERSC) || (*t_line == BLANK) - || (*t_line == COLON) || (*t_line == ASTER) ||(*t_line == DOT)) - *txt_ptr++ = *t_line++; - *txt_ptr = NULL; - } - - if (win_array[win_ctr]->t_head == NULL) - { - if ((*txt_str) && (r_loc_flg) && (c_loc_flg)) - { - win_array[win_ctr]->t_head = txt_alloc(); - win_array[win_ctr]->t_head->next = NULL; - if (*txt_str) - strcpy(win_array[win_ctr]->t_head->txt_str,txt_str); - win_array[win_ctr]->t_head->l_crn_row = l_crn_row; - win_array[win_ctr]->t_head->l_crn_col = l_crn_col; - } - else if (! (txt_str)) - printf("No text string. Text node omitted.\n"); - else if ((!(r_loc_flg)) || (! (c_loc_flg))) - printf("Incomplete location information. Text node omitted.\n"); - } - - - /* Otherwise, add the node immediately after the head of the list. */ - - else - { - if ((*txt_str) && (r_loc_flg) && (c_loc_flg)) - { - node_ptr = txt_alloc(); /* Set the new node's next pointer to point at - the head of the list. */ - node_ptr->next= win_array[win_ctr]->t_head; /* Set pointer to the head to point at the new node. */ - win_array[win_ctr]->t_head = node_ptr; - if (*txt_str) - strcpy(win_array[win_ctr]->t_head->txt_str,txt_str); - win_array[win_ctr]->t_head->l_crn_row = l_crn_row; - win_array[win_ctr]->t_head->l_crn_col = l_crn_col; - } - else if (! (txt_str)) - printf("No text string. Text node omitted.\n"); - else if ((!(r_loc_flg)) || (! (c_loc_flg))) - printf("Incomplete location information. Text node omitted.\n"); - } - return; - } - -/************************************************************************************/ -/* This function throws away all characters and returns a pointer */ -/* to the first digit. */ -/************************************************************************************/ - -static char *skip_to_digit(pstr) - char *pstr; - { - - while (*pstr) - { - if( (isdigit(*pstr)) ) - return (pstr); - else if (pstr == NULL) - { - return (NULL); - } - else - pstr++; - } - - return (NULL); - } - -/************************************************************************************/ -/* Get a number from display element line, convert it to register short. */ -/* This function was stolen from Bob Dalesio with a slight modification. */ -/************************************************************************************/ - -static int to_short(pstr) - char *pstr; - { - short num; - - num = 0; - while(isdigit(*pstr)) - { - num = (num * 10) + (*pstr -'0'); - pstr++; - } - return num; - } - - -/*************************************************************************************/ -/* This subroutine will be used for debugging only. It reads out the linked list of */ -/* control nodes. It is best to comment out print_menu when using this. */ -/*************************************************************************************/ - -static VOID read_disp_lst(wnd_array,nfiles) -struct window_node *wnd_array[MAX_DISP_NUM]; -int nfiles; -{ - struct mon_node *ctl_ptr; - struct mon_node *mon_ptr; - struct txt_node *txt_ptr; - short lopi_i,lopi_j; /* Counters. */ - - lopi_j = 1; - for (lopi_i = 0; lopi_i < nfiles; lopi_i++) - { - if (wind_array[lopi_i] != NULL) - { - ctl_ptr = wnd_array[lopi_i]->c_head; - if ((ctl_ptr == NULL) || (ctl_ptr->next->l_crn_row == LIST_END )) - printf("Ctl list for display %d is empty.\n",lopi_i); - else - { - ctl_ptr = ctl_ptr->next; - while (ctl_ptr->l_crn_row != LIST_END) - { - printf("Display %d: Node %d\n",lopi_i,lopi_j); - printf("wnd_array[%d]->c_head->chan = %s \n",lopi_i,ctl_ptr->chan); - printf("wnd_array[%d]->c_head->l_crn_row = %d \n",lopi_i,ctl_ptr->l_crn_row); - printf("wnd_array[%d]->c_head->l_crn_col = %d \n",lopi_i,ctl_ptr->l_crn_col); - lopi_j++; - ctl_ptr = ctl_ptr->next; - } - } - - lopi_j = 1; - mon_ptr = wnd_array[lopi_i]->m_head; - if (mon_ptr == NULL) - printf("Mon list for display %d is empty.\n",lopi_i); - else - { - while (mon_ptr != NULL) - { - printf("Display %d: Node %d\n",lopi_i,lopi_j); - printf("wnd_array[%d]->m_head->chan = %s \n",lopi_i,mon_ptr->chan); - printf("wnd_array[%d]->m_head->l_crn_row = %d \n",lopi_i,mon_ptr->l_crn_row); - printf("wnd_array[%d]->m_head->l_crn_col = %d \n",lopi_i,mon_ptr->l_crn_col); - lopi_j++; - mon_ptr = mon_ptr->next; - } - } - lopi_j = 1; - txt_ptr = wnd_array[lopi_i]->t_head; - if (txt_ptr == NULL) - printf("Txt list for display %d is empty.\n",lopi_i); - else - { - while (txt_ptr != NULL) - { - printf("Display %d: Node %d\n",lopi_i,lopi_j); - printf("wnd_array[%d]->t_head->txt_str = %s \n",lopi_i,txt_ptr->txt_str); - printf("wnd_array[%d]->t_head->l_crn_row = %d \n",lopi_i,txt_ptr->l_crn_row); - printf("wnd_array[%d]->t_head->l_crn_col = %d \n",lopi_i,txt_ptr->l_crn_col); - lopi_j++; - txt_ptr = txt_ptr->next; - } - } - } - lopi_j = 1; - } - return; -} - - -/***************************************************************************************/ -/* This function puts text specified by the user in the display file on the screen. */ -/***************************************************************************************/ - -static VOID display_text(disp_array,selected) - struct window_node *disp_array[MAX_DISP_NUM]; - short selected; - { - short mrow,mcol; - struct txt_node *txt_ptr; - char txt_str[MAX_LIN_LEN]; - mrow = 0; - mcol = 0; - mv_cursor(&mrow,&mcol,NO_CMD); - txt_ptr = disp_array[selected]->t_head; - - while (txt_ptr != NULL) - { - mrow = txt_ptr->l_crn_row; - mcol = txt_ptr->l_crn_col; - strcpy(txt_str,txt_ptr->txt_str); - mv_cursor(&mrow,&mcol,txt_str); - txt_ptr = txt_ptr->next; - } - - return; - } - -/***************************************************************************************/ -/* Displays a file chosen by the user from the display file which was created when */ -/* the program initialized. Also calls put_value() to write to controls if the user */ -/* selects and F7. */ -/***************************************************************************************/ - -static VOID display_file(disp_array,selected,screen_up,data_num,pdata_flg,k_buff,val_in) - struct window_node *disp_array[MAX_DISP_NUM]; - short selected; - short *screen_up; - short *data_num; /* Flag indicating that there is data waiting to - be read from the input buffer. */ - short *pdata_flg; /* Flag indicating that a monitor has brought in new data. */ - char k_buff[BUFF_SIZE]; /* Buffer for characters entered. */ - char val_in[MAX_STRING_SIZE]; - { - char *w_ptr; /* Pointer to next available space for writing. */ - struct mon_node *c_ptr = NULL; - struct mon_node *m_ptr = NULL; - struct txt_node *t_ptr = NULL; - char txt_str[MAX_LIN_LEN]; - char prefix[MAX_LIN_LEN]; - int nmbr; - short krow,kcol; /* Variables keeping track of where cursor is at all times. */ - short trow,tcol; /* Variables keeping track of where cursor is at all times. */ - short init; /* Flag to indicate display monitors whether to initialize monitors or - not. */ - - - /* Initialize buffers into which channel names and values are - written for a put. */ - pdata_flg = OFF; - k_buff[BUFF_SIZE - 1] = NULL; - w_ptr = k_buff; - *data_num = 0; - num_times = 0; - krow = 0; /*Krow and kcol store cursor position. */ - kcol = 0; - - trow = 0; /* trow and tcol store cursor position for diagnostic messages only. */ - trow = 0; - - /* If a non existant screen has been selected, print error message. */ - - if ( disp_array[selected] == NULL ) - { - trow++; - tcol = 0; - mv_cursor(&trow,&tcol,"Found no display file for this display."); - trow++; - taskDelay(30); - selected = NOTHING_SELECTED; - *screen_up = OFF; - w_ptr = k_buff; - (*data_num) = 0; - } - else - { - trow++; - tcol = 0; - m_ptr = disp_array[selected]->m_head; - c_ptr = disp_array[selected]->c_head; - t_ptr = disp_array[selected]->t_head; - /* If a screen with no data has been selected, exit. */ - - if ((c_ptr == NULL) && (m_ptr == NULL) - && ( t_ptr == NULL)) - { - trow++; - tcol = 0; - mv_cursor(&trow,&tcol,"Found nothing in this file."); - taskDelay(60); - selected = NOTHING_SELECTED; - *screen_up = OFF; - w_ptr = k_buff; - (*data_num) = 0; - } - else - { - /* Otherwise put up text and initialize the monitors. */ - if(t_ptr != NULL); - display_text(disp_array,selected); - init = ON; - if ((m_ptr != NULL) || (c_ptr != NULL)) - { - display_monitors(disp_array,selected,screen_up,pdata_flg,&init,except_ptr); - } - init = OFF; - - /* Place cursor on position of first control . */ - - if ((c_ptr != NULL) && (c_ptr->next->l_crn_row != LIST_END)) - { - c_ptr = c_ptr->next; - krow = c_ptr->l_crn_row; - kcol = c_ptr->l_crn_col; - mv_cursor(&krow,&kcol,NO_CMD); - } - } - } - - while (*screen_up == ON) - { - - /* If there is something in the buffer it will lopi consumed - until it is used up. */ - - - while (*data_num > 0) - { - switch (*w_ptr) - { - case F6: /* F6 will cause an exit. Everything else in buffer - will be lost. */ - semTake(key_sem); - w_ptr = k_buff; - *data_num = 0; - *screen_up = OFF; - semGive(key_sem); - break; - case F7: - display_text(disp_array,selected); - semTake(key_sem); - w_ptr = k_buff; - *data_num = 0; - semGive(key_sem); - trow = BEG_BOX; - tcol = BEG_BOX; - if(c_ptr != NULL) - put_value(c_ptr,val_in); - break; - case U_ARROW: - if (c_ptr != NULL) - { - if (c_ptr->prev->l_crn_row != LIST_END) - { - c_ptr = c_ptr->prev; - krow = c_ptr->l_crn_row; - kcol = c_ptr->l_crn_col; - mv_cursor(&krow,&kcol,NO_CMD); - } - else - { - c_ptr = c_ptr->prev->prev; - krow = c_ptr->l_crn_row; - kcol = c_ptr->l_crn_col; - mv_cursor(&krow,&kcol,NO_CMD); - } - w_ptr++; - semTake(key_sem); - (*data_num)--; - if ((*w_ptr) == NULL) - w_ptr = k_buff; - semGive(key_sem); - } - break; - case D_ARROW: - if (c_ptr != NULL) - { - if (c_ptr->next->l_crn_row != LIST_END) - { - c_ptr = c_ptr->next; - krow = c_ptr->l_crn_row; - kcol = c_ptr->l_crn_col; - mv_cursor(&krow,&kcol,NO_CMD); - } - else - { - c_ptr = c_ptr->next->next; - krow = c_ptr->l_crn_row; - kcol = c_ptr->l_crn_col; - mv_cursor(&krow,&kcol,NO_CMD); - } - semTake(key_sem); - w_ptr++; - (*data_num)--; - if ((*w_ptr) == NULL) - w_ptr = k_buff; - semGive(key_sem); - } - break; - case RETURN: - semTake(key_sem); - (*data_num) = 0; - w_ptr = k_buff; - semGive(key_sem); - break; - default: - w_ptr++; - semTake(key_sem); - if ((*w_ptr) == NULL) - w_ptr = k_buff; - semGive(key_sem); - break; - } /* End switch. */ - - - } /* End while data_num > 0 */ - - if (*pdata_flg) - { - display_monitors(disp_array,selected,screen_up,pdata_flg,&init,except_ptr); - taskDelay(5); - mv_cursor(&krow,&kcol,NO_CMD); - } - - - } /* end while screen up. */ - - if (disp_array[selected] != NULL) - { - stop_monitors(disp_array,selected); - } - - return; -} - -/********************************************************************************/ -/* VOID display_monitors */ -/* Uses a linked list of monitors and a doubly linked circular list of */ -/* controls. Controls and monitors are treated the same as far as this */ -/* subroutine is concerned. That is both are monitored. */ -/********************************************************************************/ - -static VOID display_monitors(disp_array,m_select,screen,pdata_flg,init,except_ptr) - struct window_node *disp_array[MAX_DISP_NUM]; - short m_select; /* Pointer to number of screen selected. */ - short *screen; /* Pointer to variable which tells when to begin desplay. */ - short *pdata_flg; /* Flag to indicate that new data had been received. */ - short *init; /* Flag to indicate that monitors need to be initialized. */ - struct except_node *except_ptr; - { - short mon_row,mon_col; /* Local variable used to move cursor to position where update is - required. After update, cursor will always be returned to the - esition where keyboard entry cursor is located. */ - short trow = 1;short tcol = 0; - int status; - chtype type = TYPENOTCONN; - char txt_str[120]; - char prefix[80]; - struct mon_node *mon_ptr, *ctl_ptr; - - mon_row = 0; - mon_col = 0; - mon_ptr = disp_array[m_select]->m_head; - - if (*init) - { - SEVCHK(ca_task_initialize(),"Unable to initialize."); - - status = ca_add_exception_event(lopi_exception_handler,except_ptr); - if (status != ECA_NORMAL) - logMsg(" Exception handler error message:%d\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - except_ptr->flg = NO_NEW_DATA; - bzero(except_ptr->msg,(sizeof(except_ptr->msg))); - - - ctl_ptr = disp_array[m_select]->c_head; - if ((ctl_ptr != NULL) && (ctl_ptr->next->l_crn_row != LIST_END)){ - ctl_ptr = ctl_ptr->next; - while (ctl_ptr->l_crn_row != LIST_END) - { - ctl_ptr->ev_ptr = ev_alloc(); - ctl_ptr->ev_ptr->data_flg = NO_NEW_DATA; - ctl_ptr->conn_flg = CA_OP_CONN_DOWN; - mon_row = ctl_ptr->l_crn_row; - mon_col = ctl_ptr->l_crn_col; - ctl_ptr->prev_size = 4; - - /* Put up a row of x's where monitor is to be displayed. */ - - ESCAPE - REVERSE_VIDEO - strcpy(ctl_ptr->ev_ptr->str," "); - mv_cursor(&mon_row,&mon_col,ctl_ptr->ev_ptr->str); - ESCAPE - ATR_OFF - status = ca_build_and_connect(ctl_ptr->chan,TYPENOTCONN,0,&ctl_ptr->chan_id, - NULL,lopi_conn_handler,ctl_ptr); - if (status != ECA_NORMAL) - logMsg(" ca_build_and_connect:%d\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - ctl_ptr = ctl_ptr->next; - } - } - - - while (mon_ptr != NULL) - { - mon_ptr->ev_ptr = ev_alloc(); - mon_ptr->ev_ptr->data_flg = NO_NEW_DATA; - mon_ptr->conn_flg = CA_OP_CONN_DOWN; - mon_row = mon_ptr->l_crn_row; - mon_col = mon_ptr->l_crn_col; - mon_ptr->prev_size = 4; - - /* Put up a row of x's where monitor is to be displayed. */ - - ESCAPE - REVERSE_VIDEO - strcpy(mon_ptr->ev_ptr->str," "); - mv_cursor(&mon_row,&mon_col,mon_ptr->ev_ptr->str); - ESCAPE - ATR_OFF - status = ca_build_and_connect(mon_ptr->chan,TYPENOTCONN,0,&mon_ptr->chan_id, - NULL,lopi_conn_handler,mon_ptr); - if (status != ECA_NORMAL) - logMsg(" ca_build_and_connect:%d\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - mon_ptr = mon_ptr->next; - } - - - mon_ptr = disp_array[m_select]->m_head; - - while (mon_ptr != NULL) - { - status = ca_add_event(DBR_STS_STRING,mon_ptr->chan_id,lopi_ev_handler,mon_ptr->ev_ptr,NULL); - if (status != ECA_NORMAL) - logMsg("Message:%d\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - type = ca_field_type(mon_ptr->chan_id); - - if (DEBUG) - logMsg("Added event for %s,status = %d,type = %d\n",mon_ptr->chan,status,type); - - /* If channel is found display data if channel is up. Display error messae if channel - is down. */ - - - if ((type = (ca_field_type(mon_ptr->chan_id))) != TYPENOTCONN) - - - /* If channel is connected display error message if it is down. - Print data if it is up. */ - { - if (mon_ptr->conn_flg == CA_OP_CONN_UP) - { - mon_row = mon_ptr->l_crn_row; - mon_col = mon_ptr->l_crn_col; - if (mon_ptr->prev_size > (strlen(mon_ptr->ev_ptr->str))) - { - blank_fill(txt_str,mon_ptr->prev_size); - mv_cursor(&mon_row,&mon_col,txt_str); - } - mon_ptr->prev_size = strlen(mon_ptr->ev_ptr->str); - mv_cursor(&mon_row,&mon_col,mon_ptr->ev_ptr->str); - } - else if (mon_ptr->conn_flg == CA_OP_CONN_DOWN) - { - ESCAPE - REVERSE_VIDEO - strcpy(txt_str,"CHAN DOWN"); - mv_cursor(&mon_row,&mon_col,txt_str); - ESCAPE - ATR_OFF - } - else - { - ESCAPE - REVERSE_VIDEO - strcpy(txt_str,"UNDEF"); - mv_cursor(&mon_row,&mon_col,txt_str); - ESCAPE - ATR_OFF - } - } - - mon_ptr = mon_ptr->next; - - } - - - if((ctl_ptr != NULL) && (disp_array[m_select]->c_head->next->l_crn_row != LIST_END)) - { - ctl_ptr = disp_array[m_select]->c_head->next; - - while (ctl_ptr->l_crn_row != LIST_END) - { - status = ca_add_event(DBR_STS_STRING,ctl_ptr->chan_id,lopi_ev_handler, ctl_ptr->ev_ptr,NULL); - if (status != ECA_NORMAL) - logMsg("Message:%s\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - type = ca_field_type(ctl_ptr->chan_id); - if (DEBUG) - logMsg("Added event for %s,status = %d,type = %d\n",ctl_ptr->chan,status,type); - - /* If channel is connected, display data if channel is up. Display error message if - channel is down. */ - - - if ((type = (ca_field_type(ctl_ptr->chan_id))) != TYPENOTCONN) - { - if (ctl_ptr->conn_flg == CA_OP_CONN_UP) - { - mon_row = ctl_ptr->l_crn_row; - mon_col = ctl_ptr->l_crn_col; - if (ctl_ptr->prev_size > strlen(ctl_ptr->ev_ptr->str)) - { - blank_fill(txt_str,ctl_ptr->prev_size); - mv_cursor(&mon_row,&mon_col,txt_str); - } - mv_cursor(&mon_row,&mon_col,ctl_ptr->ev_ptr->str); - ctl_ptr->prev_size = strlen(ctl_ptr->ev_ptr->str); - } - else if (ctl_ptr->conn_flg == CA_OP_CONN_DOWN) - { - ESCAPE - REVERSE_VIDEO - strcpy(txt_str,"CHAN DOWN"); - mv_cursor(&mon_row,&mon_col,txt_str); - ESCAPE - ATR_OFF - } - else - { - ESCAPE - REVERSE_VIDEO - strcpy(txt_str,"UNDEF"); - mv_cursor(&mon_row,&mon_col,txt_str); - ESCAPE - ATR_OFF - } - } /* If type is not TYPENOTCONN. */ - - /* If channel was never connected, display appropriate message. */ - - - ctl_ptr = ctl_ptr->next; - } /* End while ctl_ptr not equal to LIST END */ - - } /* End if ctl_ptr != NULL etc. */ - - - status = ca_flush_io(); - SEVCHK(status,NULL); - - if (except_ptr->flg) - { - lopi_signal(except_ptr->status,except_ptr->msg); - if (status != ECA_NORMAL) - logMsg("Status abnormal: %d\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - else - logMsg("Normal status:%d\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - except_ptr->flg = NO_NEW_DATA; - } - - } /* End if init */ - else - { - mon_ptr = disp_array[m_select]->m_head; - while (mon_ptr != NULL) - { - if ((mon_ptr->ev_ptr->data_flg) && (mon_ptr->conn_flg == CA_OP_CONN_UP)) - { - mon_row = mon_ptr->l_crn_row; - mon_col = mon_ptr->l_crn_col; - mon_ptr->ev_ptr->data_flg = NO_NEW_DATA; - if (mon_ptr->prev_size > strlen(mon_ptr->ev_ptr->str)) - { - blank_fill(txt_str,mon_ptr->prev_size); - mv_cursor(&mon_row,&mon_col,txt_str); - } - mon_ptr->prev_size = strlen(mon_ptr->ev_ptr->str + 2); - mv_cursor(&mon_row,&mon_col,mon_ptr->ev_ptr->str); - mon_ptr = mon_ptr->next; - } - else if (mon_ptr->conn_flg == CA_OP_CONN_DOWN) - { - mon_row = mon_ptr->l_crn_row; - mon_col = mon_ptr->l_crn_col; - ESCAPE - REVERSE_VIDEO - strcpy(txt_str,"CHAN DOWN"); - mv_cursor(&mon_row,&mon_col,txt_str); - ESCAPE - ATR_OFF - mon_ptr->prev_size = 10; - mon_ptr = mon_ptr->next; - } - else - mon_ptr = mon_ptr->next; - - } - ctl_ptr = disp_array[m_select]->c_head; - - if ((ctl_ptr != NULL) && (disp_array[m_select]->c_head->next->l_crn_row != LIST_END)) - { - ctl_ptr = disp_array[m_select]->c_head->next; - - while (ctl_ptr->l_crn_row != LIST_END) - { - if ((ctl_ptr->ev_ptr->data_flg) && (ctl_ptr->conn_flg == CA_OP_CONN_UP)) - { - mon_row = ctl_ptr->l_crn_row; - mon_col = ctl_ptr->l_crn_col; - ctl_ptr->ev_ptr->data_flg = NO_NEW_DATA; - if (ctl_ptr->prev_size > strlen(ctl_ptr->ev_ptr->str)) - { - blank_fill(txt_str,ctl_ptr->prev_size ); - mv_cursor(&mon_row,&mon_col,txt_str); - } - ctl_ptr->prev_size =(strlen(ctl_ptr->ev_ptr->str)) + 2; - mv_cursor(&mon_row,&mon_col,ctl_ptr->ev_ptr->str); - ctl_ptr = ctl_ptr->next; - } - else if (ctl_ptr->conn_flg == CA_OP_CONN_DOWN) - { - mon_row = ctl_ptr->l_crn_row; - mon_col = ctl_ptr->l_crn_col; - ESCAPE - REVERSE_VIDEO - strcpy(txt_str,"CHAN DOWN"); - mv_cursor(&mon_row,&mon_col,txt_str); - ESCAPE - ATR_OFF - ctl_ptr->prev_size = 10; - ctl_ptr = ctl_ptr->next; - } - else - ctl_ptr = ctl_ptr->next; - } /* End while ctl_ptr != LIST_END. */ - } /* End if ctl_ptr != NULL etc. */ - - semTake(mon_sem); - *pdata_flg = NO_NEW_DATA ; - semGive(mon_sem); - - if (except_ptr->flg) - { - lopi_signal(except_ptr->status,except_ptr->msg); - mon_col++; - if (status != ECA_NORMAL) - logMsg("Status abnormal: %d\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - else - logMsg("Normal status:%d\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - except_ptr->flg = NO_NEW_DATA; - } - - } /* End else */ - } - -/*************************************************************************************/ -/* VOID stop_monitors */ -/*************************************************************************************/ -static VOID stop_monitors(disp_array,m_select) - struct window_node *disp_array[MAX_DISP_NUM]; - short m_select; /* Pointer to number of screen selected. */ - { - struct mon_node *mon_ptr, *ctl_ptr; - - - - /* Free channel access resources. */ - - mon_ptr = disp_array[m_select]->m_head; - semTake(mon_sem); - - while (mon_ptr != NULL) - { - ca_clear_channel(mon_ptr->chan_id); - mon_ptr = mon_ptr->next; - } - - ctl_ptr = disp_array[m_select]->c_head; - - if ((ctl_ptr != NULL) && (disp_array[m_select]->c_head->next->l_crn_row != LIST_END)) - { - ctl_ptr = disp_array[m_select]->c_head->next; - while (ctl_ptr->l_crn_row != LIST_END) - { - ca_clear_channel(ctl_ptr->chan_id); - ctl_ptr = ctl_ptr->next; - } - } - - /* Exit channel access. */ - - ca_flush_io(); - - semGive(mon_sem); - - /* Initialize monitor pointer to the head of the monitor linked list - in order to move through linked list freeing memory. */ - - - semTake(mon_sem); - mon_ptr = disp_array[m_select]->m_head; - while (mon_ptr != NULL) - { - free(mon_ptr->ev_ptr); - mon_ptr->ev_ptr = NULL; - mon_ptr = mon_ptr->next; - } - - /* Initialize control pointer to the head of the control linked list - in order to move through the list freeing memory. */ - - - ctl_ptr = disp_array[m_select]->c_head; - - if ((ctl_ptr != NULL) && (disp_array[m_select]->c_head->next->l_crn_row != LIST_END)){ - ctl_ptr = disp_array[m_select]->c_head->next; - - while (ctl_ptr->l_crn_row != LIST_END) - { - free(ctl_ptr->ev_ptr); - ctl_ptr->ev_ptr = NULL; - ctl_ptr = ctl_ptr->next; - } - } - semGive(mon_sem); - - - } - -/*************************************************************************************/ -/* Monitor event handler. Sets the global data_flg when an event is received */ -/* asynchronously. The flag is reset in display_monitors. */ -/*************************************************************************************/ - - - -VOID lopi_ev_handler(lopi_arg) - struct event_handler_args lopi_arg; - { - struct dbr_sts_string *sts_str_ptr; - struct ev_node *ev_ptr; - char txt_str[40]; - static short mon_row = 0; - static short mon_col = 0; - char name[15],*nm_ptr; - struct mon_node *mptr; - - sts_str_ptr = (struct dbr_sts_string *)lopi_arg.dbr; - ev_ptr = ((struct ev_node *)lopi_arg.usr); - - /* If new data has arrived, copy it to the data_string and - set a flag indicating new data. */ - - mptr = (struct mon_node *)ca_puser(lopi_arg.chid); - nm_ptr =(char *)(ca_name(lopi_arg.chid)); - semTake(mon_sem); - if (DEBUG) - logMsg("Ev hand for CA:%s, BW:%s\n",nm_ptr,mptr->chan); - if ((data_flg = strncmp(ev_ptr->str,sts_str_ptr->value,12) != 0)) - { - strncpy(ev_ptr->str, sts_str_ptr->value,12); - ev_ptr->str[12] = NULL; - ev_ptr->data_flg = NEW_DATA; - } - semGive(mon_sem); - } - -/*************************************************************************************/ -/* Exception handler. This routine is called by channel access for asychronous */ -/* events in the server. */ -/*************************************************************************************/ - - VOID lopi_exception_handler(lopi_except_arg) - struct exception_handler_args lopi_except_arg; - { - struct except_node *except_ptr; - except_ptr = (struct except_node *)lopi_except_arg.usr; - if (DEBUG) - logMsg("Exception handler got exception. \n"); - strncpy(except_ptr->msg,lopi_except_arg.ctx, MAX_LIN_LEN - 2); - except_ptr->msg[MAX_LIN_LEN - 1] = NULL; - except_ptr->status = lopi_except_arg.stat; - except_ptr->flg = NEW_DATA; - } - -/*************************************************************************************/ -/* Monitor connection handler. This routine is called by channel access to report */ -/* changes in the connection status channels. */ -/*************************************************************************************/ - -VOID lopi_conn_handler(lopi_connect_arg) - struct connection_handler_args lopi_connect_arg; - { - struct mon_node *pmon; - int status; - char txt_str[40]; - static short mon_row = 0; - static short mon_col = 0; - char name[15],*nm_ptr; - - pmon = (struct mon_node *)ca_puser(lopi_connect_arg.chid); - nm_ptr = (char *)ca_name(lopi_connect_arg.chid); - if (lopi_connect_arg.op == CA_OP_CONN_DOWN) - { - pmon->conn_flg = CA_OP_CONN_DOWN; - } - else if (lopi_connect_arg.op == CA_OP_CONN_UP) - { - pmon->conn_flg = CA_OP_CONN_UP; - } - else - pmon->conn_flg = UNDEF; - - if (DEBUG) - logMsg("Conn hand for CA:%s, BW:%s\n",nm_ptr,pmon->chan); - - } - -/*************************************************************************************/ -/* Frees memory allocated by lopi.c */ -/*************************************************************************************/ - -void free_mem(disp_array,dmenu,nlines,except_ptr) - struct window_node *disp_array[MAX_DISP_NUM]; - int nlines; - char *dmenu[MXMENU]; - { - struct txt_node *txt_ptr; - struct mon_node *ctl_ptr; - struct mon_node *mon_ptr; - char *mptr; - register short lopi_i; - for (lopi_i = 0; lopi_i < nlines; lopi_i++) - { - while (disp_array[lopi_i]->t_head != NULL) - { - txt_ptr = disp_array[lopi_i]->t_head; - disp_array[lopi_i]->t_head = disp_array[lopi_i]->t_head->next; - free(txt_ptr); - } - - while(disp_array[lopi_i]->c_head != NULL) - { - ctl_ptr = disp_array[lopi_i]->c_head; - disp_array[lopi_i]->c_head = disp_array[lopi_i]->c_head->next; - free(ctl_ptr); - } - - while(disp_array[lopi_i]->m_head != NULL) - { - mon_ptr = disp_array[lopi_i]->m_head; - disp_array[lopi_i]->m_head = disp_array[lopi_i]->m_head->next; - free(mon_ptr); - } - - mptr = dmenu[lopi_i]; - free(mptr); - dmenu[lopi_i] = NULL; - - } - free(except_ptr); - return; - } - -/********************************************************************************/ -/* Puts the value passed to it as a string to the data base channel which cptr */ -/* points to. */ -/********************************************************************************/ - -void put_value(c_ptr,val_in) - char val_in[MAX_STRING_SIZE]; /* Array containing value to be put. */ - struct mon_node *c_ptr; /* Pointer to record of channel to which value is to - be passes. */ - { - status = ca_put(DBR_STRING,c_ptr->chan_id,((void *)val_in)); - if (status != ECA_NORMAL) - logMsg("Message:%s\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - if (DEBUG) - logMsg("Putting %s to %s\n",val_in,c_ptr->chan); - status = ca_flush_io(); - if (status != ECA_NORMAL) - logMsg("Message:%s\n",ca_message_text[CA_EXTRACT_MSG_NO(status)]); - return; - } diff --git a/src/util/lopi_def.h b/src/util/lopi_def.h deleted file mode 100644 index fcee2c3df..000000000 --- a/src/util/lopi_def.h +++ /dev/null @@ -1,225 +0,0 @@ - /* $Id$ - * Author: Betty Ann Gunther - * Date: 02-15-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 07-03-91 rac changed "bw" to "lopi" - * .02 07-03-91 rac eliminate some gcc warnings - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -VOID lopi_init(); -VOID create_menu(); -VOID get_displays(); -struct mon_node *mon_alloc(); /* Allocates memory for an update.*/ -struct txt_node *txt_alloc(); /* Allocates memory for a test label. */ -struct ev_node *ev_alloc(); /* Allocates memory for an event node. */ -struct except_node *except_alloc(); /* Allocates memory for an exception node. */ -struct window_node *win_alloc(); /* Allocates memory for a window structure. */ -VOID init_monitors (); -VOID print_menu(); -VOID mv_cursor(); -VOID get_key(); -char get_esc_seq(); -VOID make_box(); -VOID get_value(); -VOID blank_fill(); -VOID mv_cursor(); -char *skipblanks(); -int getline(); -VOID lopi_conn_handler(); -VOID lopi_exception_handler(); -LOCAL VOID add_ctl(); -VOID add_mon(); -VOID add_txt(); -char *skip_to_digit(); -int int_to_short(); -VOID read_disp_lst(); -VOID display_text(); -VOID display_file(); -VOID display_monitors(); -VOID stop_monitors(); -VOID lopi_ev_handler(); -VOID lopi_exception_handler(); -VOID lopi_conn_handler(); -VOID free_mem(); -struct mon_node *find_channel(); -VOID put_value(); -int to_short(); - -#define FN_LEN 24 -#define LIST_END -1 -#define NEWLINE '\n' -#define MXMENU 34 -#define ESC '\33' -#define L_BRACKET '[' -#define RETURN '\15' -#define CR '\13' -#define DELETE '\177' -#define BLANK ' ' -#define UNDERSC '_' -#define MINUS '-' -#define COLON ':' -#define TILDE '~' -#define ASTER '*' /* Legal text character. */ -#define L_ARROW '$' -#define R_ARROW '%' -#define U_ARROW '!' -#define D_ARROW '@' -#define ILL_CHR '#' -#define F6 '^' /* Permits exit back to main menu. */ -#define F7 '&' -#define DOT '.' - -/* VT220 Escape secquences */ - -#define CLEAR_SCREEN fdprintf(lopi_fd,"%c", '\33'); \ - fdprintf(lopi_fd,"%s","[2J"); -#define INIT_CURSOR fdprintf(lopi_fd,"%c", '\33'); \ - fdprintf(lopi_fd,"%s", "[?25h"); -#define ERASE_LINE fdprintf(lopi_fd,"%c",ESC); \ - fdprintf(lopi_fd,"%s","[2K"); -#define ESCAPE fdprintf(lopi_fd,"%c",'\33'); -#define REVERSE_VIDEO fdprintf(lopi_fd,"%s","[7;5m"); -#define ATR_OFF fdprintf(lopi_fd,"%s","[0m"); - -#define CTL 1 -#define MON 0 -#define DEBUG 0 -#define OFF 0 -#define ON 1 -#define NO_CMD "\0" -#define NEW_DATA 1 -#define NO_NEW_DATA 0 -#define NOTHING_SELECTED -1 /* Flag to indicate that lopi is waiting - for the user to make a selection. */ -#define STRT_TTLE_ROW 1 /* Title row position. */ -#define STRT_TTLE_COL 30 /* Title column position. */ -#define STRT_MENU_ROW 7 /* Row position of first menu item. */ -#define STRT_MENU_COL 20 /* Column position of first menu item. */ -#define MAX_DISP_NUM 10 /* Maximum number of displays. */ -#define MAX_LIN_LEN 80 /* Maximum number of characters in a line of a - display file. */ -#define BUFF_SIZE 10 -#define MAX_SCREEN_HEIGHT 24 -#define MAX_SCREEN_WIDTH 78 -#define CHAN_NM_SIZE 40 -#define MAX_FIELD_SIZE 8 - -#define ERR_MSG_ROW 20 -#define ERR_MSG_COL 0 -#define BOX_IN_ROW 2 -#define BOX_IN_COL 43 -#define BEG_BOX 1 -#define END_BOX 3 -#define UNDEF 8 -#define FOUND 1 -#define NOT_FOUND 0 - -shell_init() -{ - ioctl(1,FIOSETOPTIONS,OPT_RAW); -} - -/* - * CA_SIGNAL() - * - * - */ - -lopi_signal(ca_status,message) -int ca_status; -char *message; -{ - short row = ERR_MSG_ROW; - short col = ERR_MSG_COL; - char prefix[MAX_LIN_LEN]; - char txt_str[MAX_LIN_LEN]; - - static char *severity[] = - { - "Warning", - "Success", - "Error", - "Info", - "Fatal", - "Fatal", - "Fatal", - "Fatal" - }; - -/* - if( CA_EXTRACT_MSG_NO(ca_status) >= NELEMENTS(ca_message_text) ){ - message = "corrupt status"; - ca_status = ECA_INTERNAL; - } -*/ - strcpy(txt_str, "CA.Diagnostic.........."); - mv_cursor(&row,&col,txt_str); - - - if(message){ - strcpy(prefix,"Severity:[%s] Error:[%s]Context: [%s]"); - sprintf(txt_str,prefix,severity[CA_EXTRACT_SEVERITY(ca_status)], - ca_message_text[CA_EXTRACT_MSG_NO(ca_status)],message); - mv_cursor(&row,&col,txt_str); - } - else{ - strcpy(prefix,"Severity:[%s],Error:[%s]"); - sprintf(txt_str,prefix,severity[CA_EXTRACT_SEVERITY(ca_status)], - ca_message_text[CA_EXTRACT_MSG_NO(ca_status)]); - mv_cursor(&row,&col,txt_str); - } - /* - * - * - * Terminate execution if unsuccessful - * - * - */ - if( !(ca_status & CA_M_SUCCESS) ){ -# ifdef VMS - lib$signal(0); -# endif -# ifdef vxWorks - ti(VXTHISTASKID); - tt(VXTHISTASKID); -# endif - /* abort(ca_status); */ - } - -} - diff --git a/src/util/pprPlot.c b/src/util/pprPlot.c deleted file mode 100644 index 575263516..000000000 --- a/src/util/pprPlot.c +++ /dev/null @@ -1,6060 +0,0 @@ -/* base/src/util $Id$ - * Author: Roger A. Cole - * Date: 12-04-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-92, 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-04-90 rac initial version - * .02 07-20-91 rac installed in SCCS; finalized "how to access" - * .03 08-09-91 rac fix a problem with pprMark when clipping - * .04 09-04-91 rac change pprAreaErase to pprRegionErase; add - * pprAreaErase; update documentation; add pprPixXToXFrac - * and pprPixYToYFrac; add various Line and Point erase - * functions - * .05 05-15-92 rac add pprErrorBar; add line caps as special marks for - * pprMark - * .06 09-07-92 rac handle sub-intervals; change pixel coordinates to - * short integers - * .07 10-09-92 rac do some optimizing to reduce CPU time and X traffic; - * provide support for strip charts; add a special - * waveform plotting call - * .08 11-13-92 rac handle annotations a little better; replace pprCvt - * with a copy of cvtXxx - * .09 05-04-94 pg HPUX port changes. - * - * make options - * -DvxWorks makes a version for VxWorks - * -DSUNVIEW to use SunView window system - * -DXWINDOWS to use X window system - * -DNDEBUG don't compile assert() checking - * -DPPR_TEST compile the embedded main program for testing - * - * UW is an "edit time" switch which sets the test program - * to use pprWinOpenUW and play like a user program which - * does all its own windowing operations. - */ -/*+/mod*********************************************************************** -* TITLE pprSubr.c - portable plotting routines -* -* DESCRIPTION -* These routines support simple 2-D plotting in a "window". The -* window can be either an actual display window, a PostScript -* printer page, or an EPS file for Encapsulated PostScript. -* -* QUICK REFERENCE -* PPR_AREA *pArea; pointer to a plot area -* PPR_WIN *pWin; pointer to a plot "window" -* -* void pprAnnotX( pArea, offset, dataL, dataR, nDiv, -* drawLine, xLabel, xAnnot, angle ) -* void pprAnnotY( pArea, offset, dataB, dataT, nDiv, -* drawLine, yLabel, yAnnot, angle ) -* void pprAnnotYMark( pArea, offset, markNum ) -* void pprAreaClose( pArea ) -* void pprAreaErase( pArea xDblLft, yDblBot, xDblRt, yDblTop) -* PPR_AREA *pprAreaOpen( pWin, fracL, fracB, fracR, fracT, -* dataL, dataB, dataR, dataT, -* nXint, nYint, charHt ) -* PPR_AREA *pprAreaOpenDflt( pWin, fracL, fracB, fracR, fracT, -* dataL, dataB, dataR, dataT ) -* void pprAreaRescale( pArea, dataL, dataB, dataR, dataT ) -* long pprAreaSetAttr( pArea, code, attrVal, pAttr ) -* code: PPR_ATTR_{CLIP,COLORNUM,BG,FG,KEYNUM,LINE_THICK,NOCLIP, -* PATT_ARRAY,STRIP} -* void pprAutoEnds( dbl1, dbl2, >pNewDbl1, >pNewDbl2 ) -* void pprAutoInterval( dbl1, dbl2, >pNint ) -* void pprAutoRangeD( dblAry, nPts, >minDbl, >maxDbl ) -* void pprAutoRangeF( fltAry, nPts, >minDbl, >maxDbl ) -* void pprAutoRangeL( lngAry, nPts, >minDbl, >maxDbl ) -* void pprAutoRangeS( shtAry, nPts, >minDbl, >maxDbl ) -* void pprChar( pArea, xDbl, yDbl, char, charHt, angle ) -* double pprCos_deg( angle ) -* void pprErrorBar( pArea, xDbl1, yDbl1, xDbl2, yDbl2 ) -* void pprCvtDblToTxt( >text, width, dblVal, nSigDigits ) -* void pprGrid( pArea ) -* void pprGridErase( pArea ) -* void pprGridLabel( pArea, xLabel, xAnnot, yLabel, yAnnot, angle) -* void pprLineD( pArea, xDblAry, yDblAry, nPts ) -* void pprLineF( pArea, xFltAry, yFltAry, nPts ) -* void pprLineL( pArea, xLngAry, yLngAry, nPts ) -* void pprLineS( pArea, xShtAry, yShtAry, nPts ) -* void pprLineEraseD( pArea, xDblAry, yDblAry, nPts ) -* void pprLineEraseF( pArea, xFltAry, yFltAry, nPts ) -* void pprLineEraseL( pArea, xLngAry, yLngAry, nPts ) -* void pprLineEraseS( pArea, xShtAry, yShtAry, nPts ) -* void pprLineSegD( pArea, xDbl1, yDbl1, xDbl2, yDbl2 ) -* void pprLineSegL( pArea, xLng1, yLng1, xLng2, yLng2 ) -* void pprLineSegEraseD(pArea, xDbl1, yDbl1, xDbl2, yDbl2 ) -* void pprLineSegEraseL(pArea, xLng1, yLng1, xLng2, yLng2 ) -* void pprMarkD( pArea, xDbl1, yDbl1, markNum ) -* void pprMarkL( pArea, xLng1, yLng1, markNum ) -* void pprMarkEraseD( pArea, xDbl1, yDbl1, markNum ) -* void pprMarkEraseL( pArea, xLng1, yLng1, markNum ) -* void pprMoveD( pArea, xDbl1, yDbl1, penDown ) -* void pprPerim( pArea ) -* void pprPerimErase( pArea ) -* void pprPerimLabel( pArea, xLabel, xAnnot, yLabel, yAnnot, angle) -* double pprPixXToXFrac( pWin, xPixel ) -* double pprPixYToYFrac( pWin, yPixel ) -* void pprPointD( pArea, xDbl1, yDbl1 ) -* void pprPointL( pArea, xLng1, yLng1 ) -* void pprPointEraseD( pArea, xDbl1, yDbl1 ) -* void pprPointEraseL( pArea, xLng1, yLng1 ) -* void pprRegionErase( pArea fracL, fracB, fracR, fracT ) -* double pprSin_deg( angle ) -* void pprText( pArea, xDbl, yDbl, text, just, charHt, angle) -* just: PPR_TXT_{CEN,RJ,LJ} -* void pprTextErase( pArea, xDbl, yDbl, text, just, charHt, angle) -* void pprWaveD( pArea, xDblIncr, yDblAry, nPts ) -* void pprWaveF( pArea, xFltIncr, yFltAry, nPts ) -* void pprWaveL( pArea, xLngIncr, yLngAry, nPts ) -* void pprWaveS( pArea, xShtIncr, yShtAry, nPts ) -* void pprWaveEraseD( pArea, xDblIncr, yDblAry, nPts ) -* void pprWaveEraseF( pArea, xFltIncr, yFltAry, nPts ) -* void pprWaveEraseL( pArea, xLngIncr, yLngAry, nPts ) -* void pprWaveEraseS( pArea, xShtIncr, yShtAry, nPts ) -* void pprWinClose( pWin ) -* void pprWinErase( pWin ) -* void pprWinInfo( pWin, >pXpos, >pYpos, >pXwid, >pYht ) -* int pprWinIsMono( pWin ) -* long pprWinLoop( pWin, drawFn, pDrawArg ) -* void drawFn(pWin, pDrawArg) -* PPR_WIN *pprWinOpen( winType, dispName, winTitle, xPos, yPos, xWid,yHt) -* winType: PPR_WIN_{SCREEN,POSTSCRIPT,EPS} -* PPR_WIN *pprWinOpenUW( pFrame, pCanvas, NULL, NULL ) -* PPR_WIN *pprWinOpenUW( ppDisp, pWindow, pGC, NULL ) -* void pprWinReplot( pWin, drawFn, pDrawArg ) -* double pprYFracToXFrac( pWin, yFrac ) -* -* DESCRIPTION (continued) -* Plotting is done within "plot areas" which are defined within -* the window. Plot areas can be as large as the window, and they -* can overlap, if desired. Clipping service is optional, since -* plot areas are often calibrated for the "normal" range of data, -* and it is useful to see what's happening if the data are outside -* the normal range. -* -* One non-intuitive aspect of the term "plot area" is that the -* usual case ALWAYS plots outside the plot area. Generally, this -* happens when annotations and labels are added to a grid. The -* plot area itself only specified where the edges of the grid were -* to be drawn. Because of this, determining the size and placement -* of a plot area must take into account the necessary margins for -* text. (pprAreaOpenDflt automatically takes care of margins.) -* -* Most plotting is done using "data coordinates", which are the -* actual data values. In some cases, coordinates or distances are -* specified in terms of a fraction of the window height (see, for -* example, pprAreaOpen or pprText). -* -* Also provided in this package are some routines for interacting -* with the "window". In many cases, this means that a plotting -* program can totally avoid any knowledge of, or dependence on, a -* particular windowing environment. This makes easily available -* the capability for producing hard copies of plots on a PostScript -* printer. -* -* Many routines in this package require that values be -* represented with type 'double'. In some cases, however, other -* data types are directly supported, so that the caller doesn't -* need to alter the way data are stored. -* -* BUGS -* o Only linear axes are presently supported -* o The SunView version of this package won't run properly with -* programs which use the SunOs LightWeight Process library. -* o The SunView version of this package doesn't handle color. -* -* EXAMPLE -* The following program plots the first 80 points of a parabola. The -* size and position of the plot window can be freely changed; the -* window can be covered and exposed, iconified and de-iconified, etc. -* When a `click right' is done in the plot window, the window is -* closed. A PostScript file named "testPS" is produced; the size of -* the plot in this file is about the same as it was when the plot -* window was closed. -* -* The program is compiled and linked for X11 with the following -* command. (If making to run on sun3, use lib.sun3 in the command.) -* -* % cc plotTest.c -I~epics/epicsH -I$(OPENWINHOME)/include \ -* -L~epics/share/bin/lib.sun4 -L$(OPENWINHOME)/lib \ -* -lppr -lX -lm -* -* #include -* #include -* -* #define NPTS 80 -* ---------------------------------------------------------------------------- -* define a structure for holding the data. This is needed because the -* replot routine (which does the actual plotting) is only given a pointer -* to the information it needs. -* ---------------------------------------------------------------------------- -* typedef struct { -* int nPts; -* float x[NPTS]; -* float y[NPTS]; -* double xMin; -* double xMax; -* double yMin; -* double yMax; -* } MY_DATA; -* -* void replot(); -* -* main() -* { -* int i; -* int x=0,y=0,width=0,height=0; -* PPR_WIN *pWin; -* MY_DATA myData; -* long stat; -* -* ---------------------------------------------------------------------------- -* generate the data in the structure. Once it's generated, figure out -* the range of values and put the range into the structure using -* pprAutoRangeF. This specific routine was chosen because the data -* is in "float" arrays. Different forms of data would result in choosing -* a different routine. -* -* The routine pprAutoEnds is available to "round" the endpoints of the -* axes to "nicer" values. Depending on the application, it will be -* attractive to use this following the pprAutoRange call. -* ---------------------------------------------------------------------------- -* myData.nPts = NPTS; -* for (i=0; ixMin, pMyData->yMin, pMyData->xMax, pMyData->yMax, -* 5, 5, charHt); -* pprPerimLabel(pArea, "x label", NULL, "y label", NULL, 0.); -* -* pprLineF(pArea, pMyData->x, pMyData->y, pMyData->nPts); -* -* pprAreaClose(pArea); -* -* return; -* } -* -*-***************************************************************************/ - -#ifdef vxWorks -/*---------------------------------------------------------------------------- -* includes and defines for VxWorks compile -*---------------------------------------------------------------------------*/ -# include -# include -# include -# include -#else -/*---------------------------------------------------------------------------- -* includes and defines for Sun compile -*---------------------------------------------------------------------------*/ -# include -# include -# include -# include -# include -#endif - -# ifdef _HPUX_SOURCE -# ifndef nint -# define nint(value) (value>=0 ? (int)((value)+.5) : (int)((value)-.5)) -# endif -# ifndef exp10 -# define exp10(value) (exp(value * log(10.))) -# endif -# endif - -#define PPR_PRIVATE -#include - -void pprAnnotX_gen(); -void pprAnnotY_gen(); -void pprArcD_gen(); -void pprLineSegPixD_ac(), pprLineSegPixL_ac(); -void pprLineSegPixD_wc(), pprLineSegPixL_wc(); -void pprLineSegDashD_wc(); -void pprText_gen(); - - -/*----------------------------------------------------------------------------- -* assert macros, so that this package can be portable without having to link -* to genLib.a -*----------------------------------------------------------------------------*/ - -#ifndef NDEBUG -# define PprAssert(expr) ((void)((expr) || pprAssertFail(__FILE__, __LINE__))) -#else -# define PprAssert(expr) ((void)0) -#endif -#define PprAssertAlways(expr) \ - ((void)((expr) || pprAssertFail(__FILE__, __LINE__))) -pprAssertFail(fileName, lineNum) -char *fileName; -int lineNum; -{ - (void)fprintf(stderr, "pprAssertFail: in file %s line %d\n", - fileName, lineNum); -#ifdef vxWorks - if (kill(taskIdSelf(), SIGUSR1) == ERROR) { - int *j; - j = (int *)(-1); - j = (int *)(*j); - } - exit(1); -#else - abort(); -#endif -} - -/*----------------------------------------------------------------------------- -* doubly linked list macros -*----------------------------------------------------------------------------*/ -#define DoubleListAppend(pItem,pHead,pTail) \ -{\ - pItem->pNext = NULL;\ - pItem->pPrev = pTail;\ - if (pTail != NULL)\ - pTail->pNext = pItem; /* link previous tail to here */\ - pTail = pItem;\ - if (pHead == NULL)\ - pHead = pItem; /* link to head if first item */\ -} - -#define DoubleListRemove(pItem,pHead,pTail) \ -{\ - if (pItem->pPrev != NULL)\ - (pItem->pPrev)->pNext = pItem->pNext; /* link prev to next */\ - else\ - pHead = pItem->pNext; /* link list head to next */\ - if (pItem->pNext != NULL)\ - (pItem->pNext)->pPrev = pItem->pPrev; /* link next to prev */\ - else\ - pTail = pItem->pPrev; /* link list tail to prev */\ - pItem->pNext = NULL;\ - pItem->pPrev = NULL;\ -} - -/*+/internal****************************************************************** -* NAME pprTest - test routine for plot library -* -*-*/ -#ifdef PPR_TEST - -#ifndef vxWorks - main() { pprTest(); } -#endif -#define NPTS 80 -typedef struct { - double xMin; - double xMax; - double yMin; - double yMax; - int nPts; - float x[NPTS]; - float y[NPTS]; -} MY_DATA; - -void replot(); - -#ifdef SUNVIEW -struct pprWinWin { - Frame frame; - PPR_WIN *pWin1; - PPR_WIN *pWin2; - void *pMyData; -}; -#endif - -#define UW -#undef UW -pprTest() -{ - int i; - int x=0,y=0,width=0,height=0; - PPR_WIN *pWin, *pWin2; - MY_DATA myData; - long stat; -#ifdef SUNVIEW - Frame plotFrame; - Canvas plotCanvas, plotCanvas1, plotCanvas2; - struct pprWinWin winList; - void pprTestEvHandler(); -#else -#if defined XWINDOWS - Display *pDisp; /* pointer to X server connection */ - int screenNo; /* screen number */ - Window rootWindow; /* the root window on display */ - GC gc; /* graphics context */ - XEvent anEvent; /* a window event structure */ - Window plotWindow; /* the plot window on the display */ - Window subWin1, subWin2; - XSizeHints sizeHints; /* defaults for position and size */ -#endif -#endif - - for (i=0; iwinType == PPR_WIN_SCREEN) { -#ifdef XWINDOWS - XFlush(pWin->pDisp); -#endif - (void)printf("eraseTest? (e or cr) "); - fflush(stdout); - if (fgets(answer, 80, stdin) == NULL || answer[0] == '\n') - ; /* no action */ - else { - if (answer[0] == 'e') - replotDraw(pWin, pMyData, 1); - } - } -#endif - - return; -} -replotDraw(pWin, pMyData, erase) -PPR_WIN *pWin; /* I pointer to plot window structure */ -MY_DATA *pMyData; -int erase; -{ - double xlo=0., ylo=0., xhi=.95, yhi=.95; - double charHt, charHtX; - PPR_AREA *pArea; - PPR_AREA *pAreaClip, *pAreaClip2; - int i; - int thick=5, thin=0; - int keyNum=0; - int markNum; - double y=6000.; - double x; - char answer[80]; - - charHt = PprDfltCharHt(ylo, yhi); - charHtX = pprYFracToXFrac(pWin, charHt); - pArea = pprAreaOpen(pWin, xlo+12.*charHtX, ylo+6.*charHt, xhi, yhi, - pMyData->xMin, pMyData->yMin, pMyData->xMax, pMyData->yMax, - 5, 5, charHt); - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thin, NULL); - if (!erase) - pprPerimLabel(pArea, "x label", NULL, "y label", NULL, 0.); - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, 0, NULL); - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - if (!erase) - pprLineF(pArea, pMyData->x, pMyData->y, pMyData->nPts); - else - pprLineEraseF(pArea, pMyData->x, pMyData->y, pMyData->nPts); - - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - for (x=1.; x<10.; x+=1.) { - if (!erase) - pprPointD(pArea, x, x*x+100.); - else - pprPointEraseD(pArea, x, x*x+100.); - } - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thin, NULL); - for (x=1.; x<10.; x+=1.) { - if (!erase) - pprPointD(pArea, x, x*x+200.); - else - pprPointEraseD(pArea, x, x*x+200.); - } - if (!erase) - pprAnnotYMark(pArea, 0, 1); - - for (keyNum=0; keyNum<=PPR_NKEYS; keyNum++) { - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, keyNum, NULL); - if (!erase) - pprLineSegD(pArea, 0., y, 50., y); - else - pprLineSegEraseD(pArea, 0., y, 50., y); - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - if (!erase) - pprLineSegD(pArea, 50., y, 70., y); - else - pprLineSegEraseD(pArea, 50., y, 70., y); - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thin, NULL); - y -= 100.; - } - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, 0, NULL); - for (i=0; i<=PPR_NCOLORS; i++) { - pprAreaSetAttr(pArea, PPR_ATTR_COLORNUM, i, NULL); - if (!erase) - pprLineSegD(pArea, 0., y, 50., y); - else - pprLineSegEraseD(pArea, 0., y, 50., y); - y -= 100.; - } - x = 1.; - for (i=0; i 2.01 || x < -.01 || x > 2.01) - markNum = 3; - else - markNum = 1; - if (!erase) - pprMarkD(pAreaClip2, x, y, markNum); - else - pprMarkEraseD(pAreaClip2, x, y, markNum); - } - } - pprAreaClose(pAreaClip2); - - -#if 1 - if (!erase && pWin->winType == PPR_WIN_SCREEN) { -#ifdef XWINDOWS - XFlush(pWin->pDisp); -#endif - (void)printf( "erase win, area, grid, or perim? (w,a,g,p, or cr) "); - fflush(stdout); - if (fgets(answer, 80, stdin) == NULL || answer[0] == '\n') - ; /* no action */ - else { - if (answer[0] == 'w') - pprWinErase(pWin); - else if (answer[0] == 'a') - pprRegionErase(pArea,.3,.3,.6,.9); - else if (answer[0] == 'p') - pprPerimErase(pArea); - else if (answer[0] == 'g') - pprGridErase(pArea); - (void)printf("done erasing: "); - fflush(stdout); - } - } -#endif - - pprAreaClose(pArea); - - return; -} -#endif - -/*+/internal****************************************************************** -* NAME pprTestEvHandler - handler for SunView events -* -*-*/ -#if defined SUNVIEW && defined UW -static void -pprTestEvHandler(window, pEvent, pArg) -Window window; -Event *pEvent; -void *pArg; -{ - struct pprWinWin *pWinList; - - pWinList = (struct pprWinWin *)window_get(window, WIN_CLIENT_DATA); - if (event_action(pEvent) == WIN_REPAINT) { - if (!window_get(window, FRAME_CLOSED)) { - if (window == pWinList->pWin1->canvas) - pprWinReplot(pWinList->pWin1, replot, pWinList->pMyData); - if (window == pWinList->pWin2->canvas) - pprWinReplot(pWinList->pWin2, replot, pWinList->pMyData); - } - } - else if (event_action(pEvent) == PPR_BTN_CLOSE) { - if (event_is_up(pEvent)) { - pprWinClose(pWinList->pWin1); - pprWinClose(pWinList->pWin2); - window_destroy(pWinList->frame); - } - } -} -#endif - -/*+/subr********************************************************************** -* NAME pprAnnotX - annotate an X axis, perhaps drawing a line and tick marks -* -* DESCRIPTION -* Annotate an X axis, placing annotations at the major tick intervals. -* -* If desired, an axis line is also drawn, with tick marks at the -* major intervals. The tick marks are drawn using the "generic" -* line attributes for the plot window. The axis line is drawn with -* the line attributes of the plot area; this allows using a dashed -* line pattern or color to associate an axis with a data line. -* -* The annotations and label are drawn using the default character -* height for the plot area, in the color, if any, for the plot area. -* -* An array of text strings can be supplied for annotating the tick -* intervals. This is useful if the desired annotations are text. -* If an annotation array isn't supplied, then numeric annotations -* are generated. -* -* To allow multiple calibrations for an axis, this routine accepts -* an `offset' argument. If this argument is greater than 0, then -* the annotation and labeling activity occurs that many lines (in -* the default character height for the plot area) below the axis -* which was established by pprAreaOpen. -* -* An alternate entry point, pprAnnotX_wc, is available to use the -* plot window's color for the annotation. -* -* RETURNS -* void -* -* BUGS -* o only linear axes are handled -* o doesn't presently support offset processing -* -* NOTES -* 1. Uses a space below the axis of 5 character heights. -* -* SEE ALSO -* pprAnnotY, pprGrid, pprPerim, pprAreaOpen, pprAreaSetAttr -* -*-*/ -void -pprAnnotX(pArea, offset, xLeft, xRight, xNint, drawLine, xLabel, xAnnot, angle) -PPR_AREA *pArea; /* I pointer to plotter area */ -int offset; /* I offset as number of lines below yBot to annotate */ -double xLeft; /* I x data value at left end of axis */ -double xRight; /* I x data value at right end of axis */ -int xNint; /* I number of major intervals for axis */ -int drawLine; /* I 1 says to draw a line and tick marks */ -char *xLabel; /* I label for x axis, or NULL; oriented horizontal */ -char **xAnnot; /* I pointer to array of x annotations, or NULL */ -double angle; /* I orientation angle for annotation text; 0. or 90. */ -{ - pprAnnotX_gen(pArea,offset,xLeft,xRight,xNint,drawLine,xLabel,xAnnot,angle, - pprLineSegD_ac, pprLineSegD, pprText); -} -void -pprAnnotX_wc(pArea,offset,xLeft,xRight,xNint,drawLine,xLabel,xAnnot,angle) -PPR_AREA *pArea; /* I pointer to plotter area */ -int offset; /* I offset as number of lines below yBot to annotate */ -double xLeft; /* I x data value at left end of axis */ -double xRight; /* I x data value at right end of axis */ -int xNint; /* I number of major intervals for axis */ -int drawLine; /* I 1 says to draw a line and tick marks */ -char *xLabel; /* I label for x axis, or NULL; oriented horizontal */ -char **xAnnot; /* I pointer to array of x annotations, or NULL */ -double angle; /* I orientation angle for annotation text; 0. or 90. */ -{ - pprAnnotX_gen(pArea,offset,xLeft,xRight,xNint,drawLine,xLabel,xAnnot,angle, - pprLineSegD_wc, pprLineSegD, pprText_wc); -} -static void -pprAnnotX_gen(pArea,offset,xLeft,xRight,xNint,drawLine,xLabel,xAnnot,angle, - fnTick, fnLine, fnText) -PPR_AREA *pArea; /* I pointer to plotter area */ -int offset; /* I offset as number of lines below yBot to annotate */ -double xLeft; /* I x data value at left end of axis */ -double xRight; /* I x data value at right end of axis */ -int xNint; /* I number of major intervals for axis */ -int drawLine; /* I 1 says to draw a line and tick marks */ -char *xLabel; /* I label for x axis, or NULL; oriented horizontal */ -char **xAnnot; /* I pointer to array of x annotations, or NULL */ -double angle; /* I orientation angle for annotation text; 0. or 90. */ -void (*fnTick)(); -void (*fnLine)(); -void (*fnText)(); -{ - double tickHalf, tick1, tick2, tick1S, tick2S; - int i, j; - double x, x1, xInterval, xSubint, y; - double xVal, xValInterval; - char *pText, text[80]; - int nCol=6; /* number of columns for annotation label */ - int sigDigits; /* sig digits to print */ - double maxVal, minVal; /* max and min of the end values for axis */ - double logDiff; /* log of diff between max and min */ - PPR_TXT_JUST just; /* justification code for annotations */ - - tickHalf = pArea->tickHt / pArea->yScale; - tick1S = pArea->yBot; - tick2S = tick1S - tickHalf; - tick1 = tick1S - tickHalf; - tick2 = tick1S + tickHalf; - if (drawLine == 0 && pArea->xNsubint > 0) { - drawLine = 1; - tick1 = tick1S; - tick2 = tick1S - 2.*tickHalf; - } - if (PprAbs(xLeft) >= PprAbs(xRight)) - maxVal = PprAbs(xLeft), minVal = PprAbs(xRight); - else - maxVal = PprAbs(xRight), minVal = PprAbs(xLeft); - if (maxVal == minVal) - maxVal = minVal + 1.; - logDiff = (int)(log10(maxVal - minVal)); - if (logDiff < 0.) sigDigits = 2 + (int)(-1. * logDiff); - else if (maxVal >= 100.) sigDigits = 0; - else if (maxVal >= 10.) sigDigits = 1; - else if (maxVal >= 1.) sigDigits = 2; - else sigDigits = 3; - - x = pArea->xLeft; - xInterval = (pArea->xRight - pArea->xLeft) / xNint; - if (pArea->xNsubint > 0) - xSubint = xInterval / pArea->xNsubint; - xVal = xLeft; - xValInterval = (xRight - xLeft) / xNint; - y = pArea->yBot - 2. * pArea->charHt / pArea->yScale; - for (i=0; i<=xNint; i++) { - if (i == xNint) x = pArea->xRight, xVal = xRight; - if (drawLine) fnTick(pArea, x, tick1, x, tick2); - - if (pArea->xNsubint > 0 && i != xNint) { - for (j=1, x1=x+xSubint; jxNsubint; j++, x1+=xSubint) - fnTick(pArea, x1, tick1S, x1, tick2S); - } - - if (i == 0) just = PPR_TXT_LJ; - else if (i == xNint) just = PPR_TXT_RJ; - else just = PPR_TXT_CEN; - if (xAnnot == NULL) - pprCvtDblToTxt(text, nCol, xVal, sigDigits), pText = text; - else - pText = xAnnot[i]; - fnText(pArea, x, y, pText, just, 0., angle); - - x += xInterval; - xVal += xValInterval; - } - if (xLabel != NULL) { - x = (pArea->xLeft + pArea->xRight) / 2.; - y = pArea->yBot - 4. * pArea->charHt / pArea->yScale; - fnText(pArea, x, y, xLabel, PPR_TXT_CEN, 0., angle); - } -} - -/*+/subr********************************************************************** -* NAME pprAnnotY - annotate a Y axis, perhaps drawing line and tick marks -* -* DESCRIPTION -* Annotate a Y axis, placing annotations at the major tick intervals. -* -* If desired, an axis line is also drawn, with tick marks at the -* major intervals. The tick marks are drawn using the "generic" -* line attributes for the plot window. The axis line is drawn with -* the line attributes of the plot area; this allows using a dashed -* line pattern or color to associate an axis with a data line. -* -* The annotations and label are drawn using the default character -* height for the plot area, in the color, if any, for the plot area. -* -* An array of text strings can be supplied for annotating the tick -* intervals. This is useful if the desired annotations are text. -* If an annotation array isn't supplied, then numeric annotations -* are generated. -* -* To allow multiple calibrations for an axis, this routine accepts -* an `offset' argument. If this argument is greater than 0, then -* the annotation and labeling activity occurs that many lines (in -* the default character height for the plot area) to the left of -* the axis which was established by pprAreaOpen. -* -* An alternate entry point, pprAnnotY_wc, is available to use the -* plot window's color for the annotation. -* -* RETURNS -* void -* -* BUGS -* o only linear axes are handled -* -* NOTES -* 1. Uses a space to the left of the axis of 12 character heights if -* annotations are horizontal, and a space of 5 character heights -* if they are vertical. -* -* SEE ALSO -* pprAnnotX, pprGrid, pprPerim, pprAreaOpen, pprAreaSetAttr -* -*-*/ -void -pprAnnotY(pArea, offset, yBot, yTop, yNint, drawLine, yLabel, yAnnot, angle) -PPR_AREA *pArea; /* I pointer to plot area structure */ -int offset; /* I number of lines to left of axis for annotation */ -double yBot; /* I y data value at bottom end of axis */ -double yTop; /* I y data value at top end of axis */ -int yNint; /* I number of major intervals for axis */ -int drawLine; /* I 1 says to draw a line and tick marks */ -char *yLabel; /* I label for y axis, or NULL; oriented vertical */ -char **yAnnot; /* I pointer to array of y annotations, or NULL */ -double angle; /* I orientation angle for annotation text; 0. or 90. */ -{ - pprAnnotY_gen(pArea,offset,yBot,yTop,yNint,drawLine,yLabel,yAnnot,angle, - pprLineSegD_ac, pprLineSegD, pprText); -} -void -pprAnnotY_wc(pArea, offset, yBot, yTop, yNint, drawLine, yLabel, yAnnot, angle) -PPR_AREA *pArea; /* I pointer to plot area structure */ -int offset; /* I number of lines to left of axis for annotation */ -double yBot; /* I y data value at bottom end of axis */ -double yTop; /* I y data value at top end of axis */ -int yNint; /* I number of major intervals for axis */ -int drawLine; /* I 1 says to draw a line and tick marks */ -char *yLabel; /* I label for y axis, or NULL; oriented vertical */ -char **yAnnot; /* I pointer to array of y annotations, or NULL */ -double angle; /* I orientation angle for annotation text; 0. or 90. */ -{ - pprAnnotY_gen(pArea,offset,yBot,yTop,yNint,drawLine,yLabel,yAnnot,angle, - pprLineSegD_wc, pprLineSegD, pprText_wc); -} -void -pprAnnotY_gen(pArea, offset, yBot, yTop, yNint, drawLine, yLabel, yAnnot, angle, - fnTick, fnLine, fnText) -PPR_AREA *pArea; /* I pointer to plot area structure */ -int offset; /* I number of lines to left of axis for annotation */ -double yBot; /* I y data value at bottom end of axis */ -double yTop; /* I y data value at top end of axis */ -int yNint; /* I number of major intervals for axis */ -int drawLine; /* I 1 says to draw a line and tick marks */ -char *yLabel; /* I label for y axis, or NULL; oriented vertical */ -char **yAnnot; /* I pointer to array of y annotations, or NULL */ -double angle; /* I orientation angle for annotation text; 0. or 90. */ -void (*fnTick)(); -void (*fnLine)(); -void (*fnText)(); -{ - double tickHalf, tick1, tick2; - int i; - double x; /* x coord for annotations */ - double xL; /* x coord for label */ - double xBase; /* base x coordinate */ - double y, yInterval; - double yVal, yValInterval; - char text[80]; - int nCol=6; /* number of columns for annotation label */ - int sigDigits; /* sig digits to print */ - double maxVal, minVal; /* max and min of the end values for axis */ - double logDiff; /* log of diff between max and min */ - PPR_TXT_JUST just; /* justification flag for text */ - - xBase = pArea->xLeft - (double)offset * pArea->charHt / pArea->xScale; - if (drawLine) { - tickHalf = pArea->tickHt / pArea->xScale; - tick1 = xBase - tickHalf; - if (offset == 0) - tick2 = xBase + tickHalf; - else - tick2 = xBase; - } - if (PprAbs(yBot) >= PprAbs(yTop)) - maxVal = PprAbs(yBot), minVal = PprAbs(yTop); - else - maxVal = PprAbs(yTop), minVal = PprAbs(yBot); - if (maxVal == minVal) - maxVal = minVal + 1.; - logDiff = (int)(log10(maxVal - minVal)); - if (logDiff < 0.) sigDigits = 2 + (int)(-1. * logDiff); - else if (maxVal >= 100.) sigDigits = 0; - else if (maxVal >= 10.) sigDigits = 1; - else if (maxVal >= 1.) sigDigits = 2; - else sigDigits = 3; - - if (angle == 0.) { - x = xBase - 2. * pArea->charHt / pArea->xScale; - xL = xBase - 10. * pArea->charHt / pArea->xScale; - } - else { - x = xBase - 2. * pArea->charHt / pArea->xScale; - xL = xBase - 4. * pArea->charHt / pArea->xScale; - } - y = pArea->yBot; - yInterval = (pArea->yTop - pArea->yBot) / yNint; - yVal = yBot; - yValInterval = (yTop - yBot) / yNint; - if (drawLine) - fnTick(pArea, tick1, y, tick2, y); - if (angle == 0.) just = PPR_TXT_RJ; - else just = PPR_TXT_LJ; - if (yAnnot == NULL) { - pprCvtDblToTxt(text, nCol, yVal, sigDigits); - fnText(pArea, x, y, text, just, 0., angle); - } - else - fnText(pArea, x, y, yAnnot[0], just, 0., angle); - if (angle == 0.) just = PPR_TXT_RJ; - else just = PPR_TXT_CEN; - for (i=1; iyTop; - if (angle == 0.) just = PPR_TXT_RJ; - else just = PPR_TXT_RJ; - if (yAnnot == NULL) { - pprCvtDblToTxt(text, nCol, yTop, sigDigits); - fnText(pArea, x, y, text, just, 0., angle); - } - else - fnText(pArea, x, y, yAnnot[yNint], just, 0., angle); - if (drawLine) { - fnTick(pArea, tick1, y, tick2, y); - fnLine(pArea, xBase, pArea->yBot, xBase, pArea->yTop); - } - if (yLabel != NULL) { - y = (pArea->yBot + pArea->yTop) / 2.; - fnText(pArea, xL, y, yLabel, PPR_TXT_CEN, 0., 90.); - } -} - -/*+/subr********************************************************************** -* NAME pprAnnotYMark - add plot marks to a Y axis annotation -* -* DESCRIPTION -* Draw two plot marks at the foot of the Y axis annotation, to allow -* associating the axis with a particular set of data. -* -* RETURNS -* void -* -* BUGS -* o only linear axes are handled -* -* SEE ALSO -* pprMark, pprAnnotY -* -* EXAMPLE -* -*-*/ -void -pprAnnotYMark(pArea, offset, markNum) -PPR_AREA *pArea; /* I pointer to plot area structure */ -int offset; /* I number of lines to left of axis for annotation */ -int markNum; /* I mark number */ -{ - double x, y; - - x = pArea->xLeft - (double)(offset+3) * pArea->charHt / pArea->xScale; - y = pArea->yBot - pArea->charHt * 2. / pArea->yScale; - pprMarkD(pArea, x, y, markNum); -} - -/*+/subr********************************************************************** -* NAME pprArc - draw an arc -* -* DESCRIPTION -* Draw an arc. The arc is specified by a radius and two angles. The -* angles, in degrees, specify the angle at which the arc starts and -* the angle at which it ends. An angle increment specifies both the -* direction of the arc and the size of the chords which approximate -* the arc. Angles are measured counter-clockwise from the positive -* X axis. -* -* The radius of the arc is treated as representing data values in the -* plot area. If both the X and Y axes of the plot area have the -* same data scaling, then circular arcs will be produced (assuming -* a square plot area). If the X scaling is not the same as the Y -* scaling, then elliptical arcs will be produced. -* -* The arc is drawn using the color, dashed line, and other attributes -* of the plot area. Alternate entry points are: -* -* pprArcD_ac uses the area color, but ignores other -* attributes -* -* RETURNS -* void -* -* SEE ALSO -* -*-*/ -void -pprArcD(pArea, xDbl, yDbl, radDbl, angle1, angle2, angleIncr) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double xDbl; /* I x data coordinate for center of arc */ -double yDbl; /* I y data coordinate for center of arc */ -double radDbl; -double angle1; /* I angle to start arc */ -double angle2; /* I angle to stop arc */ -double angleIncr; /* I size of steps in drawing arc */ -{ - pprArcD_gen(pArea, xDbl, yDbl, radDbl, angle1, angle2, angleIncr, - pprMoveD); -} -void -pprArcD_ac(pArea, xDbl, yDbl, radDbl, angle1, angle2, angleIncr) -PPR_AREA *pArea; -double xDbl, yDbl, radDbl, angle1, angle2, angleIncr; -{ - pprArcD_gen(pArea, xDbl, yDbl, radDbl, angle1, angle2, angleIncr, - pprMoveD_ac); -} -void -pprArcD_gen(pArea, xDbl, yDbl, radDbl, angle1, angle2, angleIncr, fn) -PPR_AREA *pArea; -double xDbl, yDbl, radDbl, angle1, angle2, angleIncr; -void (*fn)(); /* I line drawing function */ -{ - double x, y, angle; - int pen=0; - - if (angle1 > angle2 && angleIncr > 0.) { - while (angle1 > angle2) - angle2 += 360.; - } - else if (angle1 < angle2 && angleIncr < 0.) { - while (angle1 < angle2) - angle1 += 360.; - } - angle = angle1; - while (1) { - x = xDbl + radDbl * pprCos_deg(angle); - y = yDbl + radDbl * pprSin_deg(angle); - fn(pArea, x, y, pen); - pen = 1; - if (angle == angle2) - break; - if ((angle += angleIncr) > angle2) - angle = angle2; - } -} - -/*+/subr********************************************************************** -* NAME pprAreaClose - close a plot area -* -* DESCRIPTION -* Frees the memory associated with a plot area pointer and does other -* cleanup operations. This routine should be called prior to calling -* pprWinClose. -* -* RETURNS -* void -* -*-*/ -void -pprAreaClose(pArea) -PPR_AREA *pArea; /* I pointer to plot area structure */ -{ - PPR_WIN *pWin; - - pWin = pArea->pWin; - -#ifdef XWINDOWS - if (pWin->winType == PPR_WIN_SCREEN) { - if (pArea->attr.myGC) - XFreeGC(pWin->pDisp, pArea->attr.gc); - if (pArea->attr.bgGC) - XFreeGC(pWin->pDisp, pArea->attr.gcBG); - if (pArea->linkedTo == NULL) { - if (pArea->pixMap != NULL) - XFreePixmap(pWin->pDisp, pArea->pixMap); - if (pArea->pixMapGC != NULL) - XFreeGC(pWin->pDisp, pArea->pixMapGC); - if (pArea->stipple != NULL) - XFreePixmap(pWin->pDisp, pArea->stipple); - } - } -#endif - DoubleListRemove(pArea, pWin->pAreaHead, pWin->pAreaTail); - free((char *)pArea); -} - -/*+/subr********************************************************************** -* NAME pprAreaErase - erase an area within a plot window -* -* DESCRIPTION -* Erases an area within a plot window. -* -* RETURNS -* void -* -* BUGS -* 1. This doesn't erase the pixmap used for strip charts. -* -* SEE ALSO -* pprWinErase, pprGridErase, pprPerimErase, pprRegionErase -* the ppr...Erase... entry points for the various drawing routines -* -* EXAMPLES -* 1. A data area occupies the upper right quarter of the plot window, -* with data values at the lower left corner of xleft,ybot and at -* the upper right of xright,ytop. 3 annotation areas are used to -* the left of the data area, extending from the left edge of the -* plot window to the left edge of the data area; each annotation -* area occupies 1/3 of the height of the data area. Erase the -* middle annotation area. -* -* double xl,yb,xr,yt; -* -* The region to erase is expressed as data values. The y values are -* straightforward--just 1/3 and 2/3 of the range of the y axis. The -* right-hand x value is just a bit less than the x at the left end -* of the x axis; the left hand x value requires a bit of analytic -* geometry to get. -* -* xl = xleft - (xright - xleft)/(1. - .5) * (.5 - 0.); -* yb = ybot + (ytop - ybot)/3.; -* xr = xright - .001 * (xright - xleft); -* yt = ybot + 2.*(ytop - ybot)/3.; -* pprAreaErase(pArea, xl, yb, xr, yt); -* -*-*/ -void -pprAreaErase(pArea, xDblLeft, yDblBot, xDblRight, yDblTop) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double xDblLeft; /* I x data value at left edge of area */ -double yDblBot; /* I y data value at bottom edge of area */ -double xDblRight; /* I x data value at right edge of area */ -double yDblTop; /* I y data value at top edge of area */ -{ - int x,y,x1,x2,y1,y2,width,height; - - if (pArea->pWin->winType != PPR_WIN_SCREEN) - return; - x1 = pArea->xPixLeft + .5 + (xDblLeft - pArea->xLeft) * pArea->xScale; - x2 = pArea->xPixLeft + .5 + (xDblRight - pArea->xLeft) * pArea->xScale; - if (x1 < x2) { - x = x1; - width = x2 - x1; - } - else { - x = x2; - width = x1 - x2; - } - y1 = pArea->yPixBot + .5 + (yDblBot - pArea->yBot) * pArea->yScale; - y2 = pArea->yPixBot + .5 + (yDblTop - pArea->yBot) * pArea->yScale; - if (y1 < y2) { - y = y1; - height = y2 - y1; - } - else { - y = y2; - height = y1 - y2; - } -#ifdef SUNVIEW - y = pArea->pWin->height - y - height; - pw_writebackground(pArea->pWin->pw, x, y, width, height, PIX_SRC); -#else -#if defined XWINDOWS - y = pArea->pWin->height - y - height; - XClearArea(pArea->pWin->pDisp, pArea->pWin->plotWindow, - x, y, width, height, False); -#endif -#endif -} - -/*+/subr********************************************************************** -* NAME pprAreaOpen - initialize a plot area -* -* DESCRIPTION -* Initialize a plot area within the plot window. This initialization -* must be done before calling any of the routines which do actual -* plotting. -* -* This routine establishes a rectangular "data area" within the plot -* window. It is within the data area that data will be plotted. -* The size and position of the data area are specified in terms -* of fractions of the window size; they are expressed as -* "coordinates" of the lower left and upper right corners of the -* area. The data area specified in the call to pprAreaOpen does -* NOT include space for axis annotations and labels. (pprAreaOpenDflt -* can be used to automatically get the necessary margins.) -* -* This routine must also be told the data values at the two corners -* of the data area in order to determine scaling. -* -* In addition to establishing scaling, this routine accepts information -* about how many major divisions there are for each axis and what -* default character height is to be used for displaying text within -* the plot area (see pprText for more information). If any of these -* parameters is specified as zero, this routine chooses an appropriate -* value. -* -* The default line attributes for the plot are copied from those of -* the plot window. pprAreaSetAttr can be used to change them. Under -* X11, a gc is created for the plot area with the foreground and -* background being copied from the gc for the plot window; -* pprAreaSetAttr can be used to change the foreground and background. -* -* When plotting is complete for a plot area, pprAreaClose should -* be called. -* -* RETURNS -* pointer to plot area, or -* NULL -* -* BUGS -* o only linear calibration is handled -* -* SEE ALSO -* pprWinOpen, pprAreaOpenDflt, pprAreaSetAttr -* pprAutoEnds, pprAutoInterval, pprAutoRange -* pprText -* -* EXAMPLE -* 1. Set up an area which occupies the full width of the window, but -* which uses the middle third vertically. The range for x values -* is 0 to 100; for y, the range is -10 to 10. Both the x and y -* axes are to be divided into 5 intervals. -* -* Allow space below and to the left of the actual area for plotting -* for pprPerim to place labels and annotations. The required -* size of "margins" depends on the size of characters used, so a -* default size is determined (and put into effect as part of the -* pprAreaOpen call). -* -* PPR_AREA *pArea; -* double charHt, charHtX; -* -* charHt = PprDfltCharHt(.33, .67); -* charHtX = pprYFracToXFrac(pWin, charHt); -* pArea = pprAreaOpen(pWin, 0.+12.*charHtX, .33+6*charHt, 1., .67, -* 0., -10., 100., 10., 5, 5, charHt); -* ... -* pprAreaClose(pArea); -* -*-*/ -PPR_AREA * -pprAreaOpen(pWin, wfracXleft, wfracYbot, wfracXright, wfracYtop, - xLeft, yBot, xRight, yTop, xNint, yNint, charHt) -PPR_WIN *pWin; /* I pointer to plot window structure */ -double wfracXleft; /* I x window fraction of left edge of data area */ -double wfracYbot; /* I y window fraction of bottom edge of data area */ -double wfracXright; /* I x window fraction of right edge of data area */ -double wfracYtop; /* I y window fraction of top edge of data area */ -double xLeft; /* I x data value at left side of data area */ -double yBot; /* I y data value at bottom side of data area */ -double xRight; /* I x data value at right side of data area */ -double yTop; /* I y data value at top side of data area */ -int xNint; /* I x axis number of intervals; if <=0, a default - value is provided */ -int yNint; /* I y axis number of intervals; if <=0, a default - value is provided */ -double charHt; /* I value to use as default for character size, as - a fraction of window height; if <= 0., - a default value is provided */ -{ - PPR_AREA *pArea; /* pointer to plot area structure */ - - if ((pArea = (PPR_AREA *)malloc(sizeof(PPR_AREA))) == NULL) { - (void)printf("pprAreaOpen: couldn't malloc plot area struct\n"); - return NULL; - } - DoubleListAppend(pArea, pWin->pAreaHead, pWin->pAreaTail); - - pArea->pWin = pWin; - pArea->xFracLeft = wfracXleft; - pArea->xFracRight = wfracXright; - if (xNint <= 0) - pprAutoInterval(xLeft, xRight, &xNint); - pArea->xNint = xNint; - pArea->xNsubint = 0; - - pArea->yFracBot = wfracYbot; - pArea->yFracTop = wfracYtop; - if (yNint <= 0) - pprAutoInterval(yBot, yTop, &yNint); - pArea->yNint = yNint; - pArea->yNsubint = 0; - - pArea->charHt = charHt * pWin->height; - pArea->oldWinHt = pWin->height; - - pprAreaRescale(pArea, xLeft, yBot, xRight, yTop); - -#ifdef XWINDOWS - if (pWin->winType == PPR_WIN_SCREEN) { - pArea->attr.gc = XCreateGC(pWin->pDisp, pWin->plotWindow, 0, NULL); - XCopyGC(pWin->pDisp, pWin->attr.gc, GCForeground | GCBackground, - pArea->attr.gc); - XSetGraphicsExposures(pWin->pDisp, pArea->attr.gc, False); - pArea->attr.myGC = 1; - } - pArea->usePixMap = 0; - pArea->linkedTo = NULL; - pArea->pixMap = pArea->stipple = NULL; - pArea->pixMapGC = NULL; -#else -#if - pArea->attr.myGC = 0; -#endif -#endif - pArea->attr.bgGC = 0; - pArea->attr.pPatt = NULL; - pArea->attr.lineThick = 1; - pArea->attr.ltCurr = -1; - pArea->attr.clip = 0; - - return pArea; -} - -/*+/subr********************************************************************** -* NAME pprAreaOpenDflt - initialize a plot area using defaults -* -* DESCRIPTION -* Initialize a plot area within the plot window. This initialization -* must be done before calling any of the routines which do actual -* plotting. -* -* This routine is a variant on pprAreaOpen. It performs the functions -* of that routine, but uses some defaults rather than making the -* caller determine specific values. In particular, this routine: -* -* o sets a default character height -* -* o determines the number of major divisions for each axis -* -* o establishes, inside the plot area specified, margins which -* will be adequate for annotating and labeling the axes. -* -* See the description for pprAreaOpen for additional details. -* -* When plotting is complete for a plot area, pprAreaClose should -* be called. -* -* RETURNS -* pointer to plot area, or -* NULL -* -* BUGS -* o only linear calibration is handled -* -* SEE ALSO -* pprWinOpen, pprAreaOpen, pprAreaSetAttr -* pprAutoEnds, pprAutoInterval, pprAutoRange -* pprText -* -*-*/ -PPR_AREA * -pprAreaOpenDflt(pWin, wfracXleft, wfracYbot, wfracXright, wfracYtop, - xLeft, yBot, xRight, yTop) -PPR_WIN *pWin; /* I pointer to plot window structure */ -double wfracXleft; /* I x window fraction of left edge of plot area */ -double wfracYbot; /* I y window fraction of bottom edge of plot area */ -double wfracXright; /* I x window fraction of right edge of plot area */ -double wfracYtop; /* I y window fraction of top edge of plot area */ -double xLeft; /* I x data value at left side of data area */ -double yBot; /* I y data value at bottom side of data area */ -double xRight; /* I x data value at right side of data area */ -double yTop; /* I y data value at top side of data area */ -{ - int xNint; /* x axis number of intervals */ - int yNint; /* y axis number of intervals */ - double charHt, charHtX;/* default for character size */ - - pprAutoInterval(xLeft, xRight, &xNint); - pprAutoInterval(yBot, yTop, &yNint); - charHt = PprDfltCharHt(wfracYbot, wfracYtop); - charHtX = pprYFracToXFrac(pWin, charHt); - wfracXleft += 12. * charHtX; - wfracYbot += 6. * charHt; - return pprAreaOpen(pWin, wfracXleft, wfracYbot, wfracXright, wfracYtop, - xLeft, yBot, xRight, yTop, xNint, yNint, charHt); -} - -/*+/subr********************************************************************** -* NAME pprAreaRescale - change scaling for existing plot area -* -* DESCRIPTION -* Changes the scaling for a plot area using new data values at the -* edges of the data area. The actual size and position of the -* data area within the plot window aren't changed. -* -* No re-drawing is done by this routine. Typically, the caller will -* erase the appropriate area, draw the grid or perimeter, set the -* area for clipping, and, finally, replot the data. -* -* Default character height for the plot area is altered proportionally -* to the rescaling of the plot area. -* -* RETURNS -* void -* -* SEE ALSO -* pprAreaSetAttr, pprAreaErase, pprRegionErase -* -*-*/ -void -pprAreaRescale(pArea, xLeft, yBot, xRight, yTop) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double xLeft; /* I x data value at left side of data area */ -double yBot; /* I y data value at bottom side of data area */ -double xRight; /* I x data value at right side of data area */ -double yTop; /* I y data value at top side of data area */ -{ - PPR_WIN *pWin; - - pWin = pArea->pWin; - if (xLeft == xRight) { - (void)printf("pprAreaRescale: x left and right are equal\n"); - return; - } - else if (yBot == yTop) { - (void)printf("pprAreaRescale: y bottom and top are equal\n"); - return; - } - pArea->xPixLeft = .5 + ((double)pWin->width)*pArea->xFracLeft; - pArea->xPixRight = .5 + ((double)pWin->width)*pArea->xFracRight; - pArea->xLeft = xLeft; - pArea->xRight = xRight; - pArea->xInterval = (xRight - xLeft) / pArea->xNint; - pArea->xScale = ((double)pWin->width) * - (pArea->xFracRight - pArea->xFracLeft) / (xRight - xLeft); - pArea->yPixBot = .5 + ((double)pWin->height)*pArea->yFracBot; - pArea->yPixTop = .5 + ((double)pWin->height)*pArea->yFracTop; - pArea->yBot = yBot; - pArea->yTop = yTop; - pArea->yInterval = (yTop - yBot) / pArea->yNint; - pArea->yScale = ((double)pWin->height) * - (pArea->yFracTop - pArea->yFracBot) / (yTop - yBot); - pArea->tickHt = (double)pWin->height * - PprMin(PprAbs(.03 * (pArea->yFracTop - pArea->yFracBot)), .01); - if (pArea->charHt <= 0.) - pArea->charHt = pWin->height * - PprDfltCharHt(pArea->yFracBot, pArea->yFracTop); - else - pArea->charHt = pArea->charHt * pWin->height / pArea->oldWinHt; - pArea->oldWinHt = pWin->height; -} - -/*+/subr********************************************************************** -* NAME pprAreaShiftLeft - shift the contents of the plot area -* -* DESCRIPTION -* Shifts the contents of the plot area to the left, as for a strip -* chart. The remembered endpoints for the plot area are changed -* to correspond to the shift. -* -* For best behavior of this routine, the PPR_ATTR_STRIP attribute -* should be set for the plot area after it is opened. If this -* attribute isn't set, the shift operation is more efficient, but -* the appearance is bogus when the data area is partially obscured -* by another window. -* -* RETURNS -* void -* -* NOTES -* 1. The amount shifted will usually be somewhat different from the -* amount requested, since shifts can only occur by a whole number -* of pixels. The .xRight and .xLeft items in the plot area structure -* will be changed by the amount actually shifted. -* -*-*/ -void -pprAreaShiftLeft(pArea, dataShift) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double dataShift; /* I amount to shift left, as an x data value */ -{ - int xl, xr, yb, yt; /* pix coord of perimeter */ - int width, height; /* pix size of perimeter */ - int widP, wc; /* widths preserved and cleared */ - PPR_WIN *pWin=pArea->pWin; - - if (pWin->winType != PPR_WIN_SCREEN) - return; -#ifdef XWINDOWS -/*----------------------------------------------------------------------------- -* This diagram shows the shifting and clearing if the window is used. -* The areas shifted and cleared don't include pixels on the perimeter. -* (Pixel coordinates are referenced to the northwest corner.) -* -* BEFORE -* --dataShift-- distance to shift, as data value -* ----wc------ distance to shift, pixels (includes right edge) -* ----------widP------------ width to shift (neither -* edge included in width) -* +-----------+--------------------------+ -* |*get rid * | -* | of this |*shift this area left *| -* | area | | -* +-----------+--------------------------+ -* ^ xl + 1 ^ xl + wc + 1 shift by copying from here to xl + 1 -* -* AFTER -* +--------------------------+-----------+ -* | * cleared *| -* |*area shifted left *| area | -* | | | -* +--------------------------+-----------+ -* ^ xl + widP + 1 -*----------------------------------------------------------------------------*/ - xl = pArea->xPixLeft; - xr = pArea->xPixRight; - width = xr - xl + 1; - yb = pWin->height - pArea->yPixBot; - yt = pWin->height - pArea->yPixTop; - height = yb - yt; - - wc = 1. + dataShift * pArea->xScale; - if (wc >= width) - wc = width, widP = 0; - else - widP = width - wc - 1; - - if (pArea->linkedTo == NULL) { - if (widP > 0) { /* shift the `preserved' area to the left */ - if (pArea->usePixMap) { - XCopyArea(pWin->pDisp, pArea->pixMap, pArea->pixMap, - pArea->pixMapGC, wc+1, 0, widP, height, 1, 0); - } - else { - XCopyArea(pWin->pDisp, pWin->plotWindow, pWin->plotWindow, - pArea->attr.gc, xl+wc+1, yt+1, widP, height-2, xl+1, yt+1); - } - } - if (wc > 0) { /* clear out the new area on the right */ - if (pArea->usePixMap) { - XFillRectangle(pWin->pDisp, pArea->pixMap, pArea->pixMapGC, - widP+1, 0, wc+1, height); - } - XClearArea(pWin->pDisp, pWin->plotWindow, - xl+widP+1, yt+1, wc-1, height-1, False); - } - if (pArea->usePixMap) { - XCopyArea(pWin->pDisp, pArea->pixMap, pWin->plotWindow, - pArea->pixMapGC, 1, 1, width-2, height-1, xl+1, yt+1); - } - } -/*----------------------------------------------------------------------------- -* Change the scaling by the amount actually shifted. (The amount -* shifted--a whole number of pixels--will usually be somewhat different -* from the amount requested.) -*----------------------------------------------------------------------------*/ - dataShift = wc / pArea->xScale; - pArea->xRight += dataShift; - pArea->xLeft += dataShift; -#endif -} - -/*+/subr********************************************************************** -* NAME pprAreaSetAttr - set attributes for a plot area -* -* DESCRIPTION -* Set individual attributes for a plot area. In most cases, the -* attributes affect the drawing of lines in the plot area. -* -* To use this routine, an attribute code and a corresponding value -* are supplied. The form of the value argument depends on the code. -* -* o PPR_ATTR_CLIP sets the plot area so that line segments which lie -* outside the data area won't be drawn, but will terminate at their -* intersection with the edge of the data area. Clipping can be -* disabled by setting the PPR_ATTR_NOCLIP attribute; the default when -* a plot area is created is no clipping. -* -* pprAreaSetAttr(pArea, PPR_ATTR_CLIP, 0, NULL); -* pprAreaSetAttr(pArea, PPR_ATTR_NOCLIP, 0, NULL); -* -* o PPR_ATTR_COLORNUM selects a color for use in drawing lines in a plot -* area. For monochrome screens, no action is taken. There are -* PPR_NCOLORS colors provided, numbered starting with 1. A colorNum -* of 0 selects black. -* -* int colorNum; -* colorNum = 4; -* pprAreaSetAttr(pArea, PPR_ATTR_COLORNUM, colorNum, NULL); -* -* o PPR_ATTR_BG installs a caller-supplied background pixel value in -* the gc for the plot area. (For use only with X11. Under X11, -* pprAreaOpen initially set the gc for the plot area to have the -* same foreground and background colors as the gc for the plot window.) -* -* pprAreaSetAttr(pArea, PPR_ATTR_BG, 0, &bg); -* -* o PPR_ATTR_FG installs a caller-supplied foreground pixel value in -* the gc for the plot area. (For use only with X11. Under X11, -* pprAreaOpen initially set the gc for the plot area to have the -* same foreground and background colors as the gc for the plot window.) -* -* pprAreaSetAttr(pArea, PPR_ATTR_FG, 0, &fg); -* -* o PPR_ATTR_KEYNUM selects a legend key for identifying lines drawn -* in a plot area, and thus distinguishing them from the lines drawn -* by a different plot area. This is primarily useful for overlapping -* plot areas, where several sets of data are drawn on the same axis. -* The key number, which is expected to be in the range 0 to PPR_NKEYS, -* inclusive, selects either a dashed line pattern or a color, -* depending on the nature of the device on which the plot window -* resides. There are PPR_NKEYS unique patterns and colors; a key -* number of 0 resets to a "plain", solid line. -* -* Use of the PPR_ATTR_KEYNUM option provides a way to restart a -* dashed line pattern at its beginning. -* -* int keyNum; -* keyNum = 4; -* pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, keyNum, NULL); -* -* o PPR_ATTR_LINE_THICK sets the line thickness for the plot area. The -* thickness is the integer number of thousandths of plot window height. -* The thickness is used for data drawing operations. A thickness of -* 0. results in pixel-thick lines. As an example, a thickness of 10 -* represents 10/1000 (or .01) of the window height. -* -* int thick; -* thick = 3; .003 of window height -* pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); -* -* o PPR_ATTR_PATT_ARRAY installs a caller-supplied dashed line pattern -* array. This is an array of type short. The first element -* contains a number of pixels with `pen down'; the second has a -* number of pixels with `pen up'; the third with `pen down'; etc. -* Following the last element must be an element with a value of 0 . -* (pprAreaSetAttr stores only a pointer to the array, so the caller -* must preserve the array until pprAreaClose is called or until -* pprAreaSetAttr is called to `de-install' the pattern array.) An -* array pointer of NULL resets the plot area back to normal drawing. -* -* short pattern[]={16,4,2,4,0}; -* pprAreaSetAttr(pArea, PPR_ATTR_PATT_ARRAY, 0, pattern); -* -* If one of the ppr...Erase routines is to be used in conjunction -* with a dashed line pattern, then the sequence of operations for -* erasing must be made the same as the sequence of operations for -* the original drawing. -* -* o PPR_ATTR_STRIP sets up the plot area so that the data area is -* a pixmap. When lines are drawn in the data area, they are -* also drawn in the pixmap. When pprAreaShiftLeft is called, the -* pixmap is shifted and then copied to the screen. (This approach -* is needed to properly handle the case where the data area is -* partially obscured by another window.) -* -* There are tradeoffs for using this attribute. Strip charts with -* a single channel work relatively well either with or without this -* attribute. Strip charts with multiple channels (i.e., those with -* overlapping plot areas) must use this attribute; the second and -* following plot areas will specify the first one as a `link'. -* -* advantages disadvantages -* o shifting always works o more X traffic is generated -* properly o more CPU time is used for -* o overlapping plot areas plotting, since plotting -* work properly goes to both screen and pixmap -* -* pprAreaSetAttr(pArea, PPR_ATTR_STRIP, 1, NULL); -* pprAreaSetAttr(pArea1, PPR_ATTR_STRIP, 1, pArea); -* pprAreaSetAttr(pArea2, PPR_ATTR_STRIP, 1, pArea); -* -* -* -* Some pprXxx routines don't use the attributes from the plot -* area, but instead use the `generic' attributes from the -* plot window structure. The pprLineSegx_wc and pprMovex_wc -* routines provide an explicit mechanism for using the plot window -* attributes. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* BUGS -* o color is supported only for X -* o when color is used, ALL output for the plot area is colored; it's -* not clear yet whether this is a bug or a feature. -* o line thickness doesn't operate consistently under SunView -* -* SEE ALSO -* pprAreaOpen -* -*-*/ -long -pprAreaSetAttr(pArea, code, arg, pArg) -PPR_AREA *pArea; /* I pointer to plot area structure */ -PPR_ATTR_CODE code; /* I attribute code: one of PPR_ATTR_xxx */ -int arg; /* I attribute value, or 0 */ -void *pArg; /* I pointer to attribute, or NULL */ -{ - int keyNum, colorNum; - PPR_WIN *pWin; -#ifdef XWINDOWS - int screenNo; - Colormap cmap; - XColor color, rgbDb; -#endif - - if (code == PPR_ATTR_CLIP) { - pArea->attr.clip = 1; - return 0; - } - if (code == PPR_ATTR_NOCLIP) { - pArea->attr.clip = 0; - return 0; - } - if (code == PPR_ATTR_COLORNUM) { -#ifdef XWINDOWS - pWin = pArea->pWin; - if (pWin->winType != PPR_WIN_SCREEN) - return 0; - colorNum = arg; - if (colorNum == 0) - XCopyGC(pWin->pDisp, pWin->attr.gc, GCForeground, pArea->attr.gc); - else { - screenNo = DefaultScreen(pWin->pDisp); - colorNum = (colorNum - 1) % PPR_NCOLORS; - if (!pprWinIsMono(pWin)) { - cmap = DefaultColormap(pWin->pDisp, screenNo); - if (XAllocNamedColor(pWin->pDisp, cmap, pglPprColor[colorNum], - &color, &rgbDb)) { - XSetForeground(pWin->pDisp,pArea->attr.gc,color.pixel); - } - else - return -1; - } - } -#endif - return 0; - } - if (code == PPR_ATTR_BG) { -#ifdef XWINDOWS - pWin = pArea->pWin; - if (pWin->winType != PPR_WIN_SCREEN) - return 0; - XSetBackground(pWin->pDisp, pArea->attr.gc, *(unsigned long *)pArg); -#endif - return 0; - } - if (code == PPR_ATTR_FG) { -#ifdef XWINDOWS - pWin = pArea->pWin; - if (pWin->winType != PPR_WIN_SCREEN) - return 0; - XSetForeground(pWin->pDisp, pArea->attr.gc, *(unsigned long *)pArg); -#endif - return 0; - } - if (code == PPR_ATTR_KEYNUM) { - keyNum = arg; - pWin = pArea->pWin; - if (keyNum == 0) { - pArea->attr.pPatt = NULL; -#ifdef XWINDOWS - if (pWin->winType == PPR_WIN_SCREEN) - XCopyGC(pWin->pDisp,pWin->attr.gc,GCForeground,pArea->attr.gc); -#endif - } - else { - keyNum = (keyNum - 1) % PPR_NKEYS; -#ifdef XWINDOWS - if (pWin->winType == PPR_WIN_SCREEN) { - screenNo = DefaultScreen(pWin->pDisp); - if (!pprWinIsMono(pWin)) { - cmap = DefaultColormap(pWin->pDisp, screenNo); - if (XAllocNamedColor(pWin->pDisp, cmap, pglPprColor[keyNum], - &color, &rgbDb)) { - - XSetForeground(pWin->pDisp,pArea->attr.gc,color.pixel); - pArea->attr.pPatt = NULL; - return 0; - } - } - } -#endif -#if 0 - if (keyNum == 0) { - pArea->attr.pPatt = NULL; - return 0; - } -#endif - pArea->attr.pPatt = pglPprPat[keyNum]; - pArea->attr.sub = 0; - pArea->attr.rem = pArea->attr.pPatt[0]; - pArea->attr.pen = 1; - } - return 0; - } - if (code == PPR_ATTR_LINE_THICK) { - - pArea->attr.lineThick = arg; - return 0; - } - if (code == PPR_ATTR_COLORNUM) { -#ifdef XWINDOWS - pWin = pArea->pWin; - if (pWin->winType != PPR_WIN_SCREEN) - return 0; - colorNum = arg; - if (colorNum == 0) - XCopyGC(pWin->pDisp, pWin->attr.gc, GCForeground, pArea->attr.gc); - else { - colorNum = (colorNum - 1) % PPR_NCOLORS; - screenNo = DefaultScreen(pWin->pDisp); - if (!pprWinIsMono(pWin)) { - cmap = DefaultColormap(pWin->pDisp, screenNo); - if (XAllocNamedColor(pWin->pDisp, cmap, pglPprColor[colorNum], - &color, &rgbDb)) { - XSetForeground(pWin->pDisp,pArea->attr.gc,color.pixel); - } - else - return -1; - } - } -#endif - return 0; - } - if (code == PPR_ATTR_PATT_ARRAY) { - pArea->attr.pPatt = (short *)pArg; - if (pArg != NULL) { - pArea->attr.sub = 0; - pArea->attr.rem = pArea->attr.pPatt[0]; - pArea->attr.pen = 1; - } - return 0; - } - if (code == PPR_ATTR_STRIP) { -#ifdef XWINDOWS - pWin = pArea->pWin; - if (pWin->winType != PPR_WIN_SCREEN) - return 0; - if (pArea->linkedTo == NULL) { - if (pArea->pixMap != NULL) - XFreePixmap(pWin->pDisp, pArea->pixMap); - if (pArea->stipple != NULL) - XFreePixmap(pWin->pDisp, pArea->stipple); - if (pArea->pixMapGC != NULL) - XFreeGC(pWin->pDisp, pArea->pixMapGC); - } - if (arg != 0) { - static char stipple[8]={0,0,0,0,0,0,0,0}; - - pArea->usePixMap = 1; - if (pArg != NULL) { - PPR_AREA *pArea1=(PPR_AREA *)pArg; - pArea->pixMapWidth = pArea1->pixMapWidth; - pArea->pixMapHeight = pArea1->pixMapHeight; - pArea->pixMap = pArea1->pixMap; - pArea->pixMapGC = pArea1->pixMapGC; - pArea->stipple = pArea1->stipple; - pArea->linkedTo = pArea1; - return 0; - } - pArea->pixMapWidth = pArea->xPixRight - pArea->xPixLeft + 1; - pArea->pixMapHeight = pArea->yPixTop - pArea->yPixBot + 2; - pArea->pixMap = XCreatePixmap(pWin->pDisp, pWin->plotWindow, - pArea->pixMapWidth, pArea->pixMapHeight, - DefaultDepth(pWin->pDisp, DefaultScreen(pWin->pDisp))); - PprAssertAlways(pArea->pixMap != NULL); - pArea->pixMapGC = XCreateGC(pWin->pDisp, pWin->plotWindow, 0, NULL); - PprAssertAlways(pArea->pixMapGC != NULL); - XCopyGC(pWin->pDisp, pArea->attr.gc, - GCBackground|GCForeground, pArea->pixMapGC); - XSetFunction(pWin->pDisp, pArea->pixMapGC, GXcopy); - pArea->stipple = XCreatePixmapFromBitmapData(pWin->pDisp, - pArea->pixMap, stipple, 8, 8, 1, 0, 1); - PprAssertAlways(pArea->stipple != NULL); - XSetStipple(pWin->pDisp, pArea->pixMapGC, pArea->stipple); - XSetFillStyle(pWin->pDisp, pArea->pixMapGC, FillOpaqueStippled); - XFillRectangle(pWin->pDisp, pArea->pixMap, pArea->pixMapGC, - 0, 0, pArea->pixMapWidth+1, pArea->pixMapHeight+1); - } - else { - pArea->usePixMap = 0; - pArea->linkedTo = NULL; - } -#endif - return 0; - } - return -1; -} - -/*+/subr********************************************************************** -* NAME pprAutoEnds - choose `clean' endpoint valuess for an axis -* -* DESCRIPTION -* For a specific numeric range, this routine calculates a possibly -* altered numeric range which will produce more tasteful axis -* calibration. -* -* RETURNS -* void -* -* BUGS -* o this routine should probably focus some attention on choice of -* number of intervals for an axis; presently, the new endpoints -* chosen by this routine may be difficult to use for choosing -* interval size -* o uses exp10(), which doesn't exist in VxWorks -* o only linear calibration is handled -* -* SEE ALSO -* pprAutoInterval, pprAutoRange, pprAreaOpen -* -*-*/ -void -pprAutoEnds(left, right, pLeftNew, pRightNew) -double left; /* I leftmost value */ -double right; /* I rightmost value */ -double *pLeftNew; /* O new leftmost value */ -double *pRightNew; /* O new rightmost value */ -{ - double x1, x2, x1a, x2a, exp1, exp2, new1, new2; - double pwr1, pwr2, pwr; - - if (left == right) { - if (left == 0.) { - left = -1.; - right = 1.; - } - else if (left < 0.) { - left -= 1.; - right = 0.; - } - else { - left = 0.; - right += 1.; - } - } - -/*----------------------------------------------------------------------------- -* if axis if "reversed", temporarily put it "normal", to make life easy -*----------------------------------------------------------------------------*/ - if (left > right) { x1 = right; x2 = left; } - else { x1 = left; x2 = right; } - -/*----------------------------------------------------------------------------- -* now, find a reasonable place to round each end to; the larger magnitude -* number controls to what "boundary" to round. Use absolute values in -* the sleuthing. -*----------------------------------------------------------------------------*/ - x1a = x1 >= 0. ? x1 : -x1; - if (x1a == 0.) - pwr1 = x1a; - else - pwr1 = exp10((double)((int)log10(x1a))); - x2a = x2 >= 0. ? x2 : -x2; - if (x2a == 0.) - pwr2 = x2a; - else - pwr2 = exp10((double)((int)log10(x2a))); - pwr = pwr1>pwr2 ? pwr1 : pwr2; - -/*----------------------------------------------------------------------------- -* actually do the rounding; and restore the values' original signs -*----------------------------------------------------------------------------*/ - if (x1 < 0.) { new1 = (1+(int)(x1a/pwr-.0001)) * pwr; new1 = -new1; } - else new1 = ((int)(x1a/pwr-.0001)) * pwr; - - if (x2 < 0.) { new2 = ((int)(x2a/pwr-.0001)) * pwr; new2 = -new2; } - else new2 = (1+(int)(x2a/pwr-.0001)) * pwr; - -/*----------------------------------------------------------------------------- -* unscramble if input was "reversed"; and give values to caller -*----------------------------------------------------------------------------*/ - if (left < right) { - *pLeftNew = new1; - *pRightNew = new2; - } - else { - *pLeftNew = new2; - *pRightNew = new1; - } -} - -/*+/subr********************************************************************** -* NAME pprAutoInterval - figure out good interval size for an axis -* -* DESCRIPTION -* Determine a "good" interval size for an axis, so that axis -* annotation will be tasteful. -* -* RETURNS -* void -* -* BUGS -* o this routine always chooses to divide an axis into 5 intervals -* o only linear calibration is handled -* -* SEE ALSO -* pprAutoEnds, pprAutoRange, pprAreaOpen -* -*-*/ -void -pprAutoInterval(val1, val2, pNint) -double val1; /* I value at one end of axis */ -double val2; /* I value at other end of axis */ -int *pNint; /* O number of intervals */ -{ -#define PPR_EQ(v1, v2) PprAbs((v2)-(v1)) <= slop - - double vmin, vmax; - double slop; /* differences no larger mean == */ - double diff, ratio, aint; - int nInt; - - slop = PprAbs(val2 - val1); - - vmin = PprMin(val1, val2); - vmax = PprMax(val1, val2); - - if (PPR_EQ(vmin, 0.)) - /* pprAutoInt(vmax, &nInt); */ - ; - else if (PPR_EQ(vmax, 0.)) - /* pprAutoInt(vmin, &nInt); */ - ; - else if (vmin < 0. && vmax > 0.) { - ; - } - nInt = 5.; - *pNint = nInt; -} - -/*+/macro********************************************************************* -* NAME pprAutoRange - find minimum and maximum values for an array -* -* DESCRIPTION -* Finds the minimum and maximum values in an array of values. -* -* Four different routines are available, depending on the type of -* the input array. Each returns the min and max as a double: -* -* void pprAutoRangeD(doubleArray, nPoints, doubleMin, doubleMax) -* void pprAutoRangeF(floatArray, nPoints, doubleMin, doubleMax) -* void pprAutoRangeL(longArray, nPoints, doubleMin, doubleMax) -* void pprAutoRangeS(shortArray, nPoints, doubleMin, doubleMax) -* -* RETURNS -* void -* -* SEE ALSO -* pprAutoEnds, pprAutoInterval, pprAreaOpen -* -*-*/ -void pprAutoRangeD(dblArray, npts, dblMin, dblMax) -double *dblArray; /* I data value array */ -int npts; /* I number of data points */ -double *dblMin; /* O minimum value in array */ -double *dblMax; /* O maximum value in array */ -{ - int i; - - *dblMin = *dblMax = dblArray[0]; - for (i=1; i dblArray[i]) *dblMin = dblArray[i]; - if (*dblMax < dblArray[i]) *dblMax = dblArray[i]; - } -} -void pprAutoRangeF(fltArray, npts, dblMin, dblMax) -float *fltArray; /* I data value array */ -int npts; /* I number of data points */ -double *dblMin; /* O minimum value in array */ -double *dblMax; /* O maximum value in array */ -{ - int i; - *dblMin = *dblMax = fltArray[0]; - for (i=1; i fltArray[i]) *dblMin = fltArray[i]; - if (*dblMax < fltArray[i]) *dblMax = fltArray[i]; - } -} -void pprAutoRangeL(lngArray, npts, dblMin, dblMax) -long *lngArray; /* I data value array */ -int npts; /* I number of data points */ -double *dblMin; /* O minimum value in array */ -double *dblMax; /* O maximum value in array */ -{ - int i; - *dblMin = *dblMax = lngArray[0]; - for (i=1; i lngArray[i]) *dblMin = lngArray[i]; - if (*dblMax < lngArray[i]) *dblMax = lngArray[i]; - } -} -void pprAutoRangeS(shtArray, npts, dblMin, dblMax) -short *shtArray; /* I data value array */ -int npts; /* I number of data points */ -double *dblMin; /* O minimum value in array */ -double *dblMax; /* O maximum value in array */ -{ - int i; - *dblMin = *dblMax = shtArray[0]; - for (i=1; i shtArray[i]) *dblMin = shtArray[i]; - if (*dblMax < shtArray[i]) *dblMax = shtArray[i]; - } -} - -static int pprTrigInit=0; -static double pprCos[361]; /* cos for 0-90, in .25 steps */ -/*+/subr********************************************************************** -* NAME pprCos_deg - get the cosine of an angle in degrees -* -* DESCRIPTION -* Get the cosine of an angle in degrees. A table lookup technique -* is used. The angle argument is truncated to the next lower 1/4 -* degree prior to lookup. -* -* RETURNS -* cosine -* -*-*/ -double -pprCos_deg(angle) -double angle; /* I angle, in degrees */ -{ - int indx; - double cosine; - - if (!pprTrigInit) { - int i; - double angle; - - pprTrigInit = 1; - for (i=0; i<=360; i++) { - angle = (double)i / 4. * .017453292; - pprCos[i] = cos(angle); - } - } - indx = angle * 4.; - if (indx < 0) - indx = -indx; - if (indx >= 1440) - indx %= 1440; - if (indx <= 360) - cosine = pprCos[indx]; - else if ((indx -= 360) <= 360) - cosine = -pprCos[360 - indx]; - else if ((indx -= 360) <= 360) - cosine = -pprCos[indx]; - else { - indx -= 360; - cosine = pprCos[360 - indx]; - } - return cosine; -} - -/*+/subr********************************************************************** -* NAME pprChar - plot a character -* -* DESCRIPTION -* Plots a single text character at a location. The center of the -* character is placed at the specified x,y position. -* -* The character height specification is in terms of a fraction of the -* height of the window. This results in automatic scaling of -* character sizes as the window size changes. If a height of zero -* is specified in the call, then the default height for the plot -* area is used. (The default height was established by pprAreaOpen.) -* -* A macro is available which returns the default character height -* used by this plot package. The value returned is proportional to -* the height of the plot area. This value can be used to generate -* "big" and "small" character sizes. -* -* PprDfltCharHt(lowYfrac, highYfrac) -* -* lowYfrac is the vertical fraction of the window at which -* the bottom edge of the plot area lies -* highYfrac is the vertical fraction of the window at which -* the top edge of the plot area lies -* -* RETURNS -* void -* -* BUGS -* o technique used works only with linear axes -* o ASCII character codes are assumed -* o no checks are made for illegal characters -* -* SEE ALSO -* pprText, pprAreaOpen, pprLine, pprPoint -* -*-*/ -void -pprChar(pArea, x, y, chr, height, angle) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate of character */ -double y; /* I y data coordinate of character */ -char chr; /* I character to plot */ -double height; /* I height of character, as a fraction of - the height of the window; a value of - zero results in using a default height */ -double angle; /* I orientation angle of character, ccw degrees */ -{ - double xWin, yWin; - double scale; /* convert character units to win coord */ - double cosT, sinT; - char str[2]; - - if (height <= 0.) - height = pArea->charHt; - else - height *= pArea->pWin->height; - xWin = pArea->xPixLeft + .5 + (x - pArea->xLeft) * pArea->xScale; - yWin = pArea->yPixBot + .5 + (y - pArea->yBot) * pArea->yScale; - - if (pArea->pWin->winType == PPR_WIN_SCREEN) { - if (angle == 0.) cosT = 1., sinT = 0.; - else if (angle == 90.) cosT = 0., sinT = 1.; - else { cosT = pprCos_deg(angle); - sinT = pprSin_deg(angle); - } - scale = height / 6.; - pprText1(pArea, - xWin, yWin, chr, 0, scale, sinT, cosT, pprLineSegPixD_ac); - } - else { - height = 1.5 * height; - str[0] = chr; - str[1] = '\0'; - pprTextPS(pArea->pWin->file, xWin, yWin,PPR_TXT_CEN,str,height,angle); - } -} - -/*+/subr********************************************************************** -* NAME pprCvtDblToTxt - convert double to text, being STINGY with space -* -* DESCRIPTION -* Convert a double value to text. The main usefulness of this routine -* is that it maximizes the amount of information presented in a -* minimum number of characters. For example, if a 1 column width -* is specified, only the sign of the value is presented. -* -* A secondary usefulness of this routine is that for small numbers -* it uses the last argument as a number of significant digits rather -* than as the number of decimal places. -* -* When an exponent is needed to represent the value, for narrow -* column widths only the exponent appears. If there isn't room -* even for the exponent, large positive exponents will appear as E*, -* and large negative exponents will appear as E-. -* -* Negative numbers receive some special treatment. In narrow -* columns, very large negative numbers may be represented as - and -* very small negative numbers may be represented as -. or -.E- . -* -* Some example outputs follow (with 3 decimal places assumed): -* -* value printed values for column widths -* 1 2 3 4 5 6 7 -* -* 0.000 0 0 0 0 0 0 0 -* -1.000 - -1 -1 -1 -1 -1 -1 -* 0.123 + E- .12 .123 .123 .123 .123 -* -0.00123 - -. -. -.E- -1E-3 -12E-4 -123E-5 -* -12.3 - - -12 -12 -12.3 -12.30 -12.300 -* 123 + E2 123 123 123.0 123.00 123.000 -* -*-*/ -void -pprCvtDblToTxt(text, width, value, sigDig) -char *text; /* O text representation of value */ -int width; /* I max width of text string (not counting '\0') */ -double value; /* I value to print */ -int sigDig; /* I max # of dec places to print */ -{ - double valAbs; /* absolute value of caller's value */ - int wholeNdig; /* number of digits in "whole" part of value */ - double logVal; /* log10 of value */ - int decPlaces; /* number of decimal places to print */ - int expI; /* exponent for frac values */ - double expD; - int expWidth; /* width needed for exponent field */ - int excess; /* number of low order digits which - won't fit into the field */ - char tempText[100]; /* temp for fractional conversions */ - int roomFor; - int minusWidth; /* amount of room for - sign--0 or 1 */ - double temp; - -/*----------------------------------------------------------------------------- -* special cases -*----------------------------------------------------------------------------*/ -#define D1 .000000001 - - if (value >= 0.) { - for (temp=0.; temp<=9.; temp+=1.) { - if (value >= temp-D1 && value <= temp+D1) { - sprintf(text, "%.0f", temp); - return; - } - } - } - if (width == 1) { - if (value >= 0) - strcpy(text, "+"); - else - strcpy(text, "-"); - return; - } - else if (value < 0.) { - for (temp=-1.; temp>=-9.; temp-=1.) { - if (value >= temp-D1 && value <= temp+D1) { - sprintf(text, "%.0f", temp); - return; - } - } - } - else if (width == 2 && value < -1.) { - strcpy(text, "-"); - return; - } - - valAbs = value>0. ? value : -value; - logVal = log10(valAbs); - strcpy(tempText, " "); - if (logVal < 0.) { -/*----------------------------------------------------------------------------- -* numbers with only a fractional part -*----------------------------------------------------------------------------*/ - if (width == 2) { - if (value > 0.) - strcpy(tempText, "0E-"); - else - strcpy(tempText, "0-."); - } - else if (width == 3 && value < 0) - strcpy(tempText, "0-."); - else { - if (value < 0.) - minusWidth = 1; - else - minusWidth = 0; - if (logVal >= -1.) - expI = -1 * ceil(logVal); - else - expI = sigDig - ceil(logVal); - if (expI < 9) expWidth = 3; /* need E-n */ - else if (expI < 99) expWidth = 4; /* need E-nn */ - else if (expI < 999) expWidth = 5; /* need E-nnn */ - else expWidth = 6; /* need E-nnnn */ -/*----------------------------------------------------------------------------- -* figure out how many significant digits can appear. For numbers between -* .1 and .999, a . will be printed; for numbers between 0. and .0999, -* no . will be printed, and number will be normalized. -*----------------------------------------------------------------------------*/ - if (logVal >= -1.) - roomFor = width - expI - 1 - minusWidth; - else - roomFor = width - expWidth - minusWidth; - if (roomFor >= 1 && logVal >= -1.) { - decPlaces = expI + sigDig; - if (decPlaces > width -1 - minusWidth) - decPlaces = roomFor + expI; - if (decPlaces > sigDig) - decPlaces = sigDig; - (void)sprintf(tempText, "%.*f", decPlaces, value); - if (value < 0.) - tempText[1] = '-'; - } - else if (roomFor >= 1) { - long t; - if (roomFor < sigDig) - expI -= (sigDig - roomFor); - else - roomFor = sigDig; - t = value * exp10((double)expI); - (void)sprintf(&tempText[1], "%dE-%d", t, expI); - } - else { - expD = expI; - value *= exp10(expD); - if (value > 0.) - sprintf(tempText, "0.E-%d", expI); - else - sprintf(tempText, "--.E-%d", expI); - } - } - - if (strlen(tempText) > 1) - strncpy(text, &tempText[1], width); - else - strcpy(text, tempText); - text[width] = '\0'; - return; - } - -/*----------------------------------------------------------------------------- -* numbers with both an integer and a fractional part -* -* find out how many columns are required to represent the integer part -* of the value. A - is counted as a column; the . isn't. -*----------------------------------------------------------------------------*/ - wholeNdig = 1 + (int)logVal; - if (value < 0.) - wholeNdig++; - if (wholeNdig < width-1) { -/*----------------------------------------------------------------------------- -* the integer part fits well within the field. Find out how many -* decimal places can be printed (honoring caller's sigDig limit). -*----------------------------------------------------------------------------*/ - decPlaces = width - wholeNdig - 1; - if (sigDig < decPlaces) - decPlaces = sigDig; - if (sigDig > 0) - (void)sprintf(text, "%.*f", decPlaces, value); - else - (void)sprintf(text, "%d", nint(value)); - } - else if (wholeNdig == width || wholeNdig == width-1) { -/*----------------------------------------------------------------------------- -* The integer part just fits within the field. Print the value as an -* integer, without printing the superfluous decimal point. -*----------------------------------------------------------------------------*/ - (void)sprintf(text, "%d", nint(value)); - } - else { -/*----------------------------------------------------------------------------- -* The integer part is too large to fit within the caller's field. Print -* with an abbreviated E notation. -*----------------------------------------------------------------------------*/ - expWidth = 2; /* assume that En will work */ - excess = wholeNdig - (width - 2); - if (excess > 999) { - expWidth = 5; /* no! it must be Ennnn */ - excess += 3; - } - else if (excess > 99) { - expWidth = 4; /* no! it must be Ennn */ - excess += 2; - } - else if (excess > 9) { - expWidth = 3; /* no! it must be Enn */ - excess += 1; - } -/*----------------------------------------------------------------------------- -* Four progressively worse cases, with all or part of exponent fitting -* into field, but not enough room for any of the value -* Ennn positive value; exponent fits -* -Ennn negative value; exponent fits -* +**** positive value; exponent too big -* -**** negative value; exponent too big -*----------------------------------------------------------------------------*/ - if (value >= 0. && expWidth == width) - (void)sprintf(text, "E%d", nint(logVal)); - else if (value < 0. && expWidth == width-1) - (void)sprintf(text, "-E%d", nint(logVal)); - else if (value > 0. && expWidth > width) - (void)sprintf(text, "%.*s", width, "+*******"); - else if (value < 0. && expWidth > width-1) - (void)sprintf(text, "%.*s", width, "-*******"); - else { -/*----------------------------------------------------------------------------- -* The value can fit, in exponential notation -*----------------------------------------------------------------------------*/ - (void)sprintf(text, "%dE%d", - nint(value/exp10((double)excess)), excess); - } - } -} - -/*+/subr********************************************************************** -* NAME pprErrorBar - plot an error bar -* -* DESCRIPTION -* Plot a line between the endpoints and draw end caps, using the color -* attribute of the plot area. Other plot area attributes are ignored. -* -* RETURNS -* void -* -* BUGS -* o only linear calibration is handled -* -* SEE ALSO -* pprLine, pprMove, pprPoint, pprText -* -*-*/ -void -pprErrorBar(pArea, x1, y1, x2, y2) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x1; /* I first x point */ -double y1; /* I first y point */ -double x2; /* I second x point */ -double y2; /* I second y point */ -{ - pprLineSegD_ac(pArea, x1, y1, x2, y2); - if (x1 == x2) { - pprMarkD(pArea, x1, y1, -1); - pprMarkD(pArea, x2, y2, -1); - } - else { - pprMarkD(pArea, x1, y1, -2); - pprMarkD(pArea, x2, y2, -2); - } -} - -/*+/subr********************************************************************** -* NAME pprGrid - draw a grid -* -* DESCRIPTION -* Draw a perimeter and grid lines. The number of intervals -* specified in the plot area structure is used for placing -* the grid lines. -* -* The color attributes for the plot window are used for drawing; -* dashed line and line thickness are ignored. -* -* RETURNS -* void -* -* BUGS -* o only linear axes are handled -* -* SEE ALSO -* pprGridLabel, pprGridErase, pprPerim, pprAnnotX, pprAnnotY, pprAreaOpen -* -*-*/ -void -pprGrid(pArea) -PPR_AREA *pArea; /* I pointer to plot area structure */ -{ - int i; - double x, y; - static short patt[]={1, 14, 0}; - -/*----------------------------------------------------------------------------- -* draw the box -*----------------------------------------------------------------------------*/ - pprMoveD_wc(pArea, pArea->xLeft, pArea->yBot, 0); - pprMoveD_wc(pArea, pArea->xRight, pArea->yBot, 1); - pprMoveD_wc(pArea, pArea->xRight, pArea->yTop, 1); - pprMoveD_wc(pArea, pArea->xLeft, pArea->yTop, 1); - pprMoveD_wc(pArea, pArea->xLeft, pArea->yBot, 1); -/*----------------------------------------------------------------------------- -* draw the vertical grid lines -*----------------------------------------------------------------------------*/ - x = pArea->xLeft; - for (i=1; ixNint; i++) { - x += pArea->xInterval; - pprLineSegDashD_wc(pArea, x, pArea->yBot, x, pArea->yTop, patt); - } -/*----------------------------------------------------------------------------- -* ditto for y axis -*----------------------------------------------------------------------------*/ - y = pArea->yBot; - for (i=1; iyNint; i++) { - y += pArea->yInterval; - pprLineSegDashD_wc(pArea, pArea->xLeft, y, pArea->xRight, y, patt); - } -} - -/*+/subr********************************************************************** -* NAME pprGridErase - erase within a grid -* -* DESCRIPTION -* Erases the screen inside the grid for the plot area. (Actually, -* the entire data area is erased and then the grid is redrawn.) -* -* RETURNS -* void -* -* SEE ALSO -* pprPerimErase, pprAreaErase, pprWinErase, pprRegionErase -* the ppr...Erase... entry points for the various drawing routines -* -*-*/ -void -pprGridErase(pArea) -PPR_AREA *pArea; /* I pointer to plot area structure */ -{ - int x,y,width,height; - - if (pArea->pWin->winType != PPR_WIN_SCREEN) - return; - x = pArea->xPixLeft - 3; - y = pArea->yPixBot - 3; - width = (pArea->xRight - pArea->xLeft) * pArea->xScale + 6; - height = (pArea->yTop - pArea->yBot) * pArea->yScale + 6; -#ifdef SUNVIEW - y = pArea->pWin->height - y - height; - pw_writebackground(pArea->pWin->pw, x, y, width, height, PIX_SRC); - pprGrid(pArea); -#else -#if defined XWINDOWS - y = pArea->pWin->height - y - height; - XClearArea(pArea->pWin->pDisp, pArea->pWin->plotWindow, - x, y, width, height, False); - if (pArea->pixMap != NULL) { - XFillRectangle(pArea->pWin->pDisp, pArea->pixMap, pArea->pixMapGC, - 0, 0, pArea->pixMapWidth+1, pArea->pixMapHeight+1); - } - pprGrid(pArea); - XFlush(pArea->pWin->pDisp); -#endif -#endif -} - -/*+/subr********************************************************************** -* NAME pprGridLabel - draw and label a grid -* -* DESCRIPTION -* Draw a perimeter and grid lines. The number of intervals -* specified in the plot area structure is used for placing -* the grid lines. -* -* Axis labels and annotations are drawn using the information from -* the plot area, as specified in the pprAreaOpen call. -* -* RETURNS -* void -* -* BUGS -* o only linear axes are handled -* -* SEE ALSO -* pprGrid, pprPerim, pprAnnotX, pprAnnotY, pprAreaOpen -* -*-*/ -void -pprGridLabel(pArea, xLabel, xAnnot, yLabel, yAnnot, angle) -PPR_AREA *pArea; /* I pointer to plot area structure */ -char *xLabel; /* I label for x axis, or NULL */ -char **xAnnot; /* I pointer to array of x annotations, or NULL */ -char *yLabel; /* I label for y axis, or NULL */ -char **yAnnot; /* I pointer to array of y annotations, or NULL */ -double angle; /* I angle for y annotations; 0. or 90. */ -{ - pprGrid(pArea); - pprAnnotX(pArea, 0, pArea->xLeft, pArea->xRight, pArea->xNint, - 0, xLabel, xAnnot, 0.); - pprAnnotY(pArea, 0, pArea->yBot, pArea->yTop, pArea->yNint, - 0, yLabel, yAnnot, angle); -} - -/*+/subr********************************************************************** -* NAME pprLine - plot a line using x and y data value vectors -* -* DESCRIPTION -* Draw a line along the path specified by two value arrays. -* -* Several entry points are available to accomodate various -* types of data: -* -* pprLineF(pArea, x, y, npts) x and y are float[] -* pprLineD(pArea, x, y, npts) x and y are double[] -* pprLineS(pArea, x, y, npts) x and y are short[] -* pprLineL(pArea, x, y, npts) x and y are long[] -* -* Several entry points are available for erasing: -* -* pprLineEraseF(pArea, x, y, npts) x and y are float[] -* pprLineEraseD(pArea, x, y, npts) x and y are double[] -* pprLineEraseS(pArea, x, y, npts) x and y are short[] -* pprLineEraseL(pArea, x, y, npts) x and y are long[] -* -* RETURNS -* void -* -* BUGS -* o only linear calibration is handled -* -* SEE ALSO -* pprLineSeg, pprMove, pprPoint, pprText -* -*-*/ -void -pprLineF(pArea, x, y, npts) -PPR_AREA *pArea; /* I pointer to plot area structure */ -float *x; /* I x array of data values */ -float *y; /* I y array of data values */ -int npts; /* I number of points to plot */ -{ - int i; - pprMoveD(pArea, (double)(x[0]), (double)(y[0]), 0); - for (i=1; ipWin->winType == PPR_WIN_SCREEN) { -#ifdef SUNVIEW - if (pArea->pWin->brush.width > 1) - pw_line(pArea->pWin->pw, xp0, yp0, xp1, yp1, - &pArea->pWin->brush, &texture, (int)PIX_SRC); - else - pw_vector(pArea->pWin->pw, xp0, yp0, xp1, yp1, PIX_SRC, 1); -#else -#if defined XWINDOWS -/*----------------------------------------------------------------------------- -* !!!! NOTE WELL !!!! Various routines have these plotting statements -* for calling XDrawLine. If you modify the statements here, modify -* the other places too!! -*----------------------------------------------------------------------------*/ - if (xp0 != xp1 || yp0 != yp1) { - XDrawLine(pArea->pWin->pDisp, pArea->pWin->plotWindow, - pArea->attr.gc, xp0, yp0, xp1, yp1); - if (pArea->usePixMap) { - XDrawLine(pArea->pWin->pDisp, pArea->pixMap, pArea->attr.gc, - xp0 - pArea->xPixLeft, - yp0 - (pArea->pWin->height - pArea->yPixTop), - xp1 - pArea->xPixLeft, - yp1 - (pArea->pWin->height - pArea->yPixTop)); - } - } -#endif -#endif - } - else if (pArea->pWin->winType == PPR_WIN_POSTSCRIPT || - pArea->pWin->winType == PPR_WIN_EPS) { - (void)fprintf(pArea->pWin->file, "%d %d %d %d DS\n", - xp0, yp0, xp1, yp1); - } -} - -static void -pprLineSegPixD_wc(pArea, xp0, yp0, xp1, yp1) -PPR_AREA *pArea; -double xp0, xp1, yp0, yp1; /* y must be corrected properly by the caller */ -{ - pprLineSegPixL_wc(pArea, (long)(xp0+.5), (long)(yp0+.5), - (long)(xp1+.5), (long)(yp1+.5)); -} - -static void -pprLineSegPixL_wc(pArea, xp0, yp0, xp1, yp1) -PPR_AREA *pArea; -long xp0, xp1, yp0, yp1; /* y must be corrected properly by the caller - for the windowing system being used. I.e., - most of the pprXxx routines assume 0,0 is - lower left, but X and SunView assume it is - upper left--the caller must have dealt with - this. */ -{ -#ifdef SUNVIEW - if (initTexture) - initTex(); -#endif - if (pArea->pWin->winType == PPR_WIN_SCREEN) { -#ifdef SUNVIEW - if (pArea->pWin->brush.width > 1) - pw_line(pArea->pWin->pw, xp0, yp0, xp1, yp1, - &pArea->pWin->brush, &texture, (int)PIX_SRC); - else - pw_vector(pArea->pWin->pw, xp0, yp0, xp1, yp1, PIX_SRC, 1); -#else -#if defined XWINDOWS - if (xp0 != xp1 || yp0 != yp1) - XDrawLine(pArea->pWin->pDisp, pArea->pWin->plotWindow, - pArea->pWin->attr.gc, xp0, yp0, xp1, yp1); -#endif -#endif - } - else if (pArea->pWin->winType == PPR_WIN_POSTSCRIPT || - pArea->pWin->winType == PPR_WIN_EPS) { - (void)fprintf(pArea->pWin->file, "%d %d %d %d DS\n", - xp0, yp0, xp1, yp1); - } -} - -static void -pprLineSegPixEraseL(pArea, xp0, yp0, xp1, yp1) -PPR_AREA *pArea; -long xp0, xp1, yp0, yp1; /* y must be corrected properly by the caller - for the windowing system being used. I.e., - most of the pprXxx routines assume 0,0 is - lower left, but X and SunView assume it is - upper left--the caller must have dealt with - this. */ -{ -#ifdef SUNVIEW - if (initTexture) - initTex(); -#endif - if (pArea->pWin->winType != PPR_WIN_SCREEN) - return; -#ifdef SUNVIEW - if (pArea->pWin->brush.width > 1) - pw_line(pArea->pWin->pw, xp0, yp0, xp1, yp1, - &pArea->pWin->brush, &texture, (int)(PIX_NOT(PIX_SRC)&PIX_DST)); - else - pw_vector(pArea->pWin->pw, xp0, yp0, xp1, yp1, PIX_SRC, 0); -#else -#if defined XWINDOWS - if (xp0 != xp1 || yp0 != yp1) - XDrawLine(pArea->pWin->pDisp, pArea->pWin->plotWindow, - pArea->pWin->attr.gcBG, xp0, yp0, xp1, yp1); -#endif -#endif -} - -static void -pprLineSegPixEraseD(pArea, xp0, yp0, xp1, yp1) -PPR_AREA *pArea; -double xp0, xp1, yp0, yp1; /* y must be corrected properly by the caller */ -{ - pprLineSegPixEraseL(pArea, (long)(xp0+.5), (long)(yp0+.5), - (long)(xp1+.5), (long)(yp1+.5)); -} - -/*+/internal****************************************************************** -* NAME pprLineSegDashD_wc - drawing a dashed line segment -* -* DESCRIPTION -* Draws a dashed line between the specified points. The dashed line -* starts at the beginning of the specified pattern. The dashes are -* drawn using the plot window color. -* -* (The dashed line attributes for the plot area are neither used nor -* altered.) -* -* No clipping service is provided. -* -* RETURNS -* void -* -*-*/ -static void -pprLineSegDashD_wc(pArea, x0, y0, x1, y1, pPatt) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x0; /* I x data coordinate of first point */ -double y0; /* I y data coordinate of first point */ -double x1; /* I x data coordinate of second point */ -double y1; /* I y data coordinate of second point */ -short *pPatt; /* I pointer to pattern array */ -{ - double xp0,yp0,xp1,yp1; - double xpA,ypA,xpB; - double segLen, endLen, dashLen, xbeg, xend, ybeg, yend; - int pen=0, sub=-1, rem=0; - - xbeg = xp0 = pArea->xPixLeft + .5 + (x0 - pArea->xLeft) * pArea->xScale; - ybeg = yp0 = pArea->yPixBot + .5 + (y0 - pArea->yBot) * pArea->yScale; - if (pArea->pWin->winType == PPR_WIN_SCREEN) - ybeg = yp0 = pArea->pWin->height - yp0; - xp1 = pArea->xPixLeft + .5 + (x1 - pArea->xLeft) * pArea->xScale; - yp1 = pArea->yPixBot + .5 + (y1 - pArea->yBot) * pArea->yScale; - if (pArea->pWin->winType == PPR_WIN_SCREEN) - yp1 = pArea->pWin->height - yp1; - pprLineThick(pArea, pArea->pWin->attr.lineThick); - segLen = sqrt((xp1-xp0)*(xp1-xp0) + (yp1-yp0)*(yp1-yp0)); - endLen = 0.; - while (endLen < segLen) { - if (rem < 1.) { - if ((rem = pPatt[++sub]) <= 0.) { - sub = 0; rem = pPatt[0]; pen = 1; - } - else - pen ^= 1; - } - dashLen = PprMin(rem, segLen-endLen); - endLen += dashLen; - if (PprAbs(endLen-segLen) < .5) - endLen = segLen; - xend = xp0 + endLen/segLen * (xp1 - xp0); - yend = yp0 + endLen/segLen * (yp1 - yp0); - if (pen) { - if (dashLen > 1.) pprLineSegPixD_wc(pArea, xbeg, ybeg, xend, yend); - else { - if (pArea->pWin->winType == PPR_WIN_SCREEN) { -#ifdef SUNVIEW - if (pArea->pWin->attr.ltPix > 1) { - ypA = ybeg; - xpA = xbeg - pArea->pWin->attr.ltPix / 2; - xpB = xpA + pArea->pWin->attr.ltPix - 1; -#else -#if defined XWINDOWS - if (pArea->attr.ltPix > 1) { - ypA = ybeg; - xpA = xbeg - pArea->attr.ltPix / 2; - xpB = xpA + pArea->attr.ltPix - 1; -#endif -#endif - /* for thick lines, draw a square 'blob' */ - pprLineSegPixD_wc(pArea, xpA, ypA, xpB, ypA); - } - else { -#ifdef SUNVIEW - pw_put(pArea->pWin->pw, (int)xbeg, (int)ybeg, 1); -#else -#if defined XWINDOWS - XDrawPoint(pArea->pWin->pDisp, pArea->pWin->plotWindow, - pArea->pWin->attr.gc, (int)xbeg, (int)ybeg); -#endif -#endif - } - } - else if (pArea->pWin->winType == PPR_WIN_POSTSCRIPT || - pArea->pWin->winType == PPR_WIN_EPS) { - (void)fprintf(pArea->pWin->file,"%.1f %.1f DP\n",xbeg,ybeg); - } - } - } - xbeg = xend; ybeg = yend; - rem -= dashLen; - } -} - -/*+/internal****************************************************************** -* NAME pprLineThick - set line thickness -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o for X, each linewidth ought to have its own gc -* o doesn't work consistently for SunView (especially after first draw) -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -pprLineThick(pArea, thick) -PPR_AREA *pArea; -short thick; /* I thickness in thousandths of window height */ -{ - PPR_WIN *pWin; - double lt; /* line thickness */ - short ltPix; /* line thickness, in pixels */ - - pWin = pArea->pWin; - - if (pWin->winType==PPR_WIN_POSTSCRIPT || pWin->winType==PPR_WIN_EPS) { - if (thick != pWin->attr.ltCurr) { - pWin->attr.ltCurr = thick; - if (thick == 0) lt = .1; - else lt = .001 * thick * pWin->height; - (void)fprintf(pWin->file, "%.1f setlinewidth\n", lt); - } - } - else { -#ifdef SUNVIEW - if (thick != pWin->attr.ltCurr) { - pWin->attr.ltCurr = thick; -#else -#if defined XWINDOWS - if (thick != pArea->attr.ltCurr) { - pArea->attr.ltCurr = thick; -#endif -#endif - if (thick == 0) - ltPix = 1; - else { - lt = .001 * thick * pWin->height; - if (lt < 1.) ltPix = 1; - else ltPix = (int)(lt + .5); - } -#ifdef SUNVIEW - pWin->attr.ltPix = ltPix; - pWin->brush.width = ltPix; -#else -#if defined XWINDOWS - pArea->attr.ltPix = ltPix; - XSetLineAttributes(pWin->pDisp, pArea->attr.gc, ltPix, LineSolid, - CapButt, JoinRound); - if (pArea->pWin->attr.bgGC) { - XSetLineAttributes(pWin->pDisp, pArea->pWin->attr.gcBG, - ltPix, LineSolid, CapButt, JoinRound); - } -#endif -#endif - } - } -} - -/*+/subr********************************************************************** -* NAME pprMarkD - draw a plotting mark -* -* DESCRIPTION -* Draw a plotting mark at the specified point. The color attribute -* (if any) of the plot area is used in drawing the mark. Line -* thickness and dashed line pattern attributes are ignored. -* -* Two entry points are available: -* -* pprMarkD(pArea, x, y, markNum) x and y are double -* pprMarkL(pArea, x, y, markNum) x and y are long -* -* Two additional entry points are available for erasing plotting marks: -* -* pprMarkEraseD(pArea, x, y, markNum) x and y are double -* pprMarkEraseL(pArea, x, y, markNum) x and y are long -* -* RETURNS -* void -* -* NOTES -* 1. Several special mark numbers are available: -* -1 draws a short horizontal line "cap" -* -2 draws a short vertical line "cap" -* -* BUGS -* o only linear calibration is handled -* -* SEE ALSO -* pprLine, pprLineSeg, pprPoint, pprText -* -*-*/ -void -pprMarkD(pArea, x, y, markNum) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate */ -double y; /* I y data coordinate */ -int markNum; /* I mark number--0 to PPR_NMARKS-1, inclusive */ -{ - pprMark_gen(pArea, x, y, markNum, pprLineSegPixL_ac); -} -static -pprMark_gen(pArea, x, y, markNum, drawFn) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate */ -double y; /* I y data coordinate */ -int markNum; /* I mark number--0 to PPR_NMARKS-1, inclusive */ -void (*drawFn)(); /* I function to draw lines, using pixel coordinates */ -{ - short *pMark; - int xp0, xp1, yp0, yp1; - int pen; - - pprLineThick(pArea, pArea->attr.lineThick); - if (markNum >= 0) { - markNum %= PPR_NMARKS; - pMark = pglPprMarkS[markNum]; /* use small marks */ - } - else if (markNum == -1) - pMark = glPprMarkS_hCap; - else if (markNum == -2) - pMark = glPprMarkS_vCap; - xp0 = pArea->xPixLeft + .5 + (x - pArea->xLeft) * pArea->xScale; - yp0 = pArea->yPixBot + .5 + (y - pArea->yBot) * pArea->yScale; - if (pArea->attr.clip) { - if (xp0 < PprMin(pArea->xPixLeft, pArea->xPixRight) || - xp0 > PprMax(pArea->xPixLeft, pArea->xPixRight) || - yp0 < PprMin(pArea->yPixBot, pArea->yPixTop) || - yp0 > PprMax(pArea->yPixBot, pArea->yPixTop)) { - return; - } - } - if (pArea->pWin->winType == PPR_WIN_SCREEN) - yp0 = pArea->pWin->height - yp0; - while (1) { - xp1 = xp0 + *pMark++; - if (pArea->pWin->winType == PPR_WIN_SCREEN) yp1 = yp0 - *pMark++; - else yp1 = yp0 + *pMark++; - pen = *pMark++; - if (pen) { - drawFn(pArea, xp0, yp0, xp1, yp1); - if (pen == 2) - break; - } - xp0 = xp1; - yp0 = yp1; - } -} -void -pprMarkL(pArea, x, y, markNum) -PPR_AREA *pArea; /* I pointer to plot area structure */ -long x; /* I x data coordinate */ -long y; /* I y data coordinate */ -int markNum; /* I mark number--0 to PPR_NMARKS-1, inclusive */ -{ - pprMark_gen(pArea, (double)x, (double)y, markNum, pprLineSegPixL_ac); -} -void -pprMarkEraseD(pArea, x, y, markNum) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate */ -double y; /* I y data coordinate */ -int markNum; /* I mark number--0 to PPR_NMARKS-1, inclusive */ -{ - pprMark_gen(pArea, x, y, markNum, pprLineSegPixEraseL); -} -void -pprMarkEraseL(pArea, x, y, markNum) -PPR_AREA *pArea; /* I pointer to plot area structure */ -long x; /* I x data coordinate */ -long y; /* I y data coordinate */ -int markNum; /* I mark number--0 to PPR_NMARKS-1, inclusive */ -{ - pprMark_gen(pArea, (double)x, (double)y, markNum, pprLineSegPixEraseL); -} - -/*+/internal****************************************************************** -* NAME pprMove_clipPix - adjust line seg ends when doing clipping -* -* RETURNS -* 0 if line segment is plottable, or -* -1 if line segment is totally outside the data area -*-*/ -static int -pprMove_clipPix(pArea, pXp0,pYp0, pXp1,pYp1) -PPR_AREA *pArea; -int *pXp0,*pYp0, *pXp1,*pYp1; -{ - int xp0=*pXp0, xp1=*pXp1, yp0=*pYp0, yp1=*pYp1; - - int xpl=pArea->xPixLeft, xpr=pArea->xPixRight; - int ypb=pArea->yPixBot, ypt=pArea->yPixTop; - int ypeb, ypet; /* "logical" top and bottom pix values */ - int xpmin=PprMin(xp0,xp1), xpmax=PprMax(xp0,xp1); - int ypmin=PprMin(yp0,yp1), ypmax=PprMax(yp0,yp1); - if (pArea->pWin->winType == PPR_WIN_SCREEN) { - ypb = pArea->pWin->height - ypb; - ypt = pArea->pWin->height - ypt; - } - ypeb = PprMin(ypb, ypt); - ypet = PprMax(ypb, ypt); - - if (xpmin > xpr || xpmax < xpl || ypmin > ypet || ypmax < ypeb) - return -1; /* no possible intersection with data area */ - if (xpmin < xpl || xpmax > xpr || ypmin < ypeb || ypmax > ypet) { - /* part of path is outside data area; find intersections */ - if (xp0 == xp1) { /* no intersection with sides */ - if (yp0 < ypeb) yp0 = ypeb; - else if (yp0 > ypet) yp0 = ypet; - if (yp1 < ypeb) yp1 = ypeb; - else if (yp1 > ypet) yp1 = ypet; - } - else if (yp0 == yp1) { /* no intersection with top or bot */ - if (xp0 < xpl) xp0 = xpl; - else if (xp0 > xpr) xp0 = xpr; - if (xp1 < xpl) xp1 = xpl; - else if (xp1 > xpr) xp1 = xpr; - } - else { - double S; /* slope of line to draw */ - int XP0=xp0, XP1=xp1, YP0=yp0, YP1=yp1; - S = (double)(yp1 - yp0) / (double)(xp1 - xp0); - if (XP0 < xpl) - XP0 = xpl, YP0 = yp0 + .5 + (double)(xpl-xp0) * S; - else if (XP0 > xpr) - XP0 = xpr, YP0 = yp0 + .5 + (double)(xpr-xp0) * S; - if (YP0 < ypeb) - YP0 = ypeb, XP0 = xp0 + .5 + (double)(ypeb-yp0)/S; - else if (YP0 > ypet) - YP0 = ypet, XP0 = xp0 + .5 + (double)(ypet-yp0)/S; - if (XP0 < xpl || XP0 > xpr) - return -1; /* no intersection */ - if (XP1 < xpl) - XP1 = xpl, YP1 = yp0 + .5 + (double)(xpl-xp0) * S; - else if (XP1 > xpr) - XP1 = xpr, YP1 = yp0 + .5 + (double)(xpr-xp0) * S; - if (YP1 < ypeb) - YP1 = ypeb, XP1 = xp0 + .5 + (double)(ypeb-yp0)/S; - else if (YP1 > ypet) - YP1 = ypet, XP1 = xp0 + .5 + (double)(ypet-yp0)/S; - if (XP1 < xpl || XP1 > xpr) - return; /* no intersection */ - xp0 = XP0, xp1 = XP1, yp0 = YP0, yp1 = YP1; - } - } - *pXp0 = xp0; *pYp0 = yp0; *pXp1 = xp1; *pYp1 = yp1; - return 0; -} - -/*+/subr********************************************************************** -* NAME pprMoveD - move the pen, possibly drawing a line -* -* DESCRIPTION -* Move the "pen" to the specified point. If the "pen" is "down" -* a line will be drawn. The line attributes of the plot area are -* used in drawing the line. If the attributes indicate a dashed -* line, the current dashed line pattern will be used. -* -* The "clipping" attribute for the plot area is honored only by -* pprMoveD; pprMoveD_ac and pprMoveD_wc never clip lines at the -* data area edges. -* -* Two alternate entry points are available for drawing plain lines, -* ignoring all attributes except color. One uses the color for the -* plot area (pprMoveD_ac); the other uses the plot window color -* (pprMoveD_wc). (As noted above, these routines don't clip.) -* -* pprMoveD_ac(pArea, x, y, pen) x and y are double -* pprMoveD_wc(pArea, x, y, pen) x and y are double -* -* An additional entry point is available for erasing: -* -* pprMoveEraseD(pArea, x, y) x and y are double -* -* RETURNS -* void -* -* BUGS -* o only linear calibration is handled -* -* SEE ALSO -* pprLine, pprLineSeg, pprText -* -*-*/ -void -pprMoveD(pArea, x, y, pen) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate of new point */ -double y; /* I y data coordinate of new point */ -int pen; /* I pen indicator--non-zero draws a line */ -{ - pprMoveD_gen(pArea, x, y, pen, pprLineSegPixL_ac); -} - - -pprMoveD_gen(pArea, x, y, pen, drawFn) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate of new point */ -double y; /* I y data coordinate of new point */ -int pen; /* I pen indicator--non-zero draws a line */ -void (*drawFn)(); /* I pointer to function to use in drawing */ -{ - short *pXPix=&pArea->xPix, *pYPix=&pArea->yPix; - int xp0, xp1, yp0, yp1; - double segLen, endLen, dashLen, xbeg, xend, ybeg, yend; - PPR_WIN *pWin=pArea->pWin; - - xp0 = *pXPix; - yp0 = *pYPix; - xp1 = pArea->xPixLeft + .5 + (x - pArea->xLeft) * pArea->xScale; - yp1 = pArea->yPixBot + .5 + (y - pArea->yBot) * pArea->yScale; - if (pWin->winType == PPR_WIN_SCREEN) - yp1 = pWin->height - yp1; - *pXPix = xp1; /* store _real_ coord, not the _clipped_ one */ - *pYPix = yp1; - if (pen) { - pprLineThick(pArea, pArea->attr.lineThick); - if (pArea->attr.clip) { - if (pprMove_clipPix(pArea, &xp0,&yp0, &xp1,&yp1) < 0) - return; - } - if (pArea->attr.pPatt == NULL) { -#if defined XWINDOWS -/*----------------------------------------------------------------------------- -* !!!! NOTE WELL !!!! Various routines have these plotting statements -* for calling XDrawLine. If you modify the statements here, modify -* the other places too!! -*----------------------------------------------------------------------------*/ - if (drawFn == pprLineSegPixL_ac) { - if (pWin->winType == PPR_WIN_SCREEN) { - if (xp0 != xp1 || yp0 != yp1) - XDrawLine(pWin->pDisp, pWin->plotWindow, - pArea->attr.gc, xp0, yp0, xp1, yp1); - if (pArea->usePixMap) { - XDrawLine(pArea->pWin->pDisp, - pArea->pixMap, pArea->attr.gc, - xp0 - pArea->xPixLeft, - yp0 - (pArea->pWin->height - pArea->yPixTop), - xp1 - pArea->xPixLeft, - yp1 - (pArea->pWin->height - pArea->yPixTop)); - } - } - else if (pWin->winType == PPR_WIN_POSTSCRIPT || - pWin->winType == PPR_WIN_EPS) { - (void)fprintf(pWin->file, "%d %d %d %d DS\n", - xp0, yp0, xp1, yp1); - } - } -#else - drawFn(pArea, xp0, yp0, xp1, yp1); -#endif - } - else { -/*----------------------------------------------------------------------------- -* draw a dashed line pattern -*----------------------------------------------------------------------------*/ - segLen = sqrt((double)((xp1-xp0)*(xp1-xp0) + (yp1-yp0)*(yp1-yp0))); - endLen = 0.; - xbeg = xp0; - ybeg = yp0; - while (endLen < segLen) { - if (pArea->attr.rem < 1.) { - if ((pArea->attr.rem = - pArea->attr.pPatt[++pArea->attr.sub]) <= 0.) { - pArea->attr.sub = 0; - pArea->attr.rem = pArea->attr.pPatt[0]; - pArea->attr.pen = 1; - } - else - pArea->attr.pen ^= 1; - } - dashLen = PprMin(pArea->attr.rem, segLen-endLen); - endLen += dashLen; - if (PprAbs(endLen-segLen) < .5) - endLen = segLen; - xend = xp0 + endLen/segLen * (xp1 - xp0); - yend = yp0 + endLen/segLen * (yp1 - yp0); - if (pArea->attr.pen) - drawFn(pArea, (long)(.5+xbeg), (long)(.5+ybeg), - (long)(.5+xend), (long)(.5+yend)); - xbeg = xend; - ybeg = yend; - pArea->attr.rem -= dashLen; - } - } - } -} - -void -pprMoveD_ac(pArea, x, y, pen) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate of new point */ -double y; /* I y data coordinate of new point */ -int pen; /* I pen indicator--1 draws a line */ -{ - int xp1 = pArea->xPixLeft + .5 + (x - pArea->xLeft) * pArea->xScale; - int yp1 = pArea->yPixBot + .5 + (y - pArea->yBot) * pArea->yScale; - if (pArea->pWin->winType == PPR_WIN_SCREEN) - yp1 = pArea->pWin->height - yp1; - if (pen) { - pprLineThick(pArea, pArea->pWin->attr.lineThick); - pprLineSegPixL_ac(pArea, pArea->xPix, pArea->yPix, xp1, yp1); - } - pArea->xPix = xp1; - pArea->yPix = yp1; -} - -void -pprMoveD_wc(pArea, x, y, pen) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate of new point */ -double y; /* I y data coordinate of new point */ -int pen; /* I pen indicator--1 draws a line */ -{ - int xp1 = pArea->xPixLeft + .5 + (x - pArea->xLeft) * pArea->xScale; - int yp1 = pArea->yPixBot + .5 + (y - pArea->yBot) * pArea->yScale; - if (pArea->pWin->winType == PPR_WIN_SCREEN) - yp1 = pArea->pWin->height - yp1; - if (pen) { - pprLineThick(pArea, pArea->pWin->attr.lineThick); - pprLineSegPixL_wc(pArea, pArea->xPix, pArea->yPix, xp1, yp1); - } - pArea->xPix = xp1; - pArea->yPix = yp1; -} -void -pprMoveEraseD(pArea, x, y) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate of new point */ -double y; /* I y data coordinate of new point */ -{ - pprMoveD_gen(pArea, x, y, 1, pprLineSegPixEraseL); -} - -/*+/subr********************************************************************** -* NAME pprPerim - draw a perimeter -* -* DESCRIPTION -* Draw a perimeter with tick marks. The number of intervals -* specified in the plot area structure is used for placing -* the tick marks. -* -* The color attributes for the plot window are used for drawing; -* dashed line and line thickness are ignored. -* -* RETURNS -* void -* -* BUGS -* o only linear axes are handled -* -* SEE ALSO -* pprPerimLabel, pprPerimErase, pprGrid, pprAnnotX, pprAnnotY, pprAreaOpen -* -*-*/ -void -pprPerim(pArea) -PPR_AREA *pArea; /* I pointer to plot area structure */ -{ - double tickHalf; - int i; - double x, y; - -/*----------------------------------------------------------------------------- -* draw the box -*----------------------------------------------------------------------------*/ - pprMoveD_wc(pArea, pArea->xLeft, pArea->yBot, 0); - pprMoveD_wc(pArea, pArea->xRight, pArea->yBot, 1); - pprMoveD_wc(pArea, pArea->xRight, pArea->yTop, 1); - pprMoveD_wc(pArea, pArea->xLeft, pArea->yTop, 1); - pprMoveD_wc(pArea, pArea->xLeft, pArea->yBot, 1); -/*----------------------------------------------------------------------------- -* draw the x axis tick marks -*----------------------------------------------------------------------------*/ - tickHalf = pArea->tickHt / pArea->yScale; - x = pArea->xLeft; - y = pArea->yBot - 3. * tickHalf; - for (i=1; ixNint; i++) { - x += pArea->xInterval; - pprLineSegD_wc(pArea, x, pArea->yBot - tickHalf, x, pArea->yBot); - pprLineSegD_wc(pArea, x, pArea->yTop + tickHalf, x, pArea->yTop); - } -/*----------------------------------------------------------------------------- -* ditto for y axis -*----------------------------------------------------------------------------*/ - tickHalf = pArea->tickHt / pArea->xScale; - x = pArea->xLeft - 1.5 * tickHalf; - y = pArea->yBot; - for (i=1; iyNint; i++) { - y += pArea->yInterval; - pprLineSegD_wc(pArea, pArea->xLeft - tickHalf, y, pArea->xLeft, y); - pprLineSegD_wc(pArea, pArea->xRight + tickHalf, y, pArea->xRight, y); - } -} - -/*+/subr********************************************************************** -* NAME pprPerimErase - erase within a perimeter -* -* DESCRIPTION -* Erases the screen inside the perimeter for the plot area. (Actually, -* the perimeter and tick marks are erased as well, since plot marks -* may have been drawn on (and thus lie partly outside of) the perimeter -* itself. The perimeter and tick marks are then redrawn.) -* -* RETURNS -* void -* -* SEE ALSO -* pprGridErase, pprAreaErase, pprWinErase, pprRegionErase -* the ppr...Erase... entry points for the various drawing routines -* -*-*/ -void -pprPerimErase(pArea) -PPR_AREA *pArea; /* I pointer to plot area structure */ -{ - int x,y,width,height; - - if (pArea->pWin->winType != PPR_WIN_SCREEN) - return; - x = pArea->xPixLeft - 3; - y = pArea->yPixBot - 3; - width = (pArea->xRight - pArea->xLeft) * pArea->xScale + 6; - height = (pArea->yTop - pArea->yBot) * pArea->yScale + 6; -#ifdef SUNVIEW - y = pArea->pWin->height - y - height; - pw_writebackground(pArea->pWin->pw, x, y, width, height, PIX_SRC); - pprPerim(pArea); -#else -#if defined XWINDOWS - y = pArea->pWin->height - y - height; - XClearArea(pArea->pWin->pDisp, pArea->pWin->plotWindow, - x, y, width, height, False); - if (pArea->pixMap != NULL) { - XFillRectangle(pArea->pWin->pDisp, pArea->pixMap, pArea->pixMapGC, - 0, 0, pArea->pixMapWidth+1, pArea->pixMapHeight+1); - } - pprPerim(pArea); - XFlush(pArea->pWin->pDisp); -#endif -#endif -} - -/*+/subr********************************************************************** -* NAME pprPerimLabel - draw and label a perimeter -* -* DESCRIPTION -* Draw a perimeter with tick marks. The number of intervals -* specified in the plot area structure is used for placing -* the tick marks. -* -* Axis labels and annotations are drawn using the information from -* the plot area, as specified in the pprAreaOpen call. -* -* RETURNS -* void -* -* BUGS -* o only linear axes are handled -* -* SEE ALSO -* pprPerim, pprGrid, pprAnnotX, pprAnnotY, pprAreaOpen -* -*-*/ -void -pprPerimLabel(pArea, xLabel, xAnnot, yLabel, yAnnot, angle) -PPR_AREA *pArea; /* I pointer to plot area structure */ -char *xLabel; /* I label for x axis, or NULL */ -char **xAnnot; /* I pointer to array of x annotations, or NULL */ -char *yLabel; /* I label for y axis, or NULL */ -char **yAnnot; /* I pointer to array of y annotations, or NULL */ -double angle; /* I angle for y annotations; 0. or 90. */ -{ - pprPerim(pArea); - pprAnnotX(pArea, 0, pArea->xLeft, pArea->xRight, pArea->xNint, - 0, xLabel, xAnnot, 0.); - pprAnnotY(pArea, 0, pArea->yBot, pArea->yTop, pArea->yNint, - 0, yLabel, yAnnot, angle); -} - -/*+/macro********************************************************************* -* NAME PprPixXToXFrac - convert pixel address to window fraction -* -* DESCRIPTION -* Converts an x or y pixel address (for example, from a mouse click) -* into a fraction of the plot window's width or height. -* -* PprPixXToXFrac(pWin, xPixel) -* PprPixYToYFrac(pWin, yPixel) -* -* RETURNS -* window fraction -* -*-*/ - -/*+/subr********************************************************************** -* NAME pprPoint - plot a point at a coordinate -* -* DESCRIPTION -* Plot a pixel sized point using the line thickness and color -* attributes of the plot area. -* -* Two entry points are available: -* -* pprPointD(pArea, x, y) x and y are double -* pprPointL(pArea, x, y) x and y are long -* -* Two entry points are available for erasing: -* -* pprPointEraseD(pArea, x, y) x and y are double -* pprPointEraseL(pArea, x, y) x and y are long -* -* RETURNS -* void -* -* BUGS -* o only linear calibration is handled -* -* SEE ALSO -* pprMark, pprAreaOpen, pprAreaSetAttr, pprLine, -* pprMove, pprText -* -*-*/ -void -pprPointD(pArea, x, y) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate */ -double y; /* I y data coordinate */ -{ - double xPix, yPix; - double xp0,yp0,xp1; - - xPix = pArea->xPixLeft + .5 + (x - pArea->xLeft) * pArea->xScale; - yPix = pArea->yPixBot + .5 + (y - pArea->yBot) * pArea->yScale; - pprLineThick(pArea, pArea->attr.lineThick); - if (pArea->pWin->winType == PPR_WIN_SCREEN) { - yPix = pArea->pWin->height - yPix; -#ifdef SUNVIEW - if (pArea->pWin->attr.ltPix > 1) { - yp0 = yPix; - xp0 = xPix - pArea->pWin->attr.ltPix / 2; - xp1 = xp0 + pArea->pWin->attr.ltPix - 1; -#else -#if defined XWINDOWS - if (pArea->attr.ltPix > 1) { - yp0 = yPix; - xp0 = xPix - pArea->attr.ltPix / 2; - xp1 = xp0 + pArea->attr.ltPix - 1; -#endif -#endif - pprLineSegPixD_ac(pArea, xp0, yp0, xp1, yp0); - } - else { -#ifdef SUNVIEW - pw_put(pArea->pWin->pw, (int)xPix, (int)yPix, 1); -#else -#if defined XWINDOWS - XDrawPoint(pArea->pWin->pDisp, pArea->pWin->plotWindow, - pArea->attr.gc, (int)xPix, (int)yPix); -#endif -#endif - } - } - else if (pArea->pWin->winType == PPR_WIN_POSTSCRIPT || - pArea->pWin->winType == PPR_WIN_EPS) { - (void)fprintf(pArea->pWin->file, "%.1f %.1f DP\n", xPix, yPix); - } -} -void -pprPointL(pArea, x, y) -PPR_AREA *pArea; /* I pointer to plot area structure */ -long x; /* I first x point */ -long y; /* I first y point */ -{ - pprPointD(pArea, (double)x, (double)y); -} -void -pprPointEraseD(pArea, x, y) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate */ -double y; /* I y data coordinate */ -{ - double xPix, yPix; - double xp0,yp0,xp1; - - if (pArea->pWin->winType != PPR_WIN_SCREEN) - return; - xPix = pArea->xPixLeft + .5 + (x - pArea->xLeft) * pArea->xScale; - yPix = pArea->yPixBot + .5 + (y - pArea->yBot) * pArea->yScale; - pprLineThick(pArea, pArea->attr.lineThick); - yPix = pArea->pWin->height - yPix; -#ifdef SUNVIEW - if (pArea->pWin->attr.ltPix > 1) { - yp0 = yPix; - xp0 = xPix - pArea->pWin->attr.ltPix / 2; - xp1 = xp0 + pArea->pWin->attr.ltPix - 1; -#else -#if defined XWINDOWS - if (pArea->attr.ltPix > 1) { - yp0 = yPix; - xp0 = xPix - pArea->attr.ltPix / 2; - xp1 = xp0 + pArea->attr.ltPix - 1; -#endif -#endif - pprLineSegPixEraseD(pArea, xp0, yp0, xp1, yp0); - } - else { -#ifdef SUNVIEW - pw_put(pArea->pWin->pw, (int)xPix, (int)yPix, 0); -#else -#if defined XWINDOWS - XDrawPoint(pArea->pWin->pDisp, pArea->pWin->plotWindow, - pArea->pWin->attr.gcBG, (int)xPix, (int)yPix); -#endif -#endif - } -} -void -pprPointEraseL(pArea, x, y) -PPR_AREA *pArea; /* I pointer to plot area structure */ -long x; /* I first x point */ -long y; /* I first y point */ -{ - pprPointEraseD(pArea, (double)x, (double)y); -} - -/*/internal ------------------------------------------------------------------- -* NAME pprPSProg - PostScript routines for lines, points, text strings, etc. -*----------------------------------------------------------------------------*/ - -static char *pprPSProg[]={ -/*----------------------------------------------------------------------------- -* DP - draw a point -* x y DP - -*----------------------------------------------------------------------------*/ -"/DP {", -" newpath", -" moveto", -" currentlinewidth dup 2 div neg 0 rlineto 0 rlineto", -" stroke", -"} def", -/*----------------------------------------------------------------------------- -* DS - draw a line segment from x1,y1 to x2,y2 -* x1 y1 x2 y2 DS - -*----------------------------------------------------------------------------*/ -"/DS {", -" newpath", -" 4 2 roll moveto lineto", -" stroke", -"} def", -/*----------------------------------------------------------------------------- -* FSet - set size of current font; if already proper size, no action -* size FSet - -* -* BUGS -* o should keep a list of scalefont which have already been done, to -* avoid the need to do a new one -* o doesn't allow selecting font family -*----------------------------------------------------------------------------*/ -"/F /Helvetica findfont def", -"/F_HT -1 def", -"/FSet {", -" /F_ht exch def", -" F_ht F_HT ne {", -" /F_HT F_ht def", -" F F_HT scalefont dup /FF exch def setfont", -" } {", -" FF setfont", /* if not changing, still must set */ -" } ifelse", -"} def", - -/*----------------------------------------------------------------------------- -* PT - plot a text string -* Text appears at current location with specified size and angle. -* The text can be right, left, or center justified; the "half height" -* of the characters will be at the current location. -* -* string just angle size PT - -* "just" is one of (PTC), (PTR), or (PTL) -*----------------------------------------------------------------------------*/ - -"/PTL { } def", -"/PTC { dup stringwidth pop -2 div 0 rmoveto } def", -"/PTR { dup stringwidth pop neg 0 rmoveto } def", - -"/PT { FSet gsave", -" currentpoint translate rotate", -" cvn cvx exec", /* execute the PTx procedure */ -" 0 F_HT -3 div rmoveto", /* offset to vertical center of char */ -" show", -" grestore } def" -}; - -/*+/subr********************************************************************** -* NAME pprRegionErase - erase an area within a plot window -* -* DESCRIPTION -* Erases an area within a plot window. -* -* RETURNS -* void -* -* SEE ALSO -* pprWinErase, pprAreaErase, pprGridErase, pprPerimErase -* the ppr...Erase... entry points for the various drawing routines -* -* BUGS -* 1. This doesn't erase the pixmap used for strip charts. -* -* NOTES -* 1. Another mode of calling pprRegionErase, in which the arguments are -* pixel offsets from the data area boundaries, is invoked by -* having one or more of the arguments be greater than 1. or less -* than 0. In this case, all the "wfrac" arguments are treated as -* pixel offsets. -* -* EXAMPLES -* 1. Erase within a data area, preserving the perimeter line. This -* example uses pixel offsets from the plot area boundary--one pixel -* inside each edge of the plot area. -* -* pprRegionErase(pArea, 1., 1., -1., -1.); -* -* 2. A data area occupies the upper right quarter of the plot window. -* An annotation area (using default character height) extends from -* the left edge of the plot window to the left edge of the data area, -* centered at the vertical midpoint of the data area. Erase the -* annotation area. -* -* double yb,yt; -* -* The region to erase is expressed as fractions of window width and -* height. For x, the region is from 0. (the left edge of the plot -* window) to .49 (just a bit left of the center of the plot window). -* For y, the region is centered at .75 (the vertical midpoint of the -* plot area within the plot window), with a height of the default -* character height. -* -* yb = .75 - PprDfltCharHt(.5,1.); -* yt = yb + PprDfltCharHt(.5,1.); -* pprRegionErase(pArea, 0., yb, .49, yt); -* -*-*/ -void -pprRegionErase(pArea, wfracXleft, wfracYbot, wfracXright, wfracYtop) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double wfracXleft; /* I x win frac of left edge of area (see Note 1) */ -double wfracYbot; /* I y win frac of bottom edge of area (see Note 1) */ -double wfracXright; /* I x win frac of right edge of area (see Note 1) */ -double wfracYtop; /* I y win frac of top edge of area (see Note 1) */ -{ - int x,y,width,height; - - if (pArea->pWin->winType != PPR_WIN_SCREEN) - return; - if (wfracXleft<0. || wfracXleft>1. || wfracXright<0. || wfracXright>1. || - wfracYbot<0. || wfracYbot>1. || wfracYtop<0. || wfracYtop>1.) { - x = pArea->xPixLeft + wfracXleft; - y = pArea->yPixBot + wfracYbot; - width = pArea->xPixRight + wfracXright - x + 1; - height = pArea->yPixTop + wfracYtop - y + 1; - } - else { - x = wfracXleft * pArea->pWin->width; - y = wfracYbot * pArea->pWin->height; - width = (wfracXright - wfracXleft) * pArea->pWin->width; - height = (wfracYtop - wfracYbot) * pArea->pWin->height; - } -#ifdef SUNVIEW - y = pArea->pWin->height - y - height; - pw_writebackground(pArea->pWin->pw, x, y, width, height, PIX_SRC); -#else -#if defined XWINDOWS - y = pArea->pWin->height - y - height; - XClearArea(pArea->pWin->pDisp, pArea->pWin->plotWindow, - x, y, width, height, False); -#endif -#endif -} - -/*+/subr********************************************************************** -* NAME pprSin_deg - get the sine of an angle in degrees -* -* DESCRIPTION -* Get the sine of an angle in degrees. A table lookup technique -* is used. The angle argument is truncated to the next lower 1/4 -* degree prior to lookup. -* -* RETURNS -* sine -* -*-*/ -double -pprSin_deg(angle) -double angle; /* I angle, in degrees */ -{ - return pprCos_deg(angle - 90.); -} - -/*/internal ------------------------------------------------------------------- -* NAME pprTextFont - character tables for drawn font -* -* ITABLE = the array defining the character set. Each character is -* defined by one 34 character string "matrix". The "matrix" -* elements consist of a series of up to 17 (IDX,IDY)'s which -* define the next stroke. The vector is positioned at (IX1,IY1) -* and drawn to (IX2,IY2) where: -* IX1 = IX + IDX1 IY1 = IY + IDY1 -* IX2 = IX + IDX2 IY2 = IY + IDY2 -* (IX2,IY2) becomes the next (IX1,IY1) unless the new IDX = 0 -* in which case a new vector is started with the next 2 -* elements after the 0 becoming (IDX,IDY) etc. (ie., an IDX -* = 0 causes a break in the character strokes.) An IDY = 0 -* causes an offset to be added to IY for the remaining strokes -* in the character. This is used for characters such as g and -* y which extend below the relative 0 line. The element -* following an IDY = 0 becomes the IDY actually used. The -* (IDX,IDY) represents a position in a 6 x 9 matrix. IDX has -* a range of 0 - 6, where most characters fall within 1 - 5; -* 0 triggers a new stroke unless it is the 1st element of the -* string in which case it is really 0. IDY has a range of -* 0 - 9, where most characters fall within 1 - 7; 0 triggers -* an offset to lower the rest of the strokes. A non-numeric -* character in the string, ie. a period, is used to terminate -* the stroke matrix for the character. -* -* converted to C by Roger Cole, 12-90 -* -* EFC 4/16/85: included call to UNPKST to make character string -* matrices nearly as efficient as octal matrices. -* Uses 95 microseconds more per character on average. -* EFC 4/8/85: rewritten for STRING a character variable rather than -* hollerith. Extended and rewrote character stroke array -* for nicer characters. Changed definition of INSIZE = 0 -* matrix from 10 x 13 to 9 x 13. -* EFC 9/21/84: rewritten for FORTRAN 77 on DEC KL-10 to use character -* functions rather than binary masks and shifts. Changed -* matrix for tau and xsi. Changed coding to fix bug in -* "y" shifting of charcters and eliminate inconsistencies -* in described usage and actual usage. -* modified by Debby Hyman, 9-80 -* Greek characters almost match QUME printer char set, now -* -*changed 16-may-76 STB CTR -*----------------------------------------------------------------------------*/ -static char *glPprFont0[]={ -/*----------------------------------------------------------------------------- -* blank ! " # $ % & ' ( ) * + , - . / -*----------------------------------------------------------------------------*/ - ".", "2737242702221313222.", "27253727057454757.", "2721047410155501353.", - "5626152444521203137.", "57110162736251604132435241.", - "511516273746451312213153.", "35473735.", "41232547.", "21434527.", - "46220422605414.", "323605414.", "31433331.", "5414.", "3242413132.", - "5711.", -/*----------------------------------------------------------------------------- -* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? -*----------------------------------------------------------------------------*/ - "132141535547271513.", "51110313726.", "51111256472716.", - "44240122141524456472716.", "46410531337.", "57171425455452412112.", - "564727161221415253442413.", "315717.", - "44555647271615244453524121121324.", "5424151627475652412112.", - "454636354504342323343.", "3646453536031334331.", "521456.", - "155501353.", "125416.", "16274756553303231212232.", -/*----------------------------------------------------------------------------- -* @ A B C D E F G H I J K L M N O -*----------------------------------------------------------------------------*/ - "512112162747565443344554.", "23430513711.", "4453524111174756554414.", - "5647271612214152.", "17114153554717.", "1444051111757.", "44140111757.", - "56472716122141520515434.", "51570541401117.", "51110313705717.", - "122131424705727.", "51240571301117.", "511117.", "5157331711.", - "57511711.", "271612214152564727.", -/*----------------------------------------------------------------------------- -* P Q R S T U V W X Y Z [ \ ] ^ _ -*----------------------------------------------------------------------------*/ - "14445556471711.", "27161221415256472703361.", "5134014445556471711.", - "564727161524445352412112.", "313705717.", "575241211217.", "573117.", - "5741352117.", "571105117.", "57340313417.", "51115717.", "41212747.", - "1751.", "21414727.", "273847.", "10252.", -/*----------------------------------------------------------------------------- -* ` a b c d e f g h i j k l m n o -*----------------------------------------------------------------------------*/ - "37454737.", "14254554510524121122353.", "1545535241211201117.", - "512112142555.", "5525141221415205157.", "512112142545545313.", - "56473726210113103414.", "52412112142545540507524121.", "111701425455451.", - "214103135250373737.", "373737030747423121.", "45134101117.", - "41210313727.", "1115014253531034455551.", "111501425455451.", - "122141525445251412.", -/*----------------------------------------------------------------------------- -* p q r s t u v w x y z { | } ~ -*----------------------------------------------------------------------------*/ - "1425455452412112010711.", "544525141221415205075161.", - "1115014254554.", "54452514234352412112.", "2545037324151.", - "151221415205155.", "553115.", "5541352115.", "551105115.", - "15122141520507524121.", "51115515.", "47372622314101424.", - "3137.", "27374642312104454.", "16274657.", -/*----------------------------------------------------------------------------- -* box dot -*----------------------------------------------------------------------------*/ - "1252561612.", "3254361432." -}; -#if 0 -static char *glPprFont1[]={ -/*----------------------------------------------------------------------------- -* blank ! " # $ % & ' ( ) * + , - . / -*----------------------------------------------------------------------------*/ - ".", "115103137.", "212704147.", "15550571101353.", "52511135195958.", - "14264254462214.", "52422614224656.", "135351.", "492523401.", - "294543201.", "125601652.", "52120333705515.", "24324403236.", - "16560353101353.", "3343443433.", "2559.", -/*----------------------------------------------------------------------------- -* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? -*----------------------------------------------------------------------------*/ - "253546483929181625.", "45150353928.", "45151648392918.", - "37270162535463748392918.", "38350461629.", "491917283847463515.", - "4839291816253546372716.", "194925.", "374839291827374635251627.", - "153546483929182747.", "172728181703747483837.", - "45463635450434232334302454.", "13510531557.", "1353015264556.", - "53110135517.", "12213137475601555.", -/*----------------------------------------------------------------------------- -* @ A B C D E F G H I J K L M N O -*----------------------------------------------------------------------------*/ - "12213142332536273848570364433.", "1136510234303526374635.", - "17315705414.", "31370575544241517.", "11513711.", "12520541401656.", - "224253554626151322021410313702747.", "1131021270175756.", - "12214152564727161202444.", "122131475766.", "162747545241211213244453.", - "11212212110415152424103545463635.", "0121011375104161.", - "512112142555.", "114152544515.", "11415254451502353.", -/*----------------------------------------------------------------------------- -* P Q R S T U V W X Y Z [ \ ] ^ _ -*----------------------------------------------------------------------------*/ - "112127017570474151.", "132242535546261513.", "132147.", "52511144175756.", - "21270414705727161524.", "21410313627160364756.", "31571731.", - "0211212314162747565443415162.", "12115152043450442402325016175756.", - "111526465551.", "161221415256.", "492920141.", "33543505414.", - "294940121.", "24364403632.", "33143501454.", -/*----------------------------------------------------------------------------- -* ` a b c d e f g h i j k l m n o -*----------------------------------------------------------------------------*/ - "1353031643705515.", "5141443525141221314255.", - "2141525344140445556472716101.", "1626243343545604721.", - "56473726255352412112132434.", "52412112234302314254554.", - "452514122141525445047201.", "152636454131224556.", - "5414132141535547271514.", "25353141.", "2145473726254151.", - "1511051134555.", "11340512717.", "514204542312112015101.", "25315355.", - "171524445557482817.", -/*----------------------------------------------------------------------------- -* p q r s t u v w x y z { | } ~ -*----------------------------------------------------------------------------*/ - "252104144055442514.", "1626415101156.", "2231415254453524101.", - "552514132232434435.", "4131350552514.", "15132141525445.", - "145404354450251423.", "25141221320333241525445.", - "17260561615244402413125251402.", "152521024354554501.", - "1736560361312215150241.", "142404939282023141.", "6859493012112.", - "445402939484023121.", "041525445465.", -/*----------------------------------------------------------------------------- -* box dot / diamond triangle -*----------------------------------------------------------------------------*/ - "3434.", "13533713." -}; -#endif - -/*+/subr********************************************************************** -* NAME pprText - plot a text string -* -* DESCRIPTION -* Plots a text string at a location. The character "half height" is -* placed at the specified x,y position; the 'justification' option -* selects whether the left end, center, or right end of the text is -* placed at the x,y coordinate. -* -* The character height specification is in terms of a fraction of the -* height of the window. This results in automatic scaling of -* character sizes as the window size changes. If a height of zero -* is specified in the call, then the default height for the plot -* area is used. (The default height was established by pprAreaOpen.) -* -* A macro is available which returns the default character height -* used by this plot package. The value returned is proportional to -* the height of the plot area. This value can be used to generate -* "big" and "small" character sizes with simple multiplication of -* the default height by a "scale factor". -* -* PprDfltCharHt(lowYfrac, highYfrac) -* -* lowYfrac is the vertical fraction of the window at which -* the bottom edge of the plot area lies -* highYfrac is the vertical fraction of the window at which -* the top edge of the plot area lies -* -* It is also often useful to know what horizontal fraction of the -* window width corresponds to a vertical fraction of the height. The -* following routine returns the horizontal fraction: -* -* pprYFracToXFrac(pWin, yFrac) -* -* An alternate entry point, pprText_wc, is available to use the -* plot window's color for drawing the text. -* -* An additional entry point is available for erasing (which requires -* all arguments to be exactly the same as when the text was originally -* plotted): -* -* pprTextErase(pArea, x, y, text, just, height, angle) -* -* RETURNS -* void -* -* BUGS -* o technique used works only with linear axes -* o ASCII character codes are assumed -* o no checks are made for illegal characters -* o positioning and sizing are somewhat different for the various -* window types -* -* SEE ALSO -* pprChar, pprAreaOpen, pprLine, pprPoint, pprCvtDblToTxt -* -*-*/ -void -pprText(pArea, x, y, text, just, height, angle) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate of text */ -double y; /* I y data coordinate of text */ -char *text; /* I text to plot */ -PPR_TXT_JUST just; /* I text justification selector: one of - PPR_TXT_CEN, PPR_TXT_RJ, or PPR_TXT_LJ */ -double height; /* I height of text characters, as a fraction of - the height of the window; a value of - zero results in using a default height */ -double angle; /* I orientation angle of text string, ccw degrees */ -{ - pprText_gen(pArea, x, y, text, just, height, angle, pprLineSegPixD_ac); -} -void -pprText_wc(pArea, x, y, text, just, height, angle) -PPR_AREA *pArea; -double x; -double y; -char *text; -PPR_TXT_JUST just; -double height; -double angle; -{ - pprText_gen(pArea, x, y, text, just, height, angle, pprLineSegPixD_wc); -} -static void -pprText_gen(pArea, x, y, text, just, height, angle, fn) -PPR_AREA *pArea; -double x; -double y; -char *text; -PPR_TXT_JUST just; -double height; -double angle; -void (*fn)(); -{ - double xWin, yWin; - double scale; /* convert character units to win coord */ - double cosT, sinT; - - if (height <= 0.) - height = pArea->charHt; - else - height *= pArea->pWin->height; - xWin = pArea->xPixLeft + .5 + (x - pArea->xLeft) * pArea->xScale; - yWin = pArea->yPixBot + .5 + (y - pArea->yBot) * pArea->yScale; - - if (pArea->pWin->winType == PPR_WIN_SCREEN) { - if (angle == 0.) cosT = 1., sinT = 0.; - else if (angle == 90.) cosT = 0., sinT = 1.; - else { cosT = pprCos_deg(angle); - sinT = pprSin_deg(angle); - } - - scale = height / 6.; - - if (just == PPR_TXT_CEN) { - xWin -= .5 * (scale * 6. * (double)(strlen(text)-1) * cosT); - yWin -= .5 * (scale * 6. * (double)(strlen(text)-1) * sinT); - } - else if (just == PPR_TXT_RJ) { - xWin -= scale * 6. * (double)(strlen(text)-1) * cosT; - yWin -= scale * 6. * (double)(strlen(text)-1) * sinT; - } - - while (*text != '\0') { - pprText1(pArea, xWin, yWin, *text, 0, scale, sinT, cosT, fn); - xWin += scale * 6. * cosT; - yWin += scale * 6. * sinT; - text++; - } - } - else { - height = 1.5 * height; - pprTextPS(pArea->pWin->file, xWin, yWin, just, text, height, angle); - } -} -void -pprTextErase(pArea, x, y, text, just, height, angle) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate of text */ -double y; /* I y data coordinate of text */ -char *text; /* I text to plot */ -PPR_TXT_JUST just; /* I text justification selector: one of - PPR_TXT_CEN, PPR_TXT_RJ, or PPR_TXT_LJ */ -double height; /* I height of text characters, as a fraction of - the height of the window; a value of - zero results in using a default height */ -double angle; /* I orientation angle of text string, ccw degrees */ -{ - pprText_gen(pArea, x, y, text, just, height, angle, pprLineSegPixEraseD); -} - -/*+/internal****************************************************************** -* NAME pprText1 - plot a "drawn" character -* -* DESCRIPTION -* Plots a character at x,y using specified scale factor and rotation. -* All sizes and coordinates use window units, rather than data units. -* -* RETURNS -* void -* -* BUGS -* o only linear calibration is handled -* -*-*/ -void -pprText1(pArea, xWin, yWin, ic, nfont, scale, sinT, cosT, fn) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double xWin; /* IO x position, in window coordinates */ -double yWin; /* IO y position, in window coordinates */ -int ic; /* I character code to plot */ -int nfont; /* I font selector--0 or 1 */ -double scale; /* I scale factor to convert a character height of - 6 to the desired height in window coord */ -double sinT; /* I sine of orientation angle */ -double cosT; /* I cosine of orientation angle */ -void (*fn)(); /* I pointer to drawing fn: pprLineSegPixD_.. */ -{ -/* stolen (who knows how many times removed) from the Los Alamos National - Laboratory Plasma Physics Plotting Package */ - char *font; /* font string for this character */ - int nStrokes; - int mcx, mcy, indw, drawit; - double rx, ry; - int ibyt; - double xp0,xp1,yp0,yp1; - - if (ic < ' ' || ic > '~') - ic = '#'; - if (nfont == 0) - font = glPprFont0[ic-' ']; -#if 0 - else - font = glPprFont1[ic-' ']; -#endif - nStrokes = (int)(index(font, '.') - font) -1; - mcx = 3; - mcy = 4; - indw = 0; - - pprLineThick(pArea, pArea->pWin->attr.lineThick); - drawit = 0; - xp0 = pArea->xPix; - yp0 = pArea->yPix; - while (indw < nStrokes) { - ibyt = font[indw] - '0'; - if (ibyt == 0 && indw != 0) - drawit = 0; /* there is a break in the strokes */ - else { - rx = (float)(ibyt - mcx); - while ((ibyt = font[++indw] - '0') == 0) - mcy = 6; /* this char has a descender, as for y or g */ - ry = (float)(ibyt - mcy); - - xp1 = xWin + scale * (rx*cosT - ry*sinT); - yp1 = yWin + scale * (rx*sinT + ry*cosT); - if (pArea->pWin->winType == PPR_WIN_SCREEN) - yp1 = pArea->pWin->height - yp1; - if (drawit) - fn(pArea, xp0, yp0, xp1, yp1); - xp0 = xp1; - yp0 = yp1; - - drawit = 1; - } - indw++; - } -} - -/*+/internal****************************************************************** -* NAME pprTextPS - send the PostScript commands to plot some text -* -* DESCRIPTION -* This routine sets up the call to the routine (unique to this -* package) in the PostScript printer. This involves: -* o moving to the desired position -* o massaging the caller's text to enclose it in ( and ) and to -* "escape" characters which are special to PostScript -* o setting the font size -* o setting the angle for the text -* o setting for right, centered, or left justification -* -* All text is printed with the font selected by the PostScript -* routine. -* -* RETURNS -* void -* -* BUGS -* o assumes that all characters in the caller's text string are printable -* -*-*/ -static void -pprTextPS(psFile, x, y, just, text, height, angle) -FILE *psFile; /* I pointer to PostScript file */ -double x,y; /* I x and y position, in window coordinates */ -PPR_TXT_JUST just; /* I text justification selector: one of - PPR_TXT_CEN, PPR_TXT_RJ, or PPR_TXT_LJ */ -char *text; /* I the text to plot */ -double height; /* I the desired height of the text, in points */ -double angle; /* I orientation angle of the text, + is ccw */ -{ - char myJust[4]; - -/*----------------------------------------------------------------------------- -* send out the text string, enclosed in PostScript string delimiters of ( ) -* Special characters are sent out as an appropriate \ sequence -*----------------------------------------------------------------------------*/ - (void)fprintf(psFile, "%d %d moveto\n", (int)(x+.5), (int)(y+.5)); - fputc('(', psFile); - while (*text != '\0') { - switch (*text) { - case '\b': - fputc('\\', psFile); fputc('b', psFile); - break; - case '\f': - fputc('\\', psFile); fputc('f', psFile); - break; - case '\n': - fputc('\\', psFile); fputc('n', psFile); - break; - case '\r': - fputc('\\', psFile); fputc('r', psFile); - break; - case '\t': - fputc('\\', psFile); fputc('t', psFile); - break; - case '(': - case ')': - case '\\': - fputc('\\', psFile); - default: - fputc(*text, psFile); - } - text++; - } - fputc(')', psFile); - fputc(' ', psFile); -/*----------------------------------------------------------------------------- -* now send out the rest of the PostScript information, so that the whole -* thing from this routine will be something like the following, with -* the proper choice of PTC PTL and PTR: -* -* x y moveto (text) (PTx) angle typesize PT -*----------------------------------------------------------------------------*/ - if (just == PPR_TXT_CEN) - (void)strcpy(myJust, "PTC"); - else if (just == PPR_TXT_RJ) - (void)strcpy(myJust, "PTR"); - else - (void)strcpy(myJust, "PTL"); - (void)fprintf(psFile, "(%s) %.2f %d PT\n", myJust, angle, (int)(height+.5)); -} - -/*+/internal****************************************************************** -* NAME QUICK_WAVE - macro for quickly plotting waveforms under X11 -* -*-*/ -/*----------------------------------------------------------------------------- -* !!!! NOTE WELL !!!! Various routines have these plotting statements -* for calling XDrawLine. If you modify the statements here, modify -* the other places too!! -*----------------------------------------------------------------------------*/ -#if defined XWINDOWS -#define QUICK_WAVE() \ - PPR_WIN *pWin=pArea->pWin; \ - if (pArea->attr.pPatt == NULL && pWin->winType == PPR_WIN_SCREEN && \ - !pArea->attr.clip && !pArea->usePixMap) { \ - int xp0, xp1, yp0, yp1, winHt=pWin->height; \ - double xPixLeft=pArea->xPixLeft, yPixBot=pArea->yPixBot; \ - double xScale=pArea->xScale, yScale=pArea->yScale; \ - double xLeft=pArea->xLeft, yBot=pArea->yBot; \ - double xbeg, xend, ybeg, yend; \ - Display *pDisp=pWin->pDisp; \ - Window plotWindow=pWin->plotWindow; \ - GC gc=pArea->attr.gc; \ - \ - pprLineThick(pArea, pArea->attr.lineThick); \ - \ - xp0 = xPixLeft + .5 + (xD - xLeft) * xScale; \ - yp0 = winHt - (int)(yPixBot + .5 + ((double)(*++y) - yBot) * yScale); \ - for (xD=x; --npts>0; xD+=x) { \ - xp1 = xPixLeft + .5 + (xD - xLeft) * xScale; \ - yp1 = winHt - (int)(yPixBot + .5 + ((double)(*++y)-yBot)*yScale); \ - if (xp0 != xp1 || yp0 != yp1) \ - XDrawLine(pDisp, plotWindow, gc, xp0, yp0, xp1, yp1); \ - xp0 = xp1; \ - yp0 = yp1; \ - } \ - pArea->xPix = xp1; \ - pArea->yPix = yp1; \ - return; \ - } -#else -#define QUICK_WAVE() -#endif - - -/*+/subr********************************************************************** -* NAME pprWave - plot a waveform -* -* DESCRIPTION -* Draw a waveform using a y data value array and an x increment value. -* The first x value is assumed to be 0. -* -* Several entry points are available to accomodate various -* types of data: -* -* pprWaveF(pArea, x, y, npts) x and y are float[] -* pprWaveD(pArea, x, y, npts) x and y are double[] -* pprWaveS(pArea, x, y, npts) x and y are short[] -* pprWaveL(pArea, x, y, npts) x and y are long[] -* -* Several entry points are available for erasing: -* -* pprWaveEraseF(pArea, x, y, npts) x and y are float[] -* pprWaveEraseD(pArea, x, y, npts) x and y are double[] -* pprWaveEraseS(pArea, x, y, npts) x and y are short[] -* pprWaveEraseL(pArea, x, y, npts) x and y are long[] -* -* RETURNS -* void -* -* BUGS -* o only linear calibration is handled -* -* SEE ALSO -* pprLineSeg, pprMove, pprPoint, pprText -* -* NOTES -* 1. The waveform drawing routines are optimized for fast plotting when -* no clipping is being done and dashed line pattern isn't being used. -* This optimization is only for plotting under X11. All other cases, -* including erasing an individual waveform, are handled with the usual -* pprXxx drawing routines. -* -*-*/ -void -pprWaveF(pArea, x, y, npts) -PPR_AREA *pArea; /* I pointer to plot area structure */ -float x; /* I x increment for data values */ -float *y; /* I y array of data values */ -int npts; /* I number of points to plot */ -{ double xD=0.; - QUICK_WAVE(); - pprMoveD(pArea, xD, (double)(*y), 0); - for (xD=x; --npts>0; xD+=x) - pprMoveD(pArea, xD, (double)(*++y), 1); -} - -void pprWaveD(pArea, x, y, npts) -PPR_AREA *pArea; double x; double *y; int npts; -{ double xD=0.; - QUICK_WAVE(); - pprMoveD(pArea, xD, *y, 0); - for (xD=x; --npts>0; xD+=x) - pprMoveD(pArea, xD, *++y, 1); -} -void pprWaveS(pArea, x, y, npts) -PPR_AREA *pArea; short x; short *y; int npts; -{ double xD=0.; - QUICK_WAVE(); - pprMoveD(pArea, xD, (double)(*y), 0); - for (xD=x; --npts>0; xD+=x) - pprMoveD(pArea, xD, (double)(*++y), 1); -} -void pprWaveL(pArea, x, y, npts) -PPR_AREA *pArea; long x; long *y; int npts; -{ double xD=0.; - QUICK_WAVE(); - pprMoveD(pArea, xD, (double)(*y), 0); - for (xD=x; --npts>0; xD+=x) - pprMoveD(pArea, xD, (double)(*++y), 1); -} -void pprWaveEraseF(pArea, x, y, npts) -PPR_AREA *pArea; float x; float *y; int npts; -{ double xD=0.; - pprMoveD(pArea, xD, (double)(*y), 0); - for (xD=x; --npts>0; xD+=x) - pprMoveEraseD(pArea, xD, (double)(*++y), 1); -} -void pprWaveEraseD(pArea, x, y, npts) -PPR_AREA *pArea; double x; double *y; int npts; -{ double xD=0.; - pprMoveD(pArea, xD, *y, 0); - for (xD=x; --npts>0; xD+=x) - pprMoveEraseD(pArea, xD, *++y, 1); -} -void pprWaveEraseS(pArea, x, y, npts) -PPR_AREA *pArea; short x; short *y; int npts; -{ double xD=0.; - pprMoveD(pArea, xD, (double)(*y), 0); - for (xD=x; --npts>0; xD+=x) - pprMoveEraseD(pArea, xD, (double)(*++y), 1); -} -void pprWaveEraseL(pArea, x, y, npts) -PPR_AREA *pArea; long x; long *y; int npts; -{ double xD=0.; - pprMoveD(pArea, xD, (double)(*y), 0); - for (xD=x; --npts>0; xD+=x) - pprMoveEraseD(pArea, xD, (double)(*++y), 1); -} - -/*+/internal****************************************************************** -* NAME pprWinAttr - set window attributes -* -*-*/ -static void -pprWinAttr(pWin) -PPR_WIN *pWin; -{ -#ifdef SUNVIEW - pWin->width = (int)window_get(pWin->canvas, WIN_WIDTH); - pWin->height = (int)window_get(pWin->canvas, WIN_HEIGHT); - pWin->x = (int)window_get(pWin->frame, WIN_X); - pWin->y = (int)window_get(pWin->frame, WIN_Y); -#else -#if defined XWINDOWS - XWindowAttributes winAttr; - XWindowAttributes parentAttr; - long stat; - Window rootWindow, parentWindow, *pChildWindows; - unsigned int nChildren; - int actualX, actualY; - - XGetWindowAttributes(pWin->pDisp, pWin->plotWindow, &winAttr); - actualX = winAttr.x; - actualY = winAttr.y; - stat = XQueryTree(pWin->pDisp, pWin->plotWindow, &rootWindow, - &parentWindow, &pChildWindows, &nChildren); - PprAssert(stat != 0); - if (pChildWindows != NULL) - XFree(pChildWindows); - if (rootWindow != parentWindow) { - XGetWindowAttributes(pWin->pDisp, parentWindow, &parentAttr); - actualX = parentAttr.x; - actualY = parentAttr.y; - } - pWin->width = winAttr.width; - pWin->height = winAttr.height; - pWin->x = actualX; - pWin->y = actualY; -#endif -#endif -} - -/*+/subr********************************************************************** -* NAME pprWinClose - close a plot window -* -* DESCRIPTION -* Free the memory associated with a plot window structure and do other -* cleanup activities. -* -* This routine should be called when plotting is complete for a plot -* window. Any plot areas not previously closed are automatically -* closed by this routine. -* -* No further references to the plot window may be made. -* -* RETURNS -* void -* -* SEE ALSO -* pprAreaClose, pprWinInfo, pprWinOpen -* -*-*/ -void -pprWinClose(pWin) -PPR_WIN *pWin; /* I pointer to plot window structure */ -{ - PPR_AREA *pArea, *pAreaNext; -#ifdef XWINDOWS - if (pWin->winType == PPR_WIN_SCREEN) { - if (pWin->attr.myGC) - XFreeGC(pWin->pDisp, pWin->attr.gc); - if (pWin->attr.bgGC) - XFreeGC(pWin->pDisp, pWin->attr.gcBG); - } -#endif - pArea = pWin->pAreaHead; - while (pArea != NULL) { - pAreaNext = pArea->pNext; - pprAreaClose(pArea); - pArea = pAreaNext; - } -#ifdef XWINDOWS - if (pWin->winType == PPR_WIN_SCREEN && pWin->userWindow == 0) - XCloseDisplay(pWin->pDisp); -#endif - free((char *)pWin); -} - -/*+/subr********************************************************************** -* NAME pprWinErase - erase a plot window -* -* DESCRIPTION -* Erase the contents of the entire plot window. -* -* RETURNS -* void -* -* SEE ALSO -* pprGridErase, pprPerimErase, pprAreaErase, pprRegionErase -* the ppr...Erase... entry points for the various drawing routines -* -*-*/ -void -pprWinErase(pWin) -PPR_WIN *pWin; /* I pointer to plot window structure */ -{ - if (pWin->winType == PPR_WIN_SCREEN) { -#ifdef SUNVIEW - pw_writebackground(pWin->pw, 0, 0, pWin->width, pWin->height, PIX_SRC); -#else -#if defined XWINDOWS - XClearArea(pWin->pDisp, pWin->plotWindow, 0, 0, - pWin->width, pWin->height, False); - XFlush(pWin->pDisp); -#endif -#endif - } -} - -/*+/internal****************************************************************** -* NAME pprWinEvHandler - handle events in the plotting window -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o action needs to depend on type of window -* o for SunView, a pw_lock() and pw_unlock() would make drawing more -* efficient -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -#ifdef SUNVIEW -static void -pprWinEvHandler(window, pEvent, pArg) -Window window; -Event *pEvent; -void *pArg; -{ - PPR_WIN *pWin; - - pWin = (PPR_WIN *)window_get(window, WIN_CLIENT_DATA); - if (pWin->winType != PPR_WIN_SCREEN) - PprAssertAlways(0); - if (event_action(pEvent) == WIN_REPAINT) { - if (window == pWin->canvas && !window_get(window, FRAME_CLOSED)) { - pprWinWrapup(pWin); - pWin->attr.ltCurr = -1; - pWin->attr.lineThick = 1; - pprWinAttr(pWin); - (pWin->drawFun)(pWin, pWin->pDrawArg); - } - } - else if (event_action(pEvent) == PPR_BTN_CLOSE) { - if (event_is_up(pEvent)) { - pprWinAttr(pWin); - window_destroy(pWin->frame); - pWin->frame = NULL; - pWin->canvas = NULL; - pprWinWrapup(pWin); - } - } -} -#endif - -#ifdef XWINDOWS -static void -pprWinEvHandler(pWin, pEvent) -PPR_WIN *pWin; -XEvent *pEvent; /* pointer to a window event structure */ -{ - - if (pEvent->type == Expose && pEvent->xexpose.count == 0) { -#define PPR_DEBUG_EVENTS 0 -#if PPR_DEBUG_EVENTS - (void)printf("expose event\n"); -#endif - pprWinWrapup(pWin); - pprWinAttr(pWin); - (pWin->drawFun)(pWin, pWin->pDrawArg); - } - else if (pEvent->type == ButtonRelease) { - pprWinAttr(pWin); - if (pEvent->xbutton.x < 0 || pEvent->xbutton.x > pWin->width || - pEvent->xbutton.y < 0 || pEvent->xbutton.y > pWin->height) { -#if PPR_DEBUG_EVENTS - (void)printf("button up but mouse not home\n"); - (void)printf("button x,y=%d,%d win x,y width,ht=%d,%d %d,%d\n", - pEvent->xbutton.x, pEvent->xbutton.y, - pWin->x, pWin->y, pWin->width, pWin->height); -#endif - ; /* no action */ - } - else if (pEvent->xbutton.button == PPR_BTN_CLOSE) { -#if PPR_DEBUG_EVENTS - (void)printf("button3 event\n"); -#endif - pprWinWrapup(pWin); - pWin->loopDone = 1; - } -#if PPR_DEBUG_EVENTS - else - (void)printf("other button event\n"); -#endif - } -#if PPR_DEBUG_EVENTS - else - (void)printf("some other event\n"); -#endif -} -#endif - -/*+/subr********************************************************************** -* NAME pprWinInfo - get some information about the plot window -* -* DESCRIPTION -* Get the size of the plot window and its position on the screen. -* -* RETURNS -* void -* -* NOTES -* 1. The information returned is window system dependent. To avoid -* portability problems, this information should be used only in -* calls to pprWinXxx routines. -* -*-*/ -void -pprWinInfo(pWin, pXpos, pYpos, pXwid, pYht) -PPR_WIN *pWin; /* I pointer to plot window structure */ -int *pXpos; /* O pointer to place to store window x coord., in pixels */ -int *pYpos; /* O pointer to place to store window y coord., in pixels */ -int *pXwid; /* O pointer to place to store window width, in pixels */ -int *pYht; /* O pointer to place to store window height, in pixels */ -{ - *pXpos = pWin->x; - *pYpos = pWin->y; - *pXwid = pWin->width; - *pYht = pWin->height; -} - -/*+/subr********************************************************************** -* NAME pprWinIsMono - test to see if plot window is monochrome -* -* DESCRIPTION -* -* RETURNS -* 1 if plot window is monochrome or gray scale -* 0 if plot window is color -* -*-*/ -int -pprWinIsMono(pWin) -PPR_WIN *pWin; /* I pointer to plot window structure */ -{ -#ifdef XWINDOWS - int screenNo; - Visual *pVisual; -#endif - -#ifdef XWINDOWS - if (pWin->winType != PPR_WIN_SCREEN) - return 1; - screenNo = DefaultScreen(pWin->pDisp); - pVisual = DefaultVisual(pWin->pDisp, screenNo); - if (pVisual->class != GrayScale && pVisual->class != StaticGray) - return 0; -#endif - return 1; /* color not supported if not XWINDOWS */ -} - -/*+/subr********************************************************************** -* NAME pprWinLoop - loop until "quit" event received in window -* -* DESCRIPTION -* Handles the interactions with the windowing system. The specific -* actions depend on the plot window type: -* -* PPR_WIN_SCREEN -* o creates a window on the screen -* o when the window actually appears, calls the caller's draw function -* o for all subsequent resize and expose events, calls the caller's -* draw function -* o when the right mouse button is clicked on the plot, closes the -* window and returns to the caller. The current position and size -* of the window are stored (and can be retrieved with pprWinInfo). -* -* PPR_WIN_POSTSCRIPT -* o calls the caller's draw function -* -* PPR_WIN_EPS -* o calls the caller's draw function -* -* The idea when using pprWinLoop is that a program -* will do some preliminary setup for the data to be plotted. -* Then the program must turn control over to the plot "window -* manager" using pprWinLoop, which will call the caller's -* actual plot routine. -* -* When pprWinLoop exits back to the calling program, that program -* can call pprWinInfo in order to "remember" the plot window -* size and position. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* BUGS -* o doesn't furnish information to the draw function which would allow -* a partial redraw -* o terminology is confusing and inconsistent: "draw" function, redraw, -* replot, repaint, etc. -* -* SEE ALSO -* pprWinOpen, pprWinInfo -* -* NOTES -* 1. Even though there aren't any "events" associated with plotting on -* a PostScript printer, this routine must be called even when using -* PPR_WIN_POSTSCRIPT and PPR_WIN_EPS, since this routine invokes the -* caller's "draw" function. -* -* EXAMPLE -* See pprWinOpen for an example of a replot function. -jjj -* -*-*/ -long -pprWinLoop(pWin, drawFun, pDrawArg) -PPR_WIN *pWin; /* I pointer to plot window structure */ -void (*drawFun)();/* I pointer to function to draw the plot */ -void *pDrawArg;/* I pointer to pass to drawFun */ -{ -#ifdef XWINDOWS - XEvent anEvent; /* a window event structure */ -#endif - - pWin->drawFun = drawFun; - pWin->pDrawArg = pDrawArg; - if (pprWinMap(pWin) != 0) - return -1; - if (pWin->winType == PPR_WIN_SCREEN) { -#ifdef SUNVIEW - window_main_loop(pWin->frame); -#else -#if defined XWINDOWS - while (pWin->loopDone == 0) { - XNextEvent(pWin->pDisp, &anEvent); - pprWinEvHandler(pWin, &anEvent); - } -#endif -#endif - } - else if (pWin->winType == PPR_WIN_POSTSCRIPT || - pWin->winType == PPR_WIN_EPS) { - (pWin->drawFun)(pWin, pWin->pDrawArg); - } - else - PprAssertAlways(0); - pprWinWrapup(pWin); - return 0; -} - -/*+/internal****************************************************************** -* NAME pprWinMap - create a plotting "window" and map it onto the display -* -* DESCRIPTION -* This routine actually creates a window on a display device. This -* must be done prior to drawing; the PPR_WIN structure must have -* been initialized by pprWinOpen . -* -* If the display "device" is a file for PostScript printing, then -* the "window" which is created isn't actually a window, but the -* plotting operations of the user routine don't know the difference. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* SEE ALSO -* pprWinOpen, pprWinLoop, pprWinWrapup -* -* NOTES -* 1. This routine is called automatically by pprWinLoop, so it should -* not be called by programs that use pprWinLoop. -* -*-*/ -long -pprWinMap(pWin) -PPR_WIN *pWin; /* I pointer to plot window structure */ -{ -#ifdef XWINDOWS - int screenNo, x, y, width, height; - XSizeHints sizeHints; -#endif - if (pWin->winType == PPR_WIN_SCREEN) { -#ifdef SUNVIEW - pWin->frame = window_create(NULL, FRAME, - FRAME_LABEL, pWin->title, - FRAME_NO_CONFIRM, 1, - WIN_EVENT_PROC, pprWinEvHandler, - WIN_CLIENT_DATA, pWin, - WIN_X, pWin->x, WIN_Y, pWin->y, - 0); - window_set(pWin->frame, WIN_CONSUME_PICK_EVENTS, WIN_NO_EVENTS, - ACTION_OPEN, ACTION_CLOSE, - ACTION_FRONT, ACTION_BACK, - WIN_MOUSE_BUTTONS, WIN_UP_EVENTS, 0, - 0); - pWin->canvas = window_create(pWin->frame, CANVAS, - WIN_WIDTH, pWin->width, - WIN_HEIGHT, pWin->height, - WIN_EVENT_PROC, pprWinEvHandler, - WIN_CLIENT_DATA, pWin, - CANVAS_AUTO_SHRINK, TRUE, - CANVAS_AUTO_EXPAND, TRUE, - CANVAS_FIXED_IMAGE, FALSE, - CANVAS_RETAINED, FALSE, - CANVAS_AUTO_CLEAR, TRUE, - 0); - pWin->pw = canvas_pixwin(pWin->canvas); - window_set(pWin->canvas, WIN_CONSUME_PICK_EVENTS, WIN_NO_EVENTS, - WIN_MOUSE_BUTTONS, WIN_UP_EVENTS, 0, - 0); - window_fit(pWin->frame); - window_set(pWin->frame, WIN_SHOW, 1, 0); - window_set(pWin->canvas, WIN_SHOW, 1, 0); - pArea->attr.myGC = 0; - pArea->attr.bgGC = 0; -#else -#if defined XWINDOWS - if (pWin->winDispName[0] == '\0') - pWin->pDisp = XOpenDisplay((char *)NULL); - else - pWin->pDisp = XOpenDisplay(pWin->winDispName); - if (pWin->pDisp == NULL) { - (void)printf("pprWinMap: XOpenDisplay to %s failed\n", - XDisplayName(pWin->winDispName)); - return -1; - } - screenNo = DefaultScreen(pWin->pDisp); - pWin->attr.gc = DefaultGC(pWin->pDisp, screenNo); - pWin->attr.myGC = 0; - sizeHints.x = x = pWin->x; - sizeHints.y = y = pWin->y; - sizeHints.width = width = pWin->width; - sizeHints.height = height = pWin->height; - sizeHints.flags = PSize | PPosition; - pWin->plotWindow = XCreateSimpleWindow(pWin->pDisp, - DefaultRootWindow(pWin->pDisp), - x, y, width, height, 1, - BlackPixel(pWin->pDisp, screenNo), - WhitePixel(pWin->pDisp, screenNo)); - - XSetStandardProperties(pWin->pDisp, pWin->plotWindow, - pWin->title, pWin->title, - None, 0, NULL, &sizeHints); - XSelectInput(pWin->pDisp, pWin->plotWindow, - ExposureMask | ButtonPressMask | ButtonReleaseMask); - XMapWindow(pWin->pDisp, pWin->plotWindow); - pWin->attr.gcBG = XCreateGC(pWin->pDisp, pWin->plotWindow, 0, NULL); - XCopyGC(pWin->pDisp, pWin->attr.gc, - GCBackground|GCForeground, pWin->attr.gcBG); - XSetFunction(pWin->pDisp, pWin->attr.gcBG, GXclear); - pWin->attr.bgGC = 1; -#endif -#endif - } - else if (pWin->winType == PPR_WIN_POSTSCRIPT || - pWin->winType == PPR_WIN_EPS) { - ; /* no action */ - } - else - PprAssertAlways(0); - - return 0; -} - -/*+/subr********************************************************************** -* NAME pprWinOpen - initialize a plotting "window" structure -* -* DESCRIPTION -* Initialize a plot window structure. This is the structure which -* keeps track of the information needed to interact with the -* device on which the "window" resides. The possible types of -* windows are: -* -* o PPR_WIN_SCREEN selects a window on a visual display. This -* will be a SunView or X window, depending on the version of -* the plotting used in linking the program. The pprWinOpen -* call actually creates a window, with the root window as the -* parent. The window thus created can be moved, resized, etc. -* according to the capabilities of the window manager of the -* windowing system being used. (To initialize a plotting -* window structure in a window which already exists, use -* pprWinOpenUW.) -* -* for SunView, -* `winDispName' is ignored and should be NULL -* `winTitle' appears on the window's title bar and icon -* `xPos' and `yPos' are pixel offsets from the upper left -* corner of the root window. If values of 0 are -* supplied, then the window will be positioned at -* 100,100. -* `xWid' and `yHt' are the width and height of the window, -* in pixels. If values of 0 are supplied, then -* a size of 512,512 will be used. -* -* for X11, -* `winDispName' specifies the X11 display name on which the -* plot window is to appear. If NULL, then the -* DISPLAY environment variable will be used. -* `winTitle' appears on the window's title bar and icon -* `xPos' and `yPos' are pixel offsets from the upper left -* corner of the root window. If values of 0 are -* supplied, then the window will be positioned at -* 100,100. -* `xWid' and `yHt' are the width and height of the window, -* in pixels. If values of 0 are supplied, then -* a size of 512,512 will be used. -* -* o PPR_WIN_POSTSCRIPT selects a "window" on a PostScript -* printer. -* -* `winDispName' is the name of a file to receive PostScript -* output. This is the file which will eventually -* be sent to a PostScript printer to get a hard -* copy of the plot. If the file exists when -* pprWinOpen is called, its contents are erased -* before writing begins. -* `winTitle' is ignored and should be NULL -* `xPos' and `yPos' are ignored -* `xWid' and `yHt' are the width and height of the window, -* in pixels. If values of 0 are supplied, then -* a size of 512,512 will be used. If the size is -* larger than the page, then the plot will be scaled -* to fit. If necessary, the plot will be printed in -* landscape mode, rather than the default of portrait -* mode. -* -* o PPR_WIN_EPS selects a "window" in an Encapsulated PostScript -* file. EPS files are intended to be included into documents -* prepared by word processing programs such as Interleaf and -* TeX. EPS files will not print directly on a PostScript printer. -* The description of the arguments for PPR_WIN_POSTSCRIPT applies, -* except that scaling and rotation aren't done. -* -* The pprXxx routines can be used for several different styles of -* usage: -* -* o a complete set of data is available prior to calling any of -* the plotting routines. In this case, grids can be drawn and -* data can be plotted at the same time. -* -* For this style of usage, the typical usage will be: -* pprWinOpen to "open" a plot window -* pprWinLoop to map the plot window to the screen -* and call the caller's replot function -* when the window is exposed, resized, -* etc. -* pprWinClose to "close" a plot window -* -* o no data (or only part of the data) is available prior to calling -* any of the plotting routines. In this case, at least some of -* the data must be plotted at a later time than when the grids -* are drawn. The pprXxx routines don't automatically support -* this style of usage fully, but they do provide some tools which -* make it relatively easy to implement. See pprWinOpenUW for -* more details. -* -* Under all circumstances, the calling program is expected to call -* pprWinClose when plotting is complete for the plot window. -* -* RETURNS -* pointer to window structure, or -* NULL if an error is encountered -* -* SEE ALSO -* pprWinOpenUW, pprWinClose, pprWinInfo, pprWinLoop -* -* EXAMPLES -* 1. Plot an existing set of data, where the data is stored in `dataStruct'. -* -* PPR_WIN *pWindow; -* . -* pWindow = pprWinOpen(PPR_WIN_SCREEN, NULL, "test", 0, 0, 0, 0); -* if (pWindow == NULL) -* abort(); -* if (pprWinLoop(pWindow, replot, &dataStruct) != 0) -* abort(); -* pprWinClose(pWindow); -* -*-*/ -PPR_WIN * -pprWinOpen(winType, winDispName, winTitle, xPos, yPos, xWid, yHt) -PPR_WIN_TY winType; /* I type of plot window: PPR_WIN_xxx */ -char *winDispName; /* I name of "display" or file for window */ -char *winTitle; /* I title for window title bar and icon */ -int xPos; /* I x position for window; 0 for default */ -int yPos; /* I y position for window; 0 for default */ -int xWid; /* I width of window; 0 for default */ -int yHt; /* I height of window; 0 for default */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - - if ((pWin = (PPR_WIN *)malloc(sizeof(PPR_WIN))) == NULL) { - (void)printf("pprWinOpen: couldn't malloc plot window struct\n"); - return NULL; - } - pWin->pAreaHead = NULL; - pWin->pAreaTail = NULL; - pWin->winType = winType; - pWin->userWindow = pWin->loopDone = 0; - pWin->drawFun = NULL; - pWin->pDrawArg = NULL; - if (xPos != 0) - pWin->x = xPos; - else if (winType == PPR_WIN_POSTSCRIPT || winType == PPR_WIN_EPS) - pWin->x = 0; - else - pWin->x = 100; - if (yPos != 0) - pWin->y = yPos; - else if (winType == PPR_WIN_POSTSCRIPT || winType == PPR_WIN_EPS) - pWin->y = 0; - else - pWin->y = 100; - if (xWid != 0) - pWin->width = xWid; - else if (winType == PPR_WIN_POSTSCRIPT || winType == PPR_WIN_EPS) - pWin->width = 0; - else - pWin->width = 512; - if (yHt != 0) - pWin->height = yHt; - else if (winType == PPR_WIN_POSTSCRIPT || winType == PPR_WIN_EPS) - pWin->height = 0; - else - pWin->height = 512; - - if (winDispName == NULL) - pWin->winDispName[0] = '\0'; - else if (strlen(winDispName) >= 120) { - (void)printf("pprWinOpen: plot file or display name too long\n"); - free((char *)pWin); - return NULL; - } - else - (void)strcpy(pWin->winDispName, winDispName); - - if (winTitle == NULL) - pWin->title[0] = '\0'; - else if (strlen(winTitle) >= 80) { - (void)printf("pprWinOpen: winTitle too long\n"); - free((char *)pWin); - return NULL; - } - else - (void)strcpy(pWin->title, winTitle); - - pWin->attr.lineThick = 1; - pWin->attr.ltCurr = -1; - pWin->attr.pPatt = NULL; - pWin->attr.myGC = 0; - pWin->attr.bgGC = 0; - -/*----------------------------------------------------------------------------- -* PostScript printer initialization -* o for PostScript, -* - send the %!PS line -* o for Encapsulated PostScript, -* - send the %!PS,EPS line -* - send the %%BoundingBox line -* o send the various PostScript programs needed -* o translate, rotate, and scale the PostScript axis as needed for -* the most recent size the window had. -*----------------------------------------------------------------------------*/ - if (winType == PPR_WIN_POSTSCRIPT || winType == PPR_WIN_EPS) { - int i; - int nLines; - double scale, xscale, yscale; - - if ((pWin->file = fopen(winDispName, "w")) == NULL) { - perror("opening PostScript or EPS file"); - PprAssertAlways(0); - } - if (winType == PPR_WIN_POSTSCRIPT) - (void)fprintf(pWin->file, "%%!PS\n"); - else { - (void)fprintf(pWin->file, "%%!PS-Adobe-2.0 EPSF-1.2\n"); - (void)fprintf(pWin->file, "%%%%BoundingBox: 0 0 %d %d\n", - pWin->width - 1, pWin->height - 1); - } - -/*----------------------------------------------------------------------------- -* write PostScript programs and defaults to file -*----------------------------------------------------------------------------*/ - nLines = sizeof(pprPSProg)/sizeof(char *); - for (i=0; ifile, "%s\n", pprPSProg[i]); - if (winType == PPR_WIN_POSTSCRIPT) { - if (pWin->width <= 560 && pWin->height <= 720) { - (void)fprintf(pWin->file, "%d %d translate\n", - (int)((612-pWin->width)/2), (760-pWin->height)); - } - else if (pWin->width <= 720 && pWin->height <= 560) { - (void)fprintf(pWin->file, "612 0 translate 90 rotate\n"); - (void)fprintf(pWin->file, "%d %d translate\n", - (int)((792-pWin->width)/2), (560-pWin->height)); - } - else if (pWin->width <= pWin->height) { - xscale = 560. / (double)pWin->width; - yscale = 720. / (double)pWin->height; - if (xscale <= yscale) - scale = xscale; - else - scale = yscale; - (void)fprintf(pWin->file, "%.3f %.3f scale\n", scale, scale); - (void)fprintf(pWin->file, "%d %d translate\n", - (int)((612./scale-pWin->width)/2.), - (int)(760./scale-pWin->height)); - } - else { - xscale = 560. / (double)pWin->width; - yscale = 720. / (double)pWin->height; - if (xscale <= yscale) - scale = xscale; - else - scale = yscale; - (void)fprintf(pWin->file, "612 0 translate 90 rotate\n"); - (void)fprintf(pWin->file, "%.3f %.3f scale\n", scale, scale); - (void)fprintf(pWin->file, "%d %d translate\n", - (int)((792./scale-pWin->width)/2.), - (int)(560./scale-pWin->height)); - } - } - } - return pWin; -} - -/*+/subr********************************************************************** -* NAME pprWinOpenUW - open a plot "window" to an existing User Window -* -* DESCRIPTION -* Initialize a plot window structure. This is the structure which -* keeps track of the information needed to interact with the -* device on which the "window" resides. -* -* This routine is for use when the caller already has a window in -* the windowing system. It is for use exclusively for PPR_WIN_SCREEN -* plot window type. The form of the call to this routine is heavily -* dependent on the windowing system being used. This routine provides -* the basis for obtaining `asynchronous' plotting. (It can also be -* used for `batched' plotting, in which all data is available prior -* to the first plotting call.) -* -* Under all circumstances, the calling program is expected to call -* pprWinClose when plotting is complete for the plot window. -* -* RETURNS -* pointer to window structure, or -* NULL if an error is encountered -* -* SEE ALSO -* pprWinOpenUW, pprWinClose, pprWinInfo, pprWinLoop -* -* EXAMPLES -* 1. for X11 -* -* PPR_WIN *pWin; -* Display *pDisp; -* Window plotWindow; -* GC plotGC; -* -* pWin = pprWinOpenUW(&pDisp, &plotWindow, &plotGC, NULL); -* ... -* pprWinReplot(pWin, drawFn, drawArg); -* ... -* pprWinClose(pWin); -* -* -* 2. for SunView -* -* PPR_WIN *pWin; -* Frame plotFrame; -* Canvas plotCanvas; -* -* pWin = pprWinOpenUW(&plotFrame, &plotCanvas, NULL, NULL); -* ... -* pprWinReplot(pWin, drawFn, drawArg); -* ... -* pprWinClose(pWin); -* -* 3. for XView -* (Since XView doesn't have any built-in line drawing capabilities, -* some fussing is needed to get the X11 items needed for plotting. -* In the following, pDisp, plotWindow, and plotGC are X11 items which -* are obtained from XView items.) -* -* PPR_WIN *pWin; -* Display *pDisp; -* Window plotWindow; -* GC plotGC; -* -* pDisp = (Display *)xv_get(frame, XV_DISPLAY); -* plotWindow = (Window)xv_get(canvas_paint_window(canvas), XV_XID); -* plotGC = DefaultGC(pDisp, DefaultScreen(pDisp)); -* -* pWin = pprWinOpenUW(&pDisp, &plotWindow, &plotGC, NULL); -* ... -* pprWinReplot(pWin, drawFn, drawArg); -* ... -* pprWinClose(pWin); -* -*-*/ -PPR_WIN * -pprWinOpenUW(pArg1, pArg2, pArg3, pArg4) -void *pArg1; -void *pArg2; -void *pArg3; -void *pArg4; -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - - if ((pWin = (PPR_WIN *)malloc(sizeof(PPR_WIN))) == NULL) { - (void)printf("pprWinOpenUW: couldn't malloc plot window struct\n"); - return NULL; - } - pWin->pAreaHead = NULL; - pWin->pAreaTail = NULL; - pWin->winType = PPR_WIN_SCREEN; - pWin->userWindow = 1; - pWin->loopDone = 0; - pWin->drawFun = NULL; - pWin->pDrawArg = NULL; - pWin->winDispName[0] = '\0'; - pWin->title[0] = '\0'; -#ifdef SUNVIEW - pWin->frame = *(Frame *)pArg1; - pWin->canvas = *(Canvas *)pArg2; - pWin->pw = canvas_pixwin(pWin->canvas); - pWin->attr.bgGC = 0; -#else -#if defined XWINDOWS - pWin->pDisp = *(Display **)pArg1; - pWin->plotWindow = *(Window *)pArg2; - pWin->attr.gc = *(GC *)pArg3; - pWin->attr.myGC = 0; - pWin->attr.gcBG = XCreateGC(pWin->pDisp, pWin->plotWindow, 0, NULL); - XCopyGC(pWin->pDisp, pWin->attr.gc, - GCBackground|GCForeground, pWin->attr.gcBG); - XSetFunction(pWin->pDisp, pWin->attr.gcBG, GXclear); - pWin->attr.bgGC = 1; -#endif -#endif - pprWinAttr(pWin); - - pWin->attr.lineThick = 1; - pWin->attr.ltCurr = -1; - pWin->attr.pPatt = NULL; - - return pWin; -} - -/*+/subr********************************************************************** -* NAME pprWinReplot - redraw a plot in a user owned window -* -* DESCRIPTION -* Calls the "replot" function to repaint the plot window. This -* routine is intended to be used with "user owned" plot windows -* which have been opened with pprWinOpenUW. -* -* Prior to calling the replot function, this routine determines -* the size of the actual window and rescales the existing plot -* areas. -* -* RETURNS -* void -* -* SEE ALSO -* pprWinOpenUW -* -*-*/ -void -pprWinReplot(pWin, pFunc, pArg) -PPR_WIN *pWin; -void (*pFunc)(); -void *pArg; -{ - int width, height; - PPR_AREA *pArea; - - width = pWin->width; - height = pWin->height; - pprWinAttr(pWin); - if (pWin->width != width || pWin->height != height) { - pArea = pWin->pAreaHead; - while (pArea != NULL) { - pprAreaRescale(pArea, pArea->xLeft, pArea->yBot, - pArea->xRight, pArea->yTop); - pArea = pArea->pNext; - } - } - pWin->drawFun = pFunc; - pWin->pDrawArg = pArg; - (pWin->drawFun)(pWin, pWin->pDrawArg); - pprWinWrapup(pWin); -} - -/*+/internal****************************************************************** -* NAME pprWinWrapup - wrapup plotting operations -* -* DESCRIPTION -* Wrap up plotting operations. -* -* RETURNS -* void -* -* SEE ALSO -* pprWinMap, pprWinOpen, pprWinLoop, pprWinOpenUW, pprWinReplot -* -* NOTES -* 1. This routine is called automatically by pprWinLoop. It should be -* used only by programs which don't use pprWinLoop. -* -*-*/ -void -pprWinWrapup(pWin) -PPR_WIN *pWin; /* I pointer to plot window structure */ -{ - if (pWin->winType == PPR_WIN_POSTSCRIPT) - (void)fprintf(pWin->file, "showpage"); - if (pWin->winType == PPR_WIN_POSTSCRIPT || pWin->winType == PPR_WIN_EPS) { - (void)fclose(pWin->file); - pWin->file = NULL; - } -} - -/*+/subr********************************************************************** -* NAME pprYFracToXFrac - convert a Y fraction to an X fraction -* -* DESCRIPTION -* Converts a value which is a fraction of window height into a value -* which is a fraction of window width, so that the two values will -* represent the same physical size, in pixels. -* -* This routine is useful for laying out a plot area, especially when -* a grid with annotations and labels is to be used. The choice of -* "data area" size (i.e., the size of the grid) depends on the size -* of the characters which will be used for the annotations and -* labels. -* -* RETURNS -* X fraction -* -* SEE ALSO -* pprText -* -* EXAMPLE -* A plot area is use the full width and the vertical 1/3 of the window. -* x values range from 0 to 100, while y is from -10 to 10. The x -* axis is to be divided into 10 divisions, the y into 4. Use -* the default character size for annotations and labels. Also, -* use the default window position and size. -* -* PPR_WIN *pWin; -* PPR_AREA *pArea; -* float charHt; height as a fraction of window height -* float charWid; width as a fraction of window width -* -* charHt = PprDfltCharHt(.33, .67); -* charWid = pprYFracToXFrac(pWin, charHt); -* pArea = pprAreaOpen(pWin, 12.*charWid, .33+6.*charHt, 1., .67, -* 0., -10., 100., 10, 4, charHt); -* -*-*/ -double -pprYFracToXFrac(pWin, yFrac) -PPR_WIN *pWin; /* I pointer to plot window structure */ -double yFrac; /* I fraction of window height */ -{ - return (yFrac * pWin->height / pWin->width); -} - -/*+/internal****************************************************************** -* NAME pprSleep - simple sleep routine to use with plots -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -static void -pprSleep(seconds, usec) -int seconds; /* I number of seconds (added to usec) to sleep */ -int usec; /* I number of micro-sec (added to sec) to sleep */ -{ -#ifndef vxWorks -/* MDA - usleep isn't POSIX - usleep((unsigned)(seconds*1000000 + usec)); -*/ - sleep((unsigned int)seconds); -#else - int ticks; - static int ticksPerSec=0; - static int usecPerTick; - - if (ticksPerSec == 0) { - ticksPerSec = sysClkRateGet(); - usecPerTick = 1000000 / ticksPerSec; - } - - ticks = seconds*ticksPerSec + usec/usecPerTick + 1; - taskDelay(ticks); -#endif -} diff --git a/src/util/pprPlot.man b/src/util/pprPlot.man deleted file mode 100644 index a8b2118ac..000000000 --- a/src/util/pprPlot.man +++ /dev/null @@ -1,1769 +0,0 @@ -TITLE pprSubr.c - portable plotting routines - -DESCRIPTION - These routines support simple 2-D plotting in a "window". The - window can be either an actual display window, a PostScript - printer page, or an EPS file for Encapsulated PostScript. - -QUICK REFERENCE -PPR_AREA *pArea; pointer to a plot area - PPR_WIN *pWin; pointer to a plot "window" - - void pprAnnotX( pArea, offset, dataL, dataR, nDiv, - drawLine, xLabel, xAnnot, angle ) - void pprAnnotY( pArea, offset, dataB, dataT, nDiv, - drawLine, yLabel, yAnnot, angle ) - void pprAnnotYMark( pArea, offset, markNum ) - void pprAreaClose( pArea ) - void pprAreaErase( pArea fracL, fracB, fracR, fracT ) -PPR_AREA *pprAreaOpen( pWin, fracL, fracB, fracR, fracT, - dataL, dataB, dataR, dataT, - nXint, nYint, charHt ) -PPR_AREA *pprAreaOpenDflt( pWin, fracL, fracB, fracR, fracT, - dataL, dataB, dataR, dataT ) - void pprAreaRescale( pArea, dataL, dataB, dataR, dataT ) - long pprAreaSetAttr( pArea, code, attrVal, pAttr ) - code: PPR_ATTR_{CLIP,COLORNUM,BG,FG,KEYNUM,LINE_THICK,NOCLIP,PATT_ARRAY} - void pprAutoEnds( dbl1, dbl2, >pNewDbl1, >pNewDbl2 ) - void pprAutoInterval( dbl1, dbl2, >pNint ) - void pprAutoRangeD( dblAry, nPts, >minDbl, >maxDbl ) - void pprAutoRangeF( fltAry, nPts, >minDbl, >maxDbl ) - void pprAutoRangeL( lngAry, nPts, >minDbl, >maxDbl ) - void pprAutoRangeS( shtAry, nPts, >minDbl, >maxDbl ) - void pprChar( pArea, xDbl, yDbl, char, charHt, angle ) - double pprCos_deg( angle ) - void pprCvtDblToTxt( >text, width, dblVal, nSigDigits ) - void pprGrid( pArea ) - void pprGridErase( pArea ) - void pprGridLabel( pArea, xLabel, xAnnot, yLabel, yAnnot, angle) - void pprLineD( pArea, xDblAry, yDblAry, nPts ) - void pprLineF( pArea, xFltAry, yFltAry, nPts ) - void pprLineL( pArea, xLngAry, yLngAry, nPts ) - void pprLineS( pArea, xShtAry, yShtAry, nPts ) - void pprLineSegD( pArea, xDbl1, yDbl1, xDbl2, yDbl2 ) - void pprLineSegL( pArea, xLng1, yLng1, xLng2, yLng2 ) - void pprMarkD( pArea, xDbl1, yDbl1, markNum ) - void pprMarkL( pArea, xLng1, yLng1, markNum ) - void pprMoveD( pArea, xDbl1, yDbl1, penDown ) - void pprPerim( pArea ) - void pprPerimErase( pArea ) - void pprPerimLabel( pArea, xLabel, xAnnot, yLabel, yAnnot, angle) - void pprPointD( pArea, xDbl1, yDbl1 ) - void pprPointL( pArea, xLng1, yLng1 ) - double pprSin_deg( angle ) - void pprText( pArea, xDbl, yDbl, text, just, charHt, angle) - just: PPR_TXT_{CEN,RJ,LJ} - void pprWinClose( pWin ) - void pprWinErase( pWin ) - void pprWinInfo( pWin, >pXpos, >pYpos, >pXwid, >pYht ) - int pprWinIsMono( pWin ) - long pprWinLoop( pWin, drawFn, pDrawArg ) - void drawFn(pWin, pDrawArg) - PPR_WIN *pprWinOpen( winType, dispName, winTitle, xPos, yPos, xWid,yHt) - winType: PPR_WIN_{SCREEN,POSTSCRIPT,EPS} - PPR_WIN *pprWinOpenUW( pFrame, pCanvas, NULL, NULL ) - PPR_WIN *pprWinOpenUW( ppDisp, pWindow, pGC, NULL ) - void pprWinReplot( pWin, drawFn, pDrawArg ) - long pprWinSetAttr( pWin, code, pAttr ) - code: PPR_ATTR_{COLORNUM,GC,KEYNUM,LINE_THICK,PATT_ARRAY} - -DESCRIPTION (continued) - Plotting is done within "plot areas" which are defined within - the window. Plot areas can be as large as the window, and they - can overlap, if desired. Clipping service is optional, since - plot areas are often calibrated for the "normal" range of data, - and it is useful to see what's happening if the data are outside - the normal range. - - One non-intuitive aspect of the term "plot area" is that the - usual case ALWAYS plots outside the plot area. Generally, this - happens when annotations and labels are added to a grid. The - plot area itself only specified where the edges of the grid were - to be drawn. Because of this, determining the size and placement - of a plot area must take into account the necessary margins for - text. (pprAreaOpenDflt automatically takes care of margins.) - - Most plotting is done using "data coordinates", which are the - actual data values. In some cases, coordinates or distances are - specified in terms of a fraction of the window height (see, for - example, pprAreaOpen or pprText). - - Also provided in this package are some routines for interacting - with the "window". In many cases, this means that a plotting - program can totally avoid any knowledge of, or dependence on, a - particular windowing environment. This makes easily available - the capability for producing hard copies of plots on a PostScript - printer. - - Many routines in this package require that values be - represented with type 'double'. In some cases, however, other - data types are directly supported, so that the caller doesn't - need to alter the way data are stored. - -BUGS -o Only linear axes are presently supported -o There is presently no mechanism to allow a calling program to - do other work while a plot is on the screen. It would be nice - for a program to be able to periodically check with this package - to see if resize or expose events need to be serviced. -o The SunView version of this package won't run properly with - programs which use the SunOs LightWeight Process library. -o The SunView version of this package doesn't handle color. - -EXAMPLE - The following program plots the first 80 points of a parabola. The - size and position of the plot window can be freely changed; the - window can be covered and exposed, iconified and de-iconified, etc. - When a `click right' is done in the plot window, the window is - closed. A PostScript file named "testPS" is produced; the size of - the plot in this file is about the same as it was when the plot - window was closed. (The plot window can be closed using the `quit' - item on the window's title bar menu (but not under X!!).) - - The program is compiled and linked for SunView with the following - command. (It will be necessary to find where pprPlot.o and - pprPlotDefs.h are located and possibly `fix up' the command.) - - cc plotTest.c pprPlot.o -lsuntool -lsunwindow -lpixrect -lm - - The program is compiled and linked for X with the following - command. (It will be necessary to find where pprPlot.o and - pprPlotDefs.h are located and possibly `fix up' the command.) - - cc plotTest.c pprPlot.o -lX11 -lm - - (As of Feb 6, 1991, plotTest.c is available on the AT-division - open network in ~gta/ar/plotTest.c. It should be copied into - the user's working directory before using it.) - - (As of Feb 6, 1991, pprPlot is available on the AT-division - open network in ~gta. Until access to this software has been - formalized, use the following for Sun3/SunView: - cc plotTest.c -I/home/obiwan/gtacs/h /home/obiwan/gtacs/ar/pprPlotS.o - -lsuntool -lsunwindow -lpixrect -lm - (For Sun3/X, use the following: - cc plotTest.c -I/home/obiwan/gtacs/h /home/obiwan/gtacs/ar/pprPlotX.o - -lX11 -lm - (For Sun4 builds, use "/ar/ar4/" in place of "/ar/" in the above - commands.) - - #include - #include - - #define NPTS 80 ----------------------------------------------------------------------------- - define a structure for holding the data. This is needed because the - replot routine (which does the actual plotting) is only given a pointer - to the information it needs. ----------------------------------------------------------------------------- - typedef struct { - int nPts; - float x[NPTS]; - float y[NPTS]; - double xMin; - double xMax; - double yMin; - double yMax; - } MY_DATA; - - void replot(); - - main() - { - int i; - int x=0,y=0,width=0,height=0; - PPR_WIN *pWin; - MY_DATA myData; - long stat; - ----------------------------------------------------------------------------- - generate the data in the structure. Once it's generated, figure out - the range of values and put the range into the structure using - pprAutoRangeF. This specific routine was chosen because the data - is in "float" arrays. Different forms of data would result in choosing - a different routine. - - The routine pprAutoEnds is available to "round" the endpoints of the - axes to "nicer" values. Depending on the application, it will be - attractive to use this following the pprAutoRange call. ----------------------------------------------------------------------------- - myData.nPts = NPTS; - for (i=0; ixMin, pMyData->yMin, pMyData->xMax, pMyData->yMax, - 5, 5, charHt); - pprPerimLabel(pArea, "x label", NULL, "y label", NULL, 0.); - - pprLineF(pArea, pMyData->x, pMyData->y, pMyData->nPts); - - pprAreaClose(pArea); - - return; - } - - -NAME pprAnnotX - annotate an X axis, perhaps drawing a line and tick marks - -DESCRIPTION - Annotate an X axis, placing annotations at the major tick intervals. - - If desired, an axis line is also drawn, with tick marks at the - major intervals. The tick marks are drawn using the "generic" - line attributes for the plot window. The axis line is drawn with - the line attributes of the plot area; this allows using a dashed - line pattern or color to associate an axis with a data line. - - The annotations and label are drawn using the default character - height for the plot area, in the color, if any, for the plot area. - - An array of text strings can be supplied for annotating the tick - intervals. This is useful if the desired annotations are text. - If an annotation array isn't supplied, then numeric annotations - are generated. - - To allow multiple calibrations for an axis, this routine accepts - an `offset' argument. If this argument is greater than 0, then - the annotation and labeling activity occurs that many lines (in - the default character height for the plot area) below the axis - which was established by pprAreaOpen. - - An alternate entry point, pprAnnotX_wc, is available to use the - plot window's color for the annotation. - -RETURNS - void - -BUGS -o only linear axes are handled -o doesn't presently support offset processing - -NOTES -1. Uses a space below the axis of 5 character heights. - -SEE ALSO - pprAnnotY, pprGrid, pprPerim, pprAreaOpen, pprAreaSetAttr - -SYNOPSIS - -void -pprAnnotX(pArea, offset, xLeft, xRight, xNint, drawLine, xLabel, xAnnot, angle) -PPR_AREA *pArea; /* IO pointer to plotter area */ -int offset; /* I offset as number of lines below yBot to annotate */ -double xLeft; /* I x data value at left end of axis */ -double xRight; /* I x data value at right end of axis */ -int xNint; /* I number of major intervals for axis */ -int drawLine; /* I 1 says to draw a line and tick marks */ -char *xLabel; /* I label for x axis, or NULL; oriented horizontal */ -char **xAnnot; /* I pointer to array of x annotations, or NULL */ -double angle; /* I orientation angle for annotation text; 0. or 90. */ - -NAME pprAnnotY - annotate a Y axis, perhaps drawing line and tick marks - -DESCRIPTION - Annotate a Y axis, placing annotations at the major tick intervals. - - If desired, an axis line is also drawn, with tick marks at the - major intervals. The tick marks are drawn using the "generic" - line attributes for the plot window. The axis line is drawn with - the line attributes of the plot area; this allows using a dashed - line pattern or color to associate an axis with a data line. - - The annotations and label are drawn using the default character - height for the plot area, in the color, if any, for the plot area. - - An array of text strings can be supplied for annotating the tick - intervals. This is useful if the desired annotations are text. - If an annotation array isn't supplied, then numeric annotations - are generated. - - To allow multiple calibrations for an axis, this routine accepts - an `offset' argument. If this argument is greater than 0, then - the annotation and labeling activity occurs that many lines (in - the default character height for the plot area) to the left of - the axis which was established by pprAreaOpen. - - An alternate entry point, pprAnnotY_wc, is available to use the - plot window's color for the annotation. - -RETURNS - void - -BUGS -o only linear axes are handled - -NOTES -1. Uses a space to the left of the axis of 12 character heights if - annotations are horizontal, and a space of 5 character heights - if they are vertical. - -SEE ALSO - pprAnnotX, pprGrid, pprPerim, pprAreaOpen, pprAreaSetAttr - -SYNOPSIS - -void -pprAnnotY(pArea, offset, yBot, yTop, yNint, drawLine, yLabel, yAnnot, angle) -PPR_AREA *pArea; /* IO pointer to plotter area */ -int offset; /* I number of lines to left of axis for annotation */ -double yBot; /* I y data value at bottom end of axis */ -double yTop; /* I y data value at top end of axis */ -int yNint; /* I number of major intervals for axis */ -int drawLine; /* I 1 says to draw a line and tick marks */ -char *yLabel; /* I label for y axis, or NULL; oriented vertical */ -char **yAnnot; /* I pointer to array of y annotations, or NULL */ -double angle; /* I orientation angle for annotation text; 0. or 90. */ - -NAME pprAnnotYMark - add plot marks to a Y axis annotation - -DESCRIPTION - Draw two plot marks at the foot of the Y axis annotation, to allow - associating the axis with a particular set of data. - -RETURNS - void - -BUGS -o only linear axes are handled - -SEE ALSO - pprMark, pprAnnotY - -EXAMPLE - -SYNOPSIS - -void -pprAnnotYMark(pArea, offset, markNum) -PPR_AREA *pArea; /* I pointer to plot area structure */ -int offset; /* I number of lines to left of axis for annotation */ -int markNum; /* I mark number */ - -NAME pprArc - draw an arc - -DESCRIPTION - Draw an arc. The arc is specified by a radius and two angles. The - angles, in degrees, specify the angle at which the arc starts and - the angle at which it ends. An angle increment specifies both the - direction of the arc and the size of the chords which approximate - the arc. Angles are measured counter-clockwise from the positive - X axis. - - The radius of the arc is treated as representing data values in the - plot area. If both the X and Y axes of the plot area have the - same data scaling, then circular arcs will be produced (assuming - a square plot area). If the X scaling is not the same as the Y - scaling, then elliptical arcs will be produced. - - The arc is drawn using the color, dashed line, and other attributes - of the plot area. Alternate entry points are: - - pprArcD_ac uses the area color, but ignores other - attributes - -RETURNS - void - -SEE ALSO - -SYNOPSIS - -void -pprArcD(pArea, xDbl, yDbl, radDbl, angle1, angle2, angleIncr) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double xDbl; /* I x data coordinate for center of arc */ -double yDbl; /* I y data coordinate for center of arc */ -double radDbl; -double angle1; /* I angle to start arc */ -double angle2; /* I angle to stop arc */ -double angleIncr; /* I size of steps in drawing arc */ - -NAME pprAreaClose - close a plot area - -DESCRIPTION - Frees the memory associated with a plot area pointer and does other - cleanup operations. This routine should be called prior to calling - pprWinClose. - -RETURNS - void - -SYNOPSIS - -void -pprAreaClose(pArea) -PPR_AREA *pArea; /* I pointer to plot area structure */ - -NAME pprAreaErase - erase an area within a plot window - -DESCRIPTION - Erases an area within a plot window. - -RETURNS - void - -SEE ALSO - pprWinErase, pprGridErase, pprPerimErase - -NOTES -1. Another mode of calling pprAreaErase, in which the arguments are - pixel offsets from the data area boundaries, can be invoked by - having one or more of the arguments be greater than 1. or less - than 0. - -EXAMPLES -1. Erase within a data area, preserving the perimeter line. - - pprAreaErase(pArea, 1., 1., -1., -1.); - -SYNOPSIS - -void -pprAreaErase(pArea, wfracXleft, wfracYbot, wfracXright, wfracYtop) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double wfracXleft; /* I x window fraction of left edge of area */ -double wfracYbot; /* I y window fraction of bottom edge of area */ -double wfracXright; /* I x window fraction of right edge of area */ -double wfracYtop; /* I y window fraction of top edge of area */ - -NAME pprAreaOpen - initialize a plot area - -DESCRIPTION - Initialize a plot area within the plot window. This initialization - must be done before calling any of the routines which do actual - plotting. - - This routine establishes a rectangular "data area" within the plot - window. It is within the data area that data will be plotted. - The size and position of the data area are specified in terms - of fractions of the window size; they are expressed as - "coordinates" of the lower left and upper right corners of the - area. The data area specified in the call to pprAreaOpen does - NOT include space for axis annotations and labels. (pprAreaOpenDflt - can be used to automatically get the necessary margins.) - - This routine must also be told the data values at the two corners - of the data area in order to determine scaling. - - In addition to establishing scaling, this routine accepts information - about how many major divisions there are for each axis and what - default character height is to be used for displaying text within - the plot area (see pprText for more information). If any of these - parameters is specified as zero, this routine chooses an appropriate - value. - - The default line attributes for the plot are copied from those of - the plot window. pprAreaSetAttr can be used to change them. Under - X11, a gc is created for the plot area with the foreground and - background being copied from the gc for the plot window; - pprAreaSetAttr can be used to change the foreground and background. - - When plotting is complete for a plot area, pprAreaClose should - be called. - -RETURNS - pointer to plot area, or - NULL - -BUGS -o only linear calibration is handled - -SEE ALSO - pprWinOpen, pprAreaOpenDflt, pprAreaSetAttr - pprAutoEnds, pprAutoInterval, pprAutoRange - pprText - -EXAMPLE -1. Set up an area which occupies the full width of the window, but - which uses the middle third vertically. The range for x values - is 0 to 100; for y, the range is -10 to 10. Both the x and y - axes are to be divided into 5 intervals. - - Allow space below and to the left of the actual area for plotting - for pprPerim to place labels and annotations. The required - size of "margins" depends on the size of characters used, so a - default size is determined (and put into effect as part of the - pprAreaOpen call). - - PPR_AREA *pArea; - double charHt, charHtX; - - charHt = PprDfltCharHt(.33, .67); - charHtX = pprYFracToXFrac(pWin, charHt); - pArea = pprAreaOpen(pWin, 0.+12.*charHtX, .33+6*charHt, 1., .67, - 0., -10., 100., 10., 5, 5, charHt); - ... - pprAreaClose(pArea); - -SYNOPSIS - -PPR_AREA * -pprAreaOpen(pWin, wfracXleft, wfracYbot, wfracXright, wfracYtop, - xLeft, yBot, xRight, yTop, xNint, yNint, charHt) -PPR_WIN *pWin; /* I pointer to plot window structure */ -double wfracXleft; /* I x window fraction of left edge of data area */ -double wfracYbot; /* I y window fraction of bottom edge of data area */ -double wfracXright; /* I x window fraction of right edge of data area */ -double wfracYtop; /* I y window fraction of top edge of data area */ -double xLeft; /* I x data value at left side of data area */ -double yBot; /* I y data value at bottom side of data area */ -double xRight; /* I x data value at right side of data area */ -double yTop; /* I y data value at top side of data area */ -int xNint; /* I x axis number of intervals; if <=0, a default - value is provided */ -int yNint; /* I y axis number of intervals; if <=0, a default - value is provided */ -double charHt; /* I value to use as default for character size, as - a fraction of window height; if <= 0., - a default value is provided */ - -NAME pprAreaOpenDflt - initialize a plot area using defaults - -DESCRIPTION - Initialize a plot area within the plot window. This initialization - must be done before calling any of the routines which do actual - plotting. - - This routine is a variant on pprAreaOpen. It performs the functions - of that routine, but uses some defaults rather than making the - caller determine specific values. In particular, this routine: - - o sets a default character height - - o determines the number of major divisions for each axis - - o establishes, inside the plot area specified, margins which - will be adequate for annotating and labeling the axes. - - See the description for pprAreaOpen for additional details. - - When plotting is complete for a plot area, pprAreaClose should - be called. - -RETURNS - pointer to plot area, or - NULL - -BUGS -o only linear calibration is handled - -SEE ALSO - pprWinOpen, pprAreaOpen, pprAreaSetAttr - pprAutoEnds, pprAutoInterval, pprAutoRange - pprText - -SYNOPSIS - -PPR_AREA * -pprAreaOpenDflt(pWin, wfracXleft, wfracYbot, wfracXright, wfracYtop, - xLeft, yBot, xRight, yTop) -PPR_WIN *pWin; /* I pointer to plot window structure */ -double wfracXleft; /* I x window fraction of left edge of plot area */ -double wfracYbot; /* I y window fraction of bottom edge of plot area */ -double wfracXright; /* I x window fraction of right edge of plot area */ -double wfracYtop; /* I y window fraction of top edge of plot area */ -double xLeft; /* I x data value at left side of data area */ -double yBot; /* I y data value at bottom side of data area */ -double xRight; /* I x data value at right side of data area */ -double yTop; /* I y data value at top side of data area */ - -NAME pprAreaRescale - change scaling for existing plot area - -DESCRIPTION - Changes the scaling for a plot area using new data values at the - edges of the data area. The actual size and position of the - data area within the plot window aren't changed. - - No re-drawing is done by this routine. Typically, the caller will - erase the appropriate area, draw the grid or perimeter, set the - area for clipping, and, finally, replot the data. - - Default character height for the plot area is altered proportionally - to the rescaling of the plot area. - -RETURNS - void - -SEE ALSO - pprAreaSetAttr, pprAreaErase - -SYNOPSIS - -void -pprAreaRescale(pArea, xLeft, yBot, xRight, yTop) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double xLeft; /* I x data value at left side of data area */ -double yBot; /* I y data value at bottom side of data area */ -double xRight; /* I x data value at right side of data area */ -double yTop; /* I y data value at top side of data area */ - -NAME pprAreaSetAttr - set attributes for a plot area - -DESCRIPTION - Set individual attributes for a plot area. In most cases, the - attributes affect the drawing of lines in the plot area. - - To use this routine, an attribute code and a corresponding value - are supplied. The form of the value argument depends on the code. - - o PPR_ATTR_CLIP sets the plot area so that line segments which lie - outside the data area won't be drawn, but will terminate at their - intersection with the edge of the data area. Clipping can be - disabled by setting the PPR_ATTR_NOCLIP attribute; the default when - a plot area is created is no clipping. - - pprAreaSetAttr(pArea, PPR_ATTR_CLIP, 0, NULL); - pprAreaSetAttr(pArea, PPR_ATTR_NOCLIP, 0, NULL); - - o PPR_ATTR_COLORNUM selects a color for use in drawing lines in a plot - area. For monochrome screens, no action is taken. There are - PPR_NCOLORS colors provided, numbered starting with 1. A colorNum - of 0 selects black. - - int colorNum; - colorNum = 4; - pprAreaSetAttr(pArea, PPR_ATTR_COLORNUM, colorNum, NULL); - - o PPR_ATTR_BG installs a caller-supplied background pixel value in - the gc for the plot area. (For use only with X11. Under X11, - pprAreaOpen initially set the gc for the plot area to have the - same foreground and background colors as the gc for the plot window.) - - pprAreaSetAttr(pArea, PPR_ATTR_BG, 0, &bg); - - o PPR_ATTR_FG installs a caller-supplied foreground pixel value in - the gc for the plot area. (For use only with X11. Under X11, - pprAreaOpen initially set the gc for the plot area to have the - same foreground and background colors as the gc for the plot window.) - - pprAreaSetAttr(pArea, PPR_ATTR_FG, 0, &fg); - - o PPR_ATTR_KEYNUM selects a legend key for identifying lines drawn - in a plot area, and thus distinguishing them from the lines drawn - by a different plot area. This is primarily useful for overlapping - plot areas, where several sets of data are drawn on the same axis. - The key number, which is expected to be in the range 0 to PPR_NKEYS, - inclusive, selects either a dashed line pattern or a color, - depending on the nature of the device on which the plot window - resides. There are PPR_NKEYS unique patterns and colors; a key - number of 0 resets to a "plain", solid line. - - Use of the PPR_ATTR_KEYNUM option provides a way to restart a - dashed line pattern at its beginning. - - int keyNum; - keyNum = 4; - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, keyNum, NULL); - - o PPR_ATTR_LINE_THICK sets the line thickness for the plot area. The - thickness is the integer number of thousandths of plot window height. - The thickness is used for data drawing operations. A thickness of - 0. results in pixel-thick lines. As an example, a thickness of 10 - represents 10/1000 (or .01) of the window height. - - int thick; - thick = 3; .003 of window height - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - - o PPR_ATTR_PATT_ARRAY installs a caller-supplied dashed line pattern - array. This is an array of type short. The first element - contains a number of pixels with `pen down'; the second has a - number of pixels with `pen up'; the third with `pen down'; etc. - Following the last element must be an element with a value of 0 . - (pprAreaSetAttr stores only a pointer to the array, so the caller - must preserve the array until pprAreaClose is called or until - pprAreaSetAttr is called to `de-install' the pattern array.) An - array pointer of NULL resets the plot area back to normal drawing. - - short pattern[]={16,4,2,4,0}; - pprAreaSetAttr(pArea, PPR_ATTR_PATT_ARRAY, 0, pattern); - - - Some pprXxx routines don't use the attributes from the plot - area, but instead use the `generic' attributes from the - plot window structure. The pprLineSegx_wc and pprMovex_wc - routines provide an explicit mechanism for using the plot window - attributes. - -RETURNS - 0, or - -1 if an error is encountered - -BUGS -o color is supported only for X -o when color is used, ALL output for the plot area is colored; it's - not clear yet whether this is a bug or a feature. -o line thickness doesn't operate consistently under SunView - -SEE ALSO - pprAreaOpen - -SYNOPSIS - -long -pprAreaSetAttr(pArea, code, arg, pArg) -PPR_AREA *pArea; /* IO pointer to plotter area */ -PPR_ATTR_CODE code; /* I attribute code: one of PPR_ATTR_xxx */ -int arg; /* I attribute value, or 0 */ -void *pArg; /* I pointer to attribute, or NULL */ - -NAME pprAutoEnds - choose `clean' endpoint valuess for an axis - -DESCRIPTION - For a specific numeric range, this routine calculates a possibly - altered numeric range which will produce more tasteful axis - calibration. - -RETURNS - void - -BUGS -o this routine should probably focus some attention on choice of - number of intervals for an axis; presently, the new endpoints - chosen by this routine may be difficult to use for choosing - interval size -o uses exp10(), which doesn't exist in VxWorks -o only linear calibration is handled - -SEE ALSO - pprAutoInterval, pprAutoRange, pprAreaOpen - -SYNOPSIS - -void -pprAutoEnds(left, right, pLeftNew, pRightNew) -double left; /* I leftmost value */ -double right; /* I rightmost value */ -double *pLeftNew; /* O new leftmost value */ -double *pRightNew; /* O new rightmost value */ - -NAME pprAutoInterval - figure out good interval size for an axis - -DESCRIPTION - Determine a "good" interval size for an axis, so that axis - annotation will be tasteful. - -RETURNS - void - -BUGS -o this routine always chooses to divide an axis into 5 intervals -o only linear calibration is handled - -SEE ALSO - pprAutoEnds, pprAutoRange, pprAreaOpen - -SYNOPSIS - -void -pprAutoInterval(val1, val2, pNint) -double val1; /* I value at one end of axis */ -double val2; /* I value at other end of axis */ -int *pNint; /* O number of intervals */ - -NAME pprAutoRange - find minimum and maximum values for an array - -DESCRIPTION - Finds the minimum and maximum values in an array of values. - - Four different routines are available, depending on the type of - the input array. Each returns the min and max as a double: - - void pprAutoRangeD(doubleArray, nPoints, doubleMin, doubleMax) - void pprAutoRangeF(floatArray, nPoints, doubleMin, doubleMax) - void pprAutoRangeL(longArray, nPoints, doubleMin, doubleMax) - void pprAutoRangeS(shortArray, nPoints, doubleMin, doubleMax) - -RETURNS - void - -SEE ALSO - pprAutoEnds, pprAutoInterval, pprAreaOpen - - -NAME pprCos_deg - get the cosine of an angle in degrees - -DESCRIPTION - Get the cosine of an angle in degrees. A table lookup technique - is used. The angle argument is truncated to the next lower 1/4 - degree prior to lookup. - -RETURNS - cosine - -SYNOPSIS - -double -pprCos_deg(angle) -double angle; /* I angle, in degrees */ - -NAME pprChar - plot a character - -DESCRIPTION - Plots a single text character at a location. The center of the - character is placed at the specified x,y position. - - The character height specification is in terms of a fraction of the - height of the window. This results in automatic scaling of - character sizes as the window size changes. If a height of zero - is specified in the call, then the default height for the plot - area is used. (The default height was established by pprAreaOpen.) - - A macro is available which returns the default character height - used by this plot package. The value returned is proportional to - the height of the plot area. This value can be used to generate - "big" and "small" character sizes. - - PprDfltCharHt(lowYfrac, highYfrac) - - lowYfrac is the vertical fraction of the window at which - the bottom edge of the plot area lies - highYfrac is the vertical fraction of the window at which - the top edge of the plot area lies - -RETURNS - void - -BUGS -o technique used works only with linear axes -o ASCII character codes are assumed -o no checks are made for illegal characters - -SEE ALSO - pprText, pprAreaOpen, pprLine, pprPoint - -SYNOPSIS - -void -pprChar(pArea, x, y, chr, height, angle) -PPR_AREA *pArea; /* IO pointer to plot area structure */ -double x; /* I x data coordinate of character */ -double y; /* I y data coordinate of character */ -char chr; /* I character to plot */ -double height; /* I height of character, as a fraction of - the height of the window; a value of - zero results in using a default height */ -double angle; /* I orientation angle of character, ccw degrees */ - -NAME pprCvtDblToTxt - format a double for printing - -DESCRIPTION - Formats a double for printing. This routine is dedicated to - getting as large a range of values as possible into a particular - field width. - - This routine doesn't attempt to handle extremely small values. - It assumes that the field is large enough to handle the smallest - significant value to be encountered. - -RETURNS - void - -BUGS -o extremely small values aren't handled well - -NOTES -1. If the value can't be represented at all in the field, the sign - followed by *'s appears. -2. In extreme cases, only the magnitude of the value will appear, as - En or Enn. For negative values, a - will precede the E. -3. When appropriate, the value is rounded to the nearest integer - for formatting. - -SYNOPSIS - -void -pprCvtDblToTxt(text, width, value, sigDig) -char *text; /* O text representation of value */ -int width; /* I max width of text string (not counting '\0') */ -double value; /* I value to print */ -int sigDig; /* I max # of dec places to print */ - -NAME pprGrid - draw a grid - -DESCRIPTION - Draw a perimeter and grid lines. The number of intervals - specified in the plot area structure is used for placing - the grid lines. - - The color attributes for the plot window are used for drawing; - dashed line and line thickness are ignored. - -RETURNS - void - -BUGS -o only linear axes are handled - -SEE ALSO - pprGridLabel, pprGridErase, pprPerim, pprAnnotX, pprAnnotY, pprAreaOpen - -SYNOPSIS - -void -pprGrid(pArea) -PPR_AREA *pArea; /* IO pointer to plotter area */ - -NAME pprGridErase - erase within a grid - -DESCRIPTION - Erases the screen inside the grid for the plot area. (Actually, - the entire data area is erased and then the grid is redrawn.) - -RETURNS - void - -SEE ALSO - pprPerimErase, pprAreaErase, pprWinErase - -SYNOPSIS - -void -pprGridErase(pArea) -PPR_AREA *pArea; /* IO pointer to plotter area */ - -NAME pprGridLabel - draw and label a grid - -DESCRIPTION - Draw a perimeter and grid lines. The number of intervals - specified in the plot area structure is used for placing - the grid lines. - - Axis labels and annotations are drawn using the information from - the plot area, as specified in the pprAreaOpen call. - -RETURNS - void - -BUGS -o only linear axes are handled - -SEE ALSO - pprGrid, pprPerim, pprAnnotX, pprAnnotY, pprAreaOpen - -SYNOPSIS - -void -pprGridLabel(pArea, xLabel, xAnnot, yLabel, yAnnot, angle) -PPR_AREA *pArea; /* IO pointer to plotter area */ -char *xLabel; /* I label for x axis, or NULL */ -char **xAnnot; /* I pointer to array of x annotations, or NULL */ -char *yLabel; /* I label for y axis, or NULL */ -char **yAnnot; /* I pointer to array of y annotations, or NULL */ -double angle; /* I angle for y annotations; 0. or 90. */ - -NAME pprLine - plot a line using x and y data value vectors - -DESCRIPTION - Draw a line along the path specified by two value arrays. - - Several entry points are available to accomodate various - types of data: - - pprLineF(pArea, x, y, npts) x and y are float[] - pprLineD(pArea, x, y, npts) x and y are double[] - pprLineS(pArea, x, y, npts) x and y are short[] - pprLineL(pArea, x, y, npts) x and y are long[] - -RETURNS - void - -BUGS -o only linear calibration is handled - -SEE ALSO - pprLineSeg, pprMove, pprPoint, pprText - -SYNOPSIS - -void -pprLineF(pArea, x, y, npts) -PPR_AREA *pArea; /* IO pointer to plot area structure */ -float *x; /* I x array of data values */ -float *y; /* I y array of data values */ -int npts; /* I number of points to plot */ - -NAME pprLineSeg - plot a line segment between a pair of points - -DESCRIPTION - Move to the first point and then draw a line to the second, using - the line attributes of the plot area. If the attributes indicate a - dashed line, the current dashed line pattern will be used. - - Two entry points are available: - - pprLineSegD(pArea, x1, y1, x2, y2) x and y are double - pprLineSegL(pArea, x1, y1, x2, y2) x and y are long - - For drawing ignoring the dashed line, line thickness, and other plot - area attributes, but using the area color attribute, two alternate - entry points are available: - - pprLineSegD_ac(pArea, x1, y1, x2, y2) x and y are double - pprLineSegL_ac(pArea, x1, y1, x2, y2) x and y are long - -RETURNS - void - -BUGS -o only linear calibration is handled - -SEE ALSO - pprLine, pprMove, pprPoint, pprText - -SYNOPSIS - -void -pprLineSegD(pArea, x1, y1, x2, y2) -PPR_AREA *pArea; /* IO pointer to plot area structure */ -double x1; /* I first x point */ -double y1; /* I first y point */ -double x2; /* I second x point */ -double y2; /* I second y point */ - -NAME pprMarkD - draw a plotting mark - -DESCRIPTION - Draw a plotting mark at the specified point. The color attribute - (if any) of the plot area is used in drawing the mark. Line - thickness and dashed line pattern attributes are ignored. - - Two entry points are available: - - pprMarkD(pArea, x, y, markNum) x and y are double - pprMarkL(pArea, x, y, markNum) x and y are long - -RETURNS - void - -BUGS -o only linear calibration is handled - -SEE ALSO - pprLine, pprLineSeg, pprPoint, pprText - -SYNOPSIS - -void -pprMarkD(pArea, x, y, markNum) -PPR_AREA *pArea; /* I pointer to plot area structure */ -double x; /* I x data coordinate */ -double y; /* I y data coordinate */ -int markNum; /* I mark number--0 to PPR_NMARKS-1, inclusive */ - -NAME pprMoveD - move the pen, possibly drawing a line - -DESCRIPTION - Move the "pen" to the specified point. If the "pen" is "down" - a line will be drawn. The line attributes of the plot area are - used in drawing the line. If the attributes indicate a dashed - line, the current dashed line pattern will be used. - - The "clipping" attribute for the plot area is honored only by - pprMoveD; pprMoveD_ac and pprMoveD_wc never clip lines at the - data area edges. - - Two alternate entry points are available for drawing plain lines, - ignoring all attributes except color. One uses the color for the - plot area (pprMoveD_ac); the other uses the plot window color - (pprMoveD_wc). - - pprMoveD_ac(pArea, x, y, pen) x and y are double - pprMoveD_wc(pArea, x, y, pen) x and y are double - -RETURNS - void - -BUGS -o only linear calibration is handled - -SEE ALSO - pprLine, pprLineSeg, pprText - -SYNOPSIS - -void -pprMoveD(pArea, x, y, pen) -PPR_AREA *pArea; /* IO pointer to plot area structure */ -double x; /* I x data coordinate of new point */ -double y; /* I y data coordinate of new point */ -int pen; /* I pen indicator--non-zero draws a line */ - -NAME pprPerim - draw a perimeter - -DESCRIPTION - Draw a perimeter with tick marks. The number of intervals - specified in the plot area structure is used for placing - the tick marks. - - The color attributes for the plot window are used for drawing; - dashed line and line thickness are ignored. - -RETURNS - void - -BUGS -o only linear axes are handled - -SEE ALSO - pprPerimLabel, pprPerimErase, pprGrid, pprAnnotX, pprAnnotY, pprAreaOpen - -SYNOPSIS - -void -pprPerim(pArea) -PPR_AREA *pArea; /* IO pointer to plotter area */ - -NAME pprPerimErase - erase within a perimeter - -DESCRIPTION - Erases the screen inside the perimeter for the plot area. (Actually, - the perimeter and tick marks are erased as well, since plot marks - may have been drawn on (and thus lie partly outside of) the perimeter - itself. The perimeter and tick marks are then redrawn.) - -RETURNS - void - -SEE ALSO - pprGridErase, pprAreaErase, pprWinErase - -SYNOPSIS - -void -pprPerimErase(pArea) -PPR_AREA *pArea; /* IO pointer to plotter area */ - -NAME pprPerimLabel - draw and label a perimeter - -DESCRIPTION - Draw a perimeter with tick marks. The number of intervals - specified in the plot area structure is used for placing - the tick marks. - - Axis labels and annotations are drawn using the information from - the plot area, as specified in the pprAreaOpen call. - -RETURNS - void - -BUGS -o only linear axes are handled - -SEE ALSO - pprPerim, pprGrid, pprAnnotX, pprAnnotY, pprAreaOpen - -SYNOPSIS - -void -pprPerimLabel(pArea, xLabel, xAnnot, yLabel, yAnnot, angle) -PPR_AREA *pArea; /* IO pointer to plotter area */ -char *xLabel; /* I label for x axis, or NULL */ -char **xAnnot; /* I pointer to array of x annotations, or NULL */ -char *yLabel; /* I label for y axis, or NULL */ -char **yAnnot; /* I pointer to array of y annotations, or NULL */ -double angle; /* I angle for y annotations; 0. or 90. */ - -NAME pprPoint - plot a point at a coordinate - -DESCRIPTION - Plot a pixel sized point using the line thickness and color - attributes of the plot area. - - Two entry points are available: - - pprPointD(pArea, x, y) x and y are double - pprPointL(pArea, x, y) x and y are long - -RETURNS - void - -BUGS -o only linear calibration is handled - -SEE ALSO - pprMark, pprAreaOpen, pprAreaSetAttr, pprLine, pprMove, pprText - -SYNOPSIS - -void -pprPointD(pArea, x, y) -PPR_AREA *pArea; /* IO pointer to plot area structure */ -double x; /* I x data coordinate */ -double y; /* I y data coordinate */ - -NAME pprSin_deg - get the sine of an angle in degrees - -DESCRIPTION - Get the sine of an angle in degrees. A table lookup technique - is used. The angle argument is truncated to the next lower 1/4 - degree prior to lookup. - -RETURNS - sine - -SYNOPSIS - -double -pprSin_deg(angle) -double angle; /* I angle, in degrees */ - -NAME pprText - plot a text string - -DESCRIPTION - Plots a text string at a location. The character "half height" is - placed at the specified x,y position; the 'justification' option - selects whether the left end, center, or right end of the text is - placed at the x,y coordinate. - - The character height specification is in terms of a fraction of the - height of the window. This results in automatic scaling of - character sizes as the window size changes. If a height of zero - is specified in the call, then the default height for the plot - area is used. (The default height was established by pprAreaOpen.) - - A macro is available which returns the default character height - used by this plot package. The value returned is proportional to - the height of the plot area. This value can be used to generate - "big" and "small" character sizes with simple multiplication of - the default height by a "scale factor". - - PprDfltCharHt(lowYfrac, highYfrac) - - lowYfrac is the vertical fraction of the window at which - the bottom edge of the plot area lies - highYfrac is the vertical fraction of the window at which - the top edge of the plot area lies - - It is also often useful to know what horizontal fraction of the - window width corresponds to a vertical fraction of the height. The - following routine returns the horizontal fraction: - - pprYFracToXFrac(pWin, yFrac) - - An alternate entry point, pprText_wc, is available to use the - plot window's color for drawing the text. - -RETURNS - void - -BUGS -o technique used works only with linear axes -o ASCII character codes are assumed -o no checks are made for illegal characters -o positioning and sizing are somewhat different for the various - window types - -SEE ALSO - pprChar, pprAreaOpen, pprLine, pprPoint, pprCvtDblToTxt - -SYNOPSIS - -void -pprText(pArea, x, y, text, just, height, angle) -PPR_AREA *pArea; /* IO pointer to plot area structure */ -double x; /* I x data coordinate of text */ -double y; /* I y data coordinate of text */ -char *text; /* I text to plot */ -PPR_TXT_JUST just; /* I text justification selector: one of - PPR_TXT_CEN, PPR_TXT_RJ, or PPR_TXT_LJ */ -double height; /* I height of text characters, as a fraction of - the height of the window; a value of - zero results in using a default height */ -double angle; /* I orientation angle of text string, ccw degrees */ - -NAME pprWinClose - close a plot window - -DESCRIPTION - Free the memory associated with a plot window structure and do other - cleanup activities. - - This routine should be called when plotting is complete for a plot - window. Any plot areas not previously closed are automatically - closed by this routine. - - No further references to the plot window may be made. - -RETURNS - void - -SEE ALSO - pprAreaClose, pprWinInfo, pprWinOpen - -SYNOPSIS - -void -pprWinClose(pWin) -PPR_WIN *pWin; /* IO pointer to plot window structure */ - -NAME pprWinErase - erase a plot window - -DESCRIPTION - Erase the contents of the entire plot window. - -RETURNS - void - -SEE ALSO - pprGridErase, pprPerimErase, pprAreaErase - -SYNOPSIS - -void -pprWinErase(pWin) -PPR_WIN *pWin; /* IO pointer to plot window structure */ - -NAME pprWinInfo - get some information about the plot window - -DESCRIPTION - Get the size of the plot window and its position on the screen. - -RETURNS - void - -NOTES -1. The information returned is window system dependent. To avoid - portability problems, this information should be used only in - calls to pprWinXxx routines. - -SYNOPSIS - -void -pprWinInfo(pWin, pXpos, pYpos, pXwid, pYht) -PPR_WIN *pWin; /* I pointer to plot window structure */ -int *pXpos; /* O pointer to place to store window x coord., in pixels */ -int *pYpos; /* O pointer to place to store window y coord., in pixels */ -int *pXwid; /* O pointer to place to store window width, in pixels */ -int *pYht; /* O pointer to place to store window height, in pixels */ - -NAME pprWinIsMono - test to see if plot window is monochrome - -DESCRIPTION - -RETURNS - 1 if plot window is monochrome or gray scale - 0 if plot window is color - -SYNOPSIS - -int -pprWinIsMono(pWin) -PPR_WIN *pWin; /* I pointer to plot window structure */ - -NAME pprWinLoop - loop until "quit" event received in window - -DESCRIPTION - Handles the interactions with the windowing system. The specific - actions depend on the plot window type: - - PPR_WIN_SCREEN - o creates a window on the screen - o when the window actually appears, calls the caller's draw function - o for all subsequent resize and expose events, calls the caller's - draw function - o when the right mouse button is clicked, closes the window and - returns to the caller. The current position and size of the - window are stored (and can be retrieved with pprWinInfo). - - PPR_WIN_POSTSCRIPT - o calls the caller's draw function - - PPR_WIN_EPS - o calls the caller's draw function - - The idea when using pprWinLoop is that a program - will do some preliminary setup for the data to be plotted. - Then the program must turn control over to the plot "window - manager" using pprWinLoop, which will call the caller's - actual plot routine. - - When pprWinLoop exits back to the calling program, that program - can call pprWinInfo in order to "remember" the plot window - size and position. - -RETURNS - 0, or - -1 if an error is encountered - -BUGS -o doesn't furnish information to the draw function which would allow - a partial redraw -o terminology is confusing and inconsistent: "draw" function, redraw, - replot, repaint, etc. - -SEE ALSO - pprWinOpen, pprWinInfo - -NOTES -1. Even though there aren't any "events" associated with plotting on - a PostScript printer, this routine must be called even when using - PPR_WIN_POSTSCRIPT and PPR_WIN_EPS, since this routine invokes the - caller's "draw" function. - -EXAMPLE - See pprWinOpen for an example of a replot function. -j - -SYNOPSIS - -long -pprWinLoop(pWin, drawFun, pDrawArg) -PPR_WIN *pWin; /* IO pointer to plot window structure */ -void (*drawFun)();/* I pointer to function to draw the plot */ -void *pDrawArg;/* I pointer to pass to drawFun */ - -NAME pprWinOpen - initialize a plotting "window" structure - -DESCRIPTION - Initialize a plot window structure. This is the structure which - keeps track of the information needed to interact with the - device on which the "window" resides. The possible types of - windows are: - - o PPR_WIN_SCREEN selects a window on a visual display. This - will be a SunView or X window, depending on the version of - the plotting used in linking the program. The pprWinOpen - call actually creates a window, with the root window as the - parent. The window thus created can be moved, resized, etc. - according to the capabilities of the window manager of the - windowing system being used. (To initialize a plotting - window structure in a window which already exists, use - pprWinOpenUW.) - - for SunView, - `winDispName' is ignored and should be NULL - `winTitle' appears on the window's title bar and icon - `xPos' and `yPos' are pixel offsets from the upper left - corner of the root window. If values of 0 are - supplied, then the window will be positioned at - 100,100. - `xWid' and `yHt' are the width and height of the window, - in pixels. If values of 0 are supplied, then - a size of 512,512 will be used. - - for X, - `winDispName' specifies the X display name on which the - plot window is to appear. If NULL, then the - DISPLAY environment variable will be used. - `winTitle' appears on the window's title bar and icon - `xPos' and `yPos' are pixel offsets from the upper left - corner of the root window. If values of 0 are - supplied, then the window will be positioned at - 100,100. - `xWid' and `yHt' are the width and height of the window, - in pixels. If values of 0 are supplied, then - a size of 512,512 will be used. - - o PPR_WIN_POSTSCRIPT selects a "window" on a PostScript - printer. - - `winDispName' is the name of a file to receive PostScript - output. This is the file which will eventually - be sent to a PostScript printer to get a hard - copy of the plot. If the file exists when - pprWinOpen is called, its contents are erased - before writing begins. - `winTitle' is ignored and should be NULL - `xPos' and `yPos' are ignored - `xWid' and `yHt' are the width and height of the window, - in pixels. If values of 0 are supplied, then - a size of 512,512 will be used. If the size is - larger than the page, then the plot will be scaled - to fit. If necessary, the plot will be printed in - landscape mode, rather than the default of portrait - mode. - - o PPR_WIN_EPS selects a "window" in an Encapsulated PostScript - file. EPS files are intended to be included into documents - prepared by word processing programs such as Interleaf and - TeX. EPS files will not print directly on a PostScript printer. - The description of the arguments for PPR_WIN_POSTSCRIPT applies, - except that scaling and rotation aren't done. - - The pprXxx routines can be used for several different styles of - usage: - - o a complete set of data is available prior to calling any of - the plotting routines. In this case, grids can be drawn and - data can be plotted at the same time. - - For this style of usage, the typical usage will be: - pprWinOpen to "open" a plot window - pprWinLoop to map the plot window to the screen - and call the caller's replot function - when the window is exposed, resized, - etc. - pprWinClose to "close" a plot window - - o no data (or only part of the data) is available prior to calling - any of the plotting routines. In this case, at least some of - the data must be plotted at a later time than when the grids - are drawn. The pprXxx routines don't automatically support - this style of usage fully, but they do provide some tools which - make it relatively easy to implement. See pprWinOpenUW for - more details. - - Under all circumstances, the calling program is expected to call - pprWinClose when plotting is complete for the plot window. - -RETURNS - pointer to window structure, or - NULL if an error is encountered - -SEE ALSO - pprWinOpenUW, pprWinClose, pprWinInfo, pprWinLoop - -EXAMPLES -1. Plot an existing set of data, where the data is stored in `dataStruct'. - - PPR_WIN *pWindow; - . - pWindow = pprWinOpen(PPR_WIN_SCREEN, NULL, "test", 0, 0, 0, 0); - if (pWindow == NULL) - abort(); - if (pprWinLoop(pWindow, replot, &dataStruct) != 0) - abort(); - pprWinClose(pWindow); - -SYNOPSIS - -PPR_WIN * -pprWinOpen(winType, winDispName, winTitle, xPos, yPos, xWid, yHt) -PPR_WIN_TY winType; /* I type of plot window: PPR_WIN_xxx */ -char *winDispName; /* I name of "display" or file for window */ -char *winTitle; /* I title for window title bar and icon */ -int xPos; /* I x position for window; 0 for default */ -int yPos; /* I y position for window; 0 for default */ -int xWid; /* I width of window; 0 for default */ -int yHt; /* I height of window; 0 for default */ - -NAME pprWinOpenUW - open a plot "window" to an existing User Window - -DESCRIPTION - Initialize a plot window structure. This is the structure which - keeps track of the information needed to interact with the - device on which the "window" resides. - - This routine is for use when the caller already has a window in - the windowing system. It is for use exclusively for PPR_WIN_SCREEN - plot window type. The form of the call to this routine is heavily - dependent on the windowing system being used. This routine provides - the basis for obtaining `asynchronous' plotting. (It can also be - used for `batched' plotting, in which all data is available prior - to the first plotting call.) - - Under all circumstances, the calling program is expected to call - pprWinClose when plotting is complete for the plot window. - -RETURNS - pointer to window structure, or - NULL if an error is encountered - -SEE ALSO - pprWinOpenUW, pprWinClose, pprWinInfo, pprWinLoop - -EXAMPLES -1. for X - - PPR_WIN *pWin; - Display *pDisp; - Window plotWindow; - GC plotGC; - - pWin = pprWinOpenUW(&pDisp, &plotWindow, &plotGC, NULL); - ... - pprWinReplot(pWin, drawFn, drawArg); - ... - pprWinClose(pWin); - - -2. for SunView - - PPR_WIN *pWin; - Frame plotFrame; - Canvas plotCanvas; - - pWin = pprWinOpenUW(&plotFrame, &plotCanvas, NULL, NULL); - ... - pprWinReplot(pWin, drawFn, drawArg); - ... - pprWinClose(pWin); - -3. for XView - - PPR_WIN *pWin; - Display *pDisp; - Window plotWindow; - GC plotGC; - - pDisp = (Display *)xv_get(frame, XV_DISPLAY); - window = (Window)xv_get(canvas_paint_window(canvas), XV_XID); - plotGC = DefaultGC(pDisp, DefaultScreen(pDisp)); - - pWin = pprWinOpenUW(&pDisp, &plotWindow, &plotGC, NULL); - ... - pprWinReplot(pWin, drawFn, drawArg); - ... - pprWinClose(pWin); - -SYNOPSIS - -PPR_WIN * -pprWinOpenUW(pArg1, pArg2, pArg3, pArg4) -void *pArg1; -void *pArg2; -void *pArg3; -void *pArg4; - -NAME pprWinReplot - redraw a plot in a user owned window - -DESCRIPTION - Calls the "replot" function to repaint the plot window. This - routine is intended to be used with "user owned" plot windows - which have been opened with pprWinOpenUW. - - Prior to calling the replot function, this routine determines - the size of the actual window and rescales the existing plot - areas. - -RETURNS - void - -SEE ALSO - pprWinOpenUW - -SYNOPSIS - -void -pprWinReplot(pWin, pFunc, pArg) -PPR_WIN *pWin; -void (*pFunc)(); -void *pArg; - -NAME pprYFracToXFrac - convert a Y fraction to an X fraction - -DESCRIPTION - Converts a value which is a fraction of window height into a value - which is a fraction of window width, so that the two values will - represent the same physical size, in pixels. - - This routine is useful for laying out a plot area, especially when - a grid with annotations and labels is to be used. The choice of - "data area" size (i.e., the size of the grid) depends on the size - of the characters which will be used for the annotations and - labels. - -RETURNS - void - -SEE ALSO - pprText - -EXAMPLE - A plot area is use the full width and the vertical 1/3 of the window. - x values range from 0 to 100, while y is from -10 to 10. The x - axis is to be divided into 10 divisions, the y into 4. Use - the default character size for annotations and labels. Also, - use the default window position and size. - - PPR_WIN *pWin; - PPR_AREA *pArea; - float charHt; height as a fraction of window height - float charWid; width as a fraction of window width - - charHt = PprDfltCharHt(.33, .67); - charWid = pprYFracToXFrac(pWin, charHt); - pArea = pprAreaOpen(pWin, 12.*charWid, .33+6.*charHt, 1., .67, - 0., -10., 100., 10, 4, charHt); - -SYNOPSIS - -double -pprYFracToXFrac(pWin, yFrac) -PPR_WIN *pWin; /* I pointer to plot window structure */ -double yFrac; /* I fraction of window height */ diff --git a/src/util/racPrint.c b/src/util/racPrint.c deleted file mode 100644 index e25d4bf95..000000000 --- a/src/util/racPrint.c +++ /dev/null @@ -1,714 +0,0 @@ -/* epics/share/src/util $Id$ - * Author: Roger A. Cole - * Date: mm-dd-yy - * - * 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: - * ----------------- - * 1.1 07/12/89 rac initial version - * 1.2 09/15/89 rac allow multiple input files; change - * the calling sequence so -o specifies - * output file; print non-printing chars - * as . - * 1.3 11/02/89 rac change printing of <; allow default - * input from stdin. If first line on page - * is FF, don't print empty page. - * 1.4 11/03/89 rac fix bug in input from stdin. - * 1.5 12/04/89 rac handle long lines without truncation - * 1.6 02/11/90 rac handle module name and subr name in heading; - * put page number in footing. - * 1.7 skipped - * 1.8 08/31/90 rac handle /subhead text--- divider lines - * 1.9 09/17/90 rac fix long line bug; allow more pages - * 1.10 07-28-91 rac installed in EPICS - * 1.11 07-28-91 rac add -w option for page width - * - */ -/*+/mod*********************************************************************** -* TITLE racPrint - filter for printing -* -* SYNOPSIS -* racPrint [-l lm] [-o output] [-t tab] [-P point] [-w width] input ... -* -* lm is the number of columns for left margin; default 0. -* tab is the tab width, in columns; default 8. -* input is an ascii file; several may be specified; if none -* is specified, stdin is used. -* output is an ascii file containing the input file broken -* into pages, with pages in reverse order; -* default is stdout. -* point is a point size for PostScript printers -* width is page width, in characters -* -* DESCRIPTION -* The input file is broken into pages and written in reverse page -* order to the output file. The following processing is done: -* o a 3 line heading is written, containing time and date, file -* path, file name, modification date, and subroutien name is -* printed -* o a 3 line footing containing file number and page number is -* printed -* o a left margin of 8 columns is added, plus an additional 7 -* columns for line numbering. (If -l is specified, it -* controls the left margin.) -* o tabs are expanded -* o form-feed characters are honored -* o long lines are folded -* o non-printing characters are printed as , where -* code is the hexadecimal code for the character. Where -* a < occurs, it is printed as a <; hopefully, the context -* will avoid confusion with . -* EXAMPLE -* % racPrint source.c | lpr -* -* BUGS -* o should guard against printing binary files -* o files which exactly fill the last page result in an extra, blank -* page being printed. -* o Doesn't print info following ^L if doesn't follow ^L -* -*-*/ -/*----------------------------------------------------------------------------- -* APOLOGY: I offer my humble apologies to whomever comes across this code-- -* it was my first program in C, and it shows it. R. Cole -*----------------------------------------------------------------------------*/ - -/* WISH LIST: -* - generate a 'table of contents' from names from divider lines -* - generate table of contents for file names and extractable entities -* - add a -help switch -* - handle the backspace character -* - handle "pre-formatted" files, such as man pages output -* - handle extremely long path names, or at least check for overflow -* - allow a `-H heading' option to provide a meaningful heading when -* input is from stdin -*/ - -#include -#include -#include -#include -#include - -#define MAXCHAR 95 /* max characters per line */ -#define MAXLINE 66 /* max lines per page */ -#define MAXPAGE 500 /* max pages at a time */ -#define MAXTOC 10 /* max table of contents pages */ -#define lineBufDim 10000 /* dimension for input line and ovf buffers */ - -#define STRCAT_CHK(str,sub_str) strcat_chk(str,sizeof str,sub_str) - -typedef struct -{ int page_no; /* page number */ - int nlines; /* number of lines on this page */ - char lines[MAXLINE][MAXCHAR+1]; /* lines of the page */ -} PAGE; - - -struct FILE_INF -{ FILE *ptr; /* file pointer from 'fopen' */ - char path[80]; /* pathname to file */ - char date_mod[30]; /* time and date last modified */ - short line_no; /* line number in file */ - char name[20]; /* file name */ - char subr[30]; /* subroutine name from subr heading */ - int fd; /* file descriptor for use in 'stat' call */ -}; - -char date[40]; /* date and time */ -char header[80]; /* heading line */ -int page_no; /* number of current page within file */ -int file_no = 0; /* file number being processed */ -int npages = 0; /* number of pages */ -PAGE pages[MAXPAGE]; /* pages from file */ -int pages_sub = 0; /* subscript into pages structure */ -PAGE toc[MAXTOC]; /* table of contents */ -int toc_sub = 0; /* subscript into toc structure */ - -int left_margin = 0; /* width of left margin in output */ -int line_numbering = 1; /* flag to number lines in output */ -int page_width = 80; /* page width, in characters */ -int point_size = 0; /* PostScript point size if non-zero */ -int tab_width = 8; /* columns per 'tab stop' */ -char overflow[lineBufDim]; /* overflow record buffer */ -int overflow_flag = 0; /* overflow record buffer in use */ - - -/*+***************************************************************** -* NAME main - racPrint main program -* -*-*/ -main(argc, argv) - int argc; /* number of command line args */ - char *argv[]; /* command line args */ -{ - void get_time_and_date(); /* get time and date string */ - int i; /* temp for loops */ - struct FILE_INF in_file; /* input file */ - struct FILE_INF out_file; /* output file */ - - char line[MAXCHAR+1]; /* line of file */ - int get_next_page(); /* get a page from the file */ - - get_time_and_date(date); - -/* ------------------------------------------------------------- -* get the option arguments from the command line -* -------------------------------------------------------------*/ - - get_option_args(argc, argv, &out_file); - -/* ------------------------------------------------------------- -* get the input file names from the command line, processing each -* in turn. -* -------------------------------------------------------------*/ - - while (get_input_file(argc, argv, &in_file) != NULL) { - -/* ------------------------------------------------------------- -* Read pages from input file. If 'buffer' becomes full, print -* the accumulated pages in reverse order. -* -------------------------------------------------------------*/ - - in_file.line_no = 0; - while (get_next_page(&in_file) != EOF) { - if (pages_sub == MAXPAGE) { /* dump and start fresh */ - for (i=pages_sub-1; i>=0; i--) - print_page(&out_file,i); - pages_sub = 0; - } - } - if (in_file.ptr != stdin) /* don't close stdin */ - fclose(in_file.ptr); - } - - for (i=pages_sub-1; i>=0; i--) { - print_page(&out_file,i); - } - - print_banner_page(&in_file,&out_file); - -/* flush and close files */ - fflush(out_file.ptr); - fclose(out_file.ptr); - - exit(0); -} - -/*+/subr************************************************************ -* NAME print_banner_page - write a banner page to the output file -* -*-*/ -print_banner_page(p_in_file,p_out_file) - struct FILE_INF *p_in_file; /* pointer to input file */ - struct FILE_INF *p_out_file; /* pointer to output file */ -{ - char banner[80]; /* temp for banner line */ - char *env; /* pointer to string from getenv */ - char *getenv(); /* get environment variables */ - int i; /* temp for loops */ - - for (i=0; i<79; i++) - banner[i] = '/'; - banner[79] = '\0'; - - env = getenv("LOGNAME"); - - for (i=0; iptr, - "%s\n",banner); - else if (i==15) - fprintf(p_out_file->ptr, - "////////// For: %s\n",env); - else if (i==17) - fprintf(p_out_file->ptr, - "////////// Date: %s\n",date); - else - fprintf(p_out_file->ptr, - "////////// \n"); - - } - - return; -} - -/*+/subr************************************************************ -* NAME print_page - write a page to the output file -* -*-*/ -print_page(p_out_file,page_number) - struct FILE_INF *p_out_file; /* pointer to file */ - int page_number; /* page number to print 0-n */ -{ - int i; /* temp for loops */ - - for (i=0; iptr); - - return; -} - -/*+/subr************************************************************ -* NAME line_store - store a line into a page -* -* DESCRIPTION -* The record is stored into the line buffer, expanding tabs. -* -* If the record isn't an overflow record, left margin and -* record number are added to the line buffer. If the -* record is too long to fit in the line buffer, the overflow -* flag is set and the excess characters are copied into the -* overflow record. -* -* If the record is an overflow record, the left margin and -* padding for the record number field are added to the line -* buffer. If the record is too long to fit in the line buffer, -* the overflow flag and overflow record will be handled as above. -* -* RETURNS -* 0 if no form-feed encountered -* 1 if form-feed encountered and line printed -* 2 if form-feed encountered and no line printed -* -*-*/ -line_store (line, rec, line_no) - char line[]; /* line to receive record, with tabs - expanded and left margin set */ - char rec[]; /* record to store */ - int line_no; /* line number to attach; if zero, - no line number will appear. */ -{ - char c; /* temp for character */ - int ff=0; /* form feed encountered flag */ - char hex_code[3]; /* temp for hex code for char */ - int l_col=0; /* column index in line */ - int lmar; /* left margin to store actual record */ - int r_col=0; /* column index in record */ - -/* ------------------------------------------------------------- -* If the first thing on a line is a ^L (i.e., ff), then don't -* do anything; just exit with `ff' indicated. -* -------------------------------------------------------------*/ - if (rec[0] == '\f') { - ff = 2; - return ff; - } - - while (l_col < left_margin) - line[l_col++] = ' '; /* blank fill left margin */ - - if (!overflow_flag) { - if (line_no > 0) { /* 'print' the line number */ - sprintf (&line[l_col], "%.5d", line_no); - l_col += 5; - line[l_col++] = ' '; - line[l_col++] = ' '; - } - } - else { - sprintf(&line[l_col], " "); - l_col += 5; - line[l_col++] = ' '; - line[l_col++] = ' '; - } - -/* ------------------------------------------------------------- -* Move the record into the line buffer, expanding tabs. If record is -* too long, the overflow is invoked. Line buffer will always be -* terminated with \n\0. Non-printing characters will be shown as -* , where hh is the hex code for the character. Where < occurs -* in the text, it will be shown as itself. -* -------------------------------------------------------------*/ -#define store_c(c) \ -if (l_col < page_width-1)\ - line[l_col++] = c;\ -else\ - line[lmar-2] = '*'; - - overflow_flag = 0; /* reset overflow flag */ - lmar = l_col; /* save this to make tab expansion 'sane' */ - while ((c=rec[r_col++]) != NULL && !overflow_flag) { - if (l_col < page_width-2) { - switch (c) { - case '\t': - line[l_col++] = ' '; - while (l_col < page_width-1 && - ((l_col-lmar) % tab_width) != 0) - line[l_col++] = ' '; - break; - case '\f': - ff = 1; - break; - case '\n': - break; - case '<': - store_c(c); - break; - default: - if (isprint(c)) - line[l_col++] = c; - else { - store_c('<'); - sprintf(hex_code,"%02.2X",c); - store_c(hex_code[0]); - store_c(hex_code[1]); - store_c('>'); - } - break; - } - } - else { - r_col--; - strcpy(overflow, &rec[r_col]); - overflow_flag = 1; - } - } - - line[l_col++] = '\n'; - line[l_col++] = '\0'; - - return ff; -} - -/*+/subr************************************************************ -* NAME get_next_page - format the next page for printing -* -* DESCRIPTION -* -* RETURNS -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -int get_next_page(p_in_file) - struct FILE_INF *p_in_file; /* pointer to input file */ -{ - char buf_in[lineBufDim];/* input buffer */ - int buf_in_len; /* length of input line */ - int col = 0; /* temp for column in line */ - int eof = 0; /* end-of-file flag */ - int ff; /* form feed flag */ - int line = 0; /* temp for line in page */ - - - line = 3; - -/* ------------------------------------------------------------- -* read the lines from the file for one page, leaving room for 'footing' -* If the overflow flag is set, input line is taken from overflow -* buffer instead of file. -* -------------------------------------------------------------*/ - while (line < MAXLINE-3 && eof == 0) { - if (overflow_flag) { - strcpy(buf_in, overflow); - } - else if (fgets(buf_in, lineBufDim, p_in_file->ptr) != NULL ) { - p_in_file->line_no++; - } - else - eof = EOF; /* no more to read */ - - if (!eof) { - if (strncmp(buf_in, "* NAME", 6) == 0) { - sscanf(&buf_in[6], "%29s", p_in_file->subr); - } - else if (strncmp(buf_in, "/*/subhead ", 11) == 0) { - int i; - int c; - i = 0; - while (i< 29 && (c=buf_in[11+i])!='-') - p_in_file->subr[i++] = c; - p_in_file->subr[i] = '\0'; - - } - ff = line_store(pages[pages_sub].lines[line++], buf_in, - line_numbering ? p_in_file->line_no : 0); - if (ff == 2 && line == 4) { /* FF on first line of page */ - line--; /* throw away the FF; already new page */ - } - else if (ff) { /* if FF encountered, pad rest of page */ - if (ff == 2) /* if no line printed, reset line_no */ - line--; - while (line < MAXLINE-3) - pages[pages_sub].lines[line++][0] = '\n'; - } - } - } - -/*---------------------------------------------------------------------------- -* set up the footing -*---------------------------------------------------------------------------*/ - for(; linedate_mod[0] != '\0') ? "last modified:" : " ", - p_in_file->date_mod); - for (col=strlen(pages[pages_sub].lines[line]); - colname); col++) - pages[pages_sub].lines[line][col] = ' '; - sprintf(&(pages[pages_sub].lines[line][page_width-2-strlen(p_in_file->name)]), - "%s\n", p_in_file->name); - - line = 1; /* line 1 has path and subroutine name */ - col = 0; - while (colpath); - for (col=strlen(pages[pages_sub].lines[line]); - colsubr); col++) - pages[pages_sub].lines[line][col] = ' '; - sprintf(&(pages[pages_sub].lines[line][page_width-2-strlen(p_in_file->subr)]), - "%s\n", p_in_file->subr); - - line++; /* line 2 is blank */ - strcpy(pages[pages_sub].lines[line],"\n"); - - pages[pages_sub].page_no = ++npages; - pages_sub++; - page_no++; - - return eof; - -} - -/*+/subr************************************************************ -* NAME get_option_args - get option args from command line -* -* DESCRIPTION -* Gets the command line options, except for input file. If -* an error is encountered, exit(1) is done. -* -*-*/ -get_option_args(argc, argv, p_out_file) - int argc; /* number of command line args */ - char *argv[]; /* command line args */ - struct FILE_INF *p_out_file; /* pointer to output file */ -{ - int c; /* option letter */ - int errflg = 0; /* error flag for options */ - int i; /* temp for string length */ - extern char *optarg; /* argument for an option */ - extern int optind; /* index in argv of next option */ - -/* ------------------------------------------------------------- -* Get any options from the command line and process them. If the -* output file is specified, open it; abort if can't open it. -* -------------------------------------------------------------*/ - - p_out_file->ptr = stdout; /* default for output is stdout */ - while ((c = getopt (argc, argv, "l:t:o:P:w:")) != -1) { - switch(c) { - case'l': - left_margin = atoi(optarg); /* -l left_margin */ - case't': - tab_width = atoi(optarg); /* -t tab_width */ - break; - case'o': - if ((p_out_file->ptr = fopen (optarg, "w")) == NULL) { - fprintf(stderr, "racPrint: can't open %s\n", optarg); - exit(1); - } - break; - case'P': - point_size = atoi(optarg); /* -P PostScript point_size */ - break; - case'w': - page_width = atoi(optarg); /* -w page_width */ - if (page_width > MAXCHAR) - page_width = MAXCHAR; - break; - case'?': - errflg++; - } - } - - if (errflg) - usage(); - - return; -} -usage() -{ - fprintf(stderr, - "Usage: racPrint [-l l_mar] [-t tabwid] [-o out_file]\ - [-w width] [-P point] input_file\n"); - exit(2); -} - -/*+/subr************************************************************ -* NAME get_input_file - get next input file from command line -* -* DESCRIPTION -* Gets the next input file argument from the command line. If -* an error is encountered, exit(1) is done. -* -* RETURNS -* 0 if no input file arg found -* 1 if there is an input file -* -*-*/ -get_input_file(argc, argv, p_in_file) - int argc; /* number of command line args */ - char *argv[]; /* command line args */ - struct FILE_INF *p_in_file; /* pointer to input file */ -{ - char *ctime(); /* convert 'time_t' to 'ascii' */ - char *getenv(); /* get environment variable value */ - int i; /* temp for string length */ - extern char *optarg; /* argument for an option */ - extern int optind; /* index in argv of next option */ - struct stat p_fstat; /* pointer to status buffer */ - char *p_ftime; /* pointer to date and time of last mod */ - -/* ------------------------------------------------------------- -* Set up pointers and do the opens for the next input file. -* The file descriptor for the file is also captured and stored. -* -------------------------------------------------------------*/ - - if (optind>=argc && file_no==0) { - p_in_file->ptr = stdin; - strcpy(p_in_file->name, "stdin"); - strcpy(p_in_file->path, " "); - p_in_file->date_mod[0] = '\0'; - - page_no=1; - file_no++; - strcpy(p_in_file->subr, " "); - return(1); - } - else if (optindptr = fopen(argv[optind], "r")) == NULL) { - fprintf(stderr, "racPrint: can't open %s\n", argv[optind]); - exit(1); - } - strcpy(p_in_file->name,argv[optind]); - strcpy(p_in_file->path,getenv("PWD")); /* get working directory */ - STRCAT_CHK(p_in_file->path,"/"); /* append /filename to it */ - STRCAT_CHK(p_in_file->path,p_in_file->name); - p_in_file->fd = fileno(p_in_file->ptr); /* get file descriptor */ - i = fstat(p_in_file->fd,&p_fstat); /* get file stat info */ - p_ftime = ctime(&p_fstat.st_mtime); /* convert to ascii \n\0 */ - p_ftime[strlen(p_ftime)-1] = '\0'; /* remove the \n */ - strcpy(p_in_file->date_mod,p_ftime); /* date last modified */ - - optind++; - - page_no=1; - file_no++; - strcpy(p_in_file->subr, " "); - return(1); - } - else - return(0); -} - -/*+/subr************************************************************ -* NAME strcat_chk - concatenate strings, checking bounds -* -* DESCRIPTION -* The sub_string is concatenated to the end of string. If -* string isn't large enough, only the part of sub_string which -* will fit is concatenated. Strings are \0 terminated. -* -*-*/ -strcat_chk (string, size_of_string, sub_string) - char string[]; /* 'master' string */ - int size_of_string; /* declared length of string */ - char sub_string[]; /* substring to concatenate */ -{ - int i; - - i = 0; - while (string[i] && i, , etc.) are mixed -* in with output. (This is really a CA bug, since they can't be -* suppressed and they go to stdout.) -* o doesn't handle state records, enum fields, etc., gracefully -* o doesn't handle array fields well -* -*-***************************************************************************/ -#include -#include -#include -#include -#include -#include -#if 0 -#include "iocmsg.h" -#include "iocinf.h" -extern struct ca_static *ca_static; -#define iiu (ca_static->ca_iiu) - if (i == 0 && pCh != NULL && dbf_type_is_valid(ca_field_type(pCh))) { - char *x; - x = host_from_addr(&iiu[pCh->iocix].sock_addr.sin_addr); - x = host_from_addr(&iiu[0].sock_addr.sin_addr); - strncpy(info[i].hostName, - host_from_addr(&iiu[pCh->iocix].sock_addr.sin_addr), 8); - printf("\n%s\n", info[i].hostName); - } -#endif - - -/* nint, exp10 aren't ANSI-C or POSIX */ -# ifndef sun -# ifndef nint -# define nint(value) (value>=0 ? (int)((value)+.5) : (int)((value)-.5)) -# endif -# ifndef exp10 -# define exp10(value) (exp(value * log(10.))) -# endif -# endif - - -#define FLD_DIM 20 -static int nFld; -static char *(fields[FLD_DIM]); -static chtype types[FLD_DIM]; -static int notInDct[FLD_DIM]; -static int notInField[FLD_DIM]; - -static char dctValues[FLD_DIM][100]; /* values for the fields above */ -static char dctName[100]; -static char dctType[100]; -static char dctNode[100]; - -#define DCT_DIM 200 -static struct { - char fldName[db_name_dim]; /* actual fields in the records */ - char fldVal[100]; -} dctFields[DCT_DIM]; - -static int nDctFields; /* number of fields for record just read */ - - -typedef struct { - int inIOC; - int inDCT; - chid pCh; - char name[db_name_dim]; - char val[db_strval_dim]; - short shtval; - float fltval; - chtype type; -} CHAN; - -typedef struct rec { - char name[db_name_dim]; /* gotten from user; may have .FLD */ - char recName[db_name_dim]; /* stripped of .FLD */ - char recType[db_name_dim]; /* type of record */ - int aField; /* 1 if name had a .FLD */ - char fldName[db_name_dim]; /* actual field name if `aField' */ - char filled; - char hostName[8]; - int found; /* 1 if record has been found */ - int hasWild; /* 1 if name has wildcard char's */ - struct rec *pHead; - struct rec *pTail; - struct rec *pNext; - struct rec *pPrev; - CHAN info[FLD_DIM]; -} REC; - -#define REC_DIM 200 -static REC records[REC_DIM];/* records to be found */ -static int nRec=0; /* number of records to be found */ -static int allFound; /* all requested records have been found */ - - -/*+/subr********************************************************************** -* NAME main -* -*-*/ -main(argc, argv) -int argc; /* number of command line args */ -char *argv[]; /* command line args */ -{ - FILE *pInFile, *pOutFile, *pDctFile; - char filled; - char rec[db_name_dim]; - int c, i, argPtr; - int header=1; - int cmdLineMode=1; - int dctFlag=0; - - nFld = 0; - initFields(); - pInFile = stdin; - pOutFile = stdout; - for (argPtr=1; argPtr= REC_DIM) { - printf("too many records\n"); - return 1; - } - if (strcmp(argv[argPtr], "F") == 0) { - records[nRec].filled = 'F'; - argPtr++; - if (argPtr >= argc) - break; - } - else - records[nRec].filled = ' '; - strncpy(records[nRec].name, argv[argPtr], db_name_dim); - nRec++; - } - } - else { - while (getFieldFromStream(pInFile, rec, &filled) != EOF) { - if (strncmp(rec, "NAME:", 5) == 0) { - while (getFieldFromStream(pInFile, rec, &filled) != EOF) { - if (strcmp(rec, "%endHeader%") == 0) { - getFieldFromStream(pInFile, rec, &filled); - break; - } - } - } - if (nRec >= REC_DIM) { - printf("too many records\n"); - return 1; - } - records[nRec].filled = filled; - strncpy(records[nRec].name, rec, db_name_dim); - nRec++; - } - } - for (i=0; i= 0; nFld++) { - assert(nFld < FLD_DIM); - fields[nFld] = f[nFld]; - types[nFld] = t[nFld]; - notInDct[nFld] = notDct[nFld]; - notInField[nFld] = notField[nFld]; - } -} - -/*+/subr********************************************************************** -* NAME setUpRec - initialize the structure for a record -* -*-*/ -setUpRec(pRec, dctFlag) -REC *pRec; -int dctFlag; -{ - char *dot, *wild; - int aField; - int i; - - strcpy(pRec->recName, pRec->name); - strcpy(pRec->recType, "."); - strcpy(pRec->hostName, "notFound"); - pRec->pHead = NULL; - pRec->pTail = NULL; - - if ((dot = strchr(pRec->recName, '.')) != NULL) { - *dot = '\0'; /* truncate pRec->recName at the '.' */ - if (strchr(dot+1, '*') != NULL || strchr(dot+1, '?') != NULL) - printf("\n*** wildcards in field name won't be acted on\n"); - if (strcmp(dot+1, "VAL") != 0) { - pRec->aField = aField = 1; - strcpy(pRec->fldName, dot+1); - } - else { - pRec->aField = aField = 0; - strcpy(pRec->fldName, "."); - } - } - else { - pRec->aField = aField = 0; - strcpy(pRec->fldName, "."); - } - pRec->found = 0; - if ((wild = strchr(pRec->recName, '*')) == NULL) - wild = strchr(pRec->recName, '?'); - if (wild != NULL) { - if (dctFlag) { - strcpy(pRec->recType, "wild"); - pRec->hasWild = 1; - } - else - printf("\n*** wildcards in record name won't be acted on\n"); - } - - for (i=0; iaField) - strcpy(pRec->info[i].name, pRec->name); - else if (fields[i] != '\0') - sprintf(pRec->info[i].name, "%s.%s", pRec->recName, fields[i]); - else - strcpy(pRec->info[i].name, pRec->name); - pRec->info[i].pCh = NULL; - pRec->info[i].type = types[i]; - pRec->info[i].inIOC = pRec->info[i].inDCT = 1; - if (dctFlag) { - strcpy(pRec->info[i].val, "."); - if (notInDct[i]) - pRec->info[i].inDCT = 0; - } - else if (aField && notInField[i]) { - strcpy(pRec->info[i].val, "n/a"); - pRec->info[i].inIOC = 0; - } - else - strcpy(pRec->info[i].val, "bad!"); - } -} - -/*+/subr********************************************************************** -* NAME getInfo_DCT - get information from DCT -* -* DESCRIPTION -* Gets information from DCT. This routine will process either -* 1) a file containing a list of white-space-separated path names -* for DCT short reports; or 2) an actual DCT short report. -* -*-*/ -getInfo_DCT(pDctFile) -FILE *pDctFile; /* I control file or short report */ -{ - FILE *pFile; - char file[100]; - - while (getFieldFromStream(pDctFile, file, NULL) != EOF) { - if (strcmp(file, "$$mono") == 0) { - getInfo_DCTfile(pDctFile); - break; - } - if ((pFile = fopen(file, "r")) == NULL) { - printf("couldn't open %s\n", file); - perror(""); - return 1; - } - getInfo_DCTfile(pFile); - fclose(pFile); - if (allFound) - break; - } -} - -/*+/subr********************************************************************** -* NAME getInfo_DCTfile - process a DCT short report -* -*-*/ -getInfo_DCTfile(pFile) -FILE *pFile; -{ - int rec, fld; - int stat; - int i; - int c; - char field[100]; - char value[100]; - int gotOne=0; - - while (1) { - c = getFieldFromStream(pFile, field, NULL); - if (c == EOF || strcmp(field, "PV:") == 0) { - if (gotOne) - getInfo_DCT_work(); - allFound = 1; - for (i=0; iname, dctName); - else - sprintf(pRec->name, "%s.%s", dctName, records[rec].fldName); - setUpRec(pRec, 1); - pRec->filled = records[rec].filled; - DoubleListAppend(pRec, records[rec].pHead, records[rec].pTail); - } - else - pRec = &records[rec]; - strcpy(pRec->hostName, dctNode); - strcpy(pRec->recType, dctType); - if (pRec->aField) { - strcpy(pRec->info[0].val, "unknown"); - for (i=0; ifldName) == 0) { - strcpy(pRec->info[0].val, dctFields[i].fldVal); - break; - } - } - } - else - strcpy(pRec->info[0].val, "."); - if (pRec->hasWild == 0) - pRec->found = 1; - for (fld=1; fldaField && notInField[fld]) - ; /* no action */ - else { - strcpy(pRec->info[fld].val, dctValues[fld]); - if (types[fld] == DBR_SHORT) - sscanf(dctValues[fld], "%hd", &pRec->info[fld].shtval); - else if (types[fld] == DBR_FLOAT) - sscanf(dctValues[fld], "%f", &pRec->info[fld].fltval); - } - } - } - } -} - -/*+/subr********************************************************************** -* NAME getInfo_IOC - get information from IOCs -* -*-*/ -getInfo_IOC() -{ - int rec, fld; - int stat; - int i; - chid pCh; - -/*----------------------------------------------------------------------------- -* make the connections -*----------------------------------------------------------------------------*/ - for (rec=0; recpHead) != NULL) { - while (pR != NULL) { - fprintf(pOutFile, "%-8s %4.4s %30s %c %8s", pR->hostName, - pR->recType, pR->name, pR->filled, pR->info[0].val); - for (i=1; iinfo[i].fltval, 3); - fprintf(pOutFile, " %4.4s", fltText); - } - else - fprintf(pOutFile, " %4.4s", pR->info[i].val); - } - } - fprintf(pOutFile, "\n"); - pR = pR->pNext; - } - return; - } - fprintf(pOutFile, "%-8s %4.4s %30s %c %8s", pRec->hostName, - pRec->recType, pRec->name, pRec->filled, pRec->info[0].val); - for (i=1; iinfo[i].fltval, 3); - fprintf(pOutFile, " %4.4s", fltText); - } - else - fprintf(pOutFile, " %4.4s", pRec->info[i].val); - } - } - fprintf(pOutFile, "\n"); - return; - } - if (header) { - fprintf(pOutFile, "\n%30s F %8s", "name", "value"); - for (i=1; iname, pRec->filled, pRec->info[0].val); - for (i=1; iinfo[i].val, "bad!") == 0 || - strcmp(pRec->info[i].val, ".") == 0 || - strcmp(pRec->info[i].val, "n/a") == 0) - fprintf(pOutFile, " %4.4s", pRec->info[i].val); - else if (types[i] == DBR_FLOAT) { - cvtDblToTxt(fltText, 4, pRec->info[i].fltval, 3); - fprintf(pOutFile, " %4.4s", fltText); - } - else - fprintf(pOutFile, " %4d", pRec->info[i].shtval); - } - fprintf(pOutFile, "\n"); -} - -/*+/subr********************************************************************** -* NAME getFieldFromStream - get next name from file -* -* DESCRIPTION -* Gets the next white-space-delimited field from a FILE* stream. -* Blank lines are ignored. The `#' character starts a comment-- -* all the rest of a line is ignored. The `#' also serves as -* a delimiter for a field. -* -* If the pFilled argument isn't NULL, then a field of "F" is -* treated special: It is taken to be a modifier for the following -* field. -* -* RETURNS -* delimiter, or -* EOF -* -*-*/ -getFieldFromStream(pFile, pName, pFilled) -FILE *pFile; -char *pName; -char *pFilled; -{ - char *name=pName; - int c; - char filled; - - *name = '\0'; - filled = ' '; - while ((c = fgetc(pFile)) != EOF) { - if (!isascii(c)) - break; - if (isspace(c)) { - if (name == pName) - ; /* skip over white space */ - else if (strcmp(pName, "F") == 0) { - if (pFilled == NULL) - break; - filled = 'F'; - name = pName; - *name = '\0'; - } - else - break; - } - else if (c == '#') { - while ((c = fgetc(pFile)) != EOF && c != '\n') - ; /* keep skipping until \n */ - if (name != pName) - break; - } - else { - *(name++) = c; - *name = '\0'; - } - } - if (name == pName) - return EOF; - - if (pFilled != NULL) - *pFilled = filled; - return c; -} - -/*+/subr********************************************************************** -* NAME cvtDblToTxt - convert double to text, being STINGY with space -* -* DESCRIPTION -* Convert a double value to text. The main usefulness of this routine -* is that it maximizes the amount of information presented in a -* minimum number of characters. For example, if a 1 column width -* is specified, only the sign of the value is presented. -* -* When an exponent is needed to represent the value, for narrow -* column widths only the exponent appears. If there isn't room -* even for the exponent, large positive exponents will appear as E*, -* and large negative exponents will appear as E-. -* -* Negative numbers receive some special treatment. In narrow -* columns, very large negative numbers may be represented as -* and - -* -*-*/ -static -cvtDblToTxt(text, width, value, decPl) -char *text; /* O text representation of value */ -int width; /* I max width of text string (not counting '\0') */ -double value; /* I value to print */ -int decPl; /* I max # of dec places to print */ -{ - double valAbs; /* absolute value of caller's value */ - int wholeNdig; /* number of digits in "whole" part of value */ - double logVal; /* log10 of value */ - int decPlaces; /* number of decimal places to print */ - int expI; /* exponent for frac values */ - double expD; - int expWidth; /* width needed for exponent field */ - int excess; /* number of low order digits which - won't fit into the field */ - char tempText[100]; /* temp for fractional conversions */ - int roomFor; - int minusWidth; /* amount of room for - sign--0 or 1 */ - -/*----------------------------------------------------------------------------- -* special cases -*----------------------------------------------------------------------------*/ - if (value == 0.) { - (void)strcpy(text, "0"); - return; - } - else if (value == 1.) { - (void)strcpy(text, "1"); - return; - } - if (width == 1) { - if (value >= 0) - strcpy(text, "+"); - else - strcpy(text, "-"); - return; - } - else if (width == 2 && value <= -1.) { - if (value == -1.) - strcpy(text, "-1"); - else - strcpy(text, "-"); - return; - } - - valAbs = value>0. ? value : -value; - logVal = log10(valAbs); - if (logVal < 0.) { -/*----------------------------------------------------------------------------- -* numbers with only a fractional part -*----------------------------------------------------------------------------*/ - if (width == 2) { - if (value > 0.) - strcpy(tempText, "0E-"); - else - strcpy(tempText, "0-."); - } - else if (width == 3 && value < 0) - strcpy(tempText, "0-."); - else { - if (value < 0.) - minusWidth = 1; - else - minusWidth = 0; - expI = -1 * (int)logVal; - if (expI < 9) - expWidth = 3; /* need E-n */ - else if (expI < 99) - expWidth = 4; /* need E-nn */ - else if (expI < 999) - expWidth = 5; /* need E-nnn */ - else - expWidth = 6; /* need E-nnnn */ - /* figure out how many sig digit can appear if print "as is" */ - /* expI is the number of leading zeros */ - roomFor = width - expI - 1 - minusWidth; /* -1 for the dot */ - if (roomFor >= 1) { - decPlaces = expI + decPl; - if (decPlaces > width -1 - minusWidth) - decPlaces = roomFor + expI; - (void)sprintf(tempText, "%.*f", decPlaces, value); - if (value < 0.) - tempText[1] = '-'; - } - else { - expD = expI; - value *= exp10(expD); - if (value > 0.) - sprintf(tempText, "0.E-%d", expI); - else - sprintf(tempText, "--.E-%d", expI); - } - } - - strncpy(text, &tempText[1], width); - text[width] = '\0'; - return; - } - -/*----------------------------------------------------------------------------- -* numbers with both an integer and a fractional part -* -* find out how many columns are required to represent the integer part -* of the value. A - is counted as a column; the . isn't. -*----------------------------------------------------------------------------*/ - wholeNdig = 1 + (int)logVal; - if (value < 0.) - wholeNdig++; - if (wholeNdig < width-1) { -/*----------------------------------------------------------------------------- -* the integer part fits well within the field. Find out how many -* decimal places can be printed (honoring caller's decPl limit). -*----------------------------------------------------------------------------*/ - decPlaces = width - wholeNdig - 1; - if (decPl < decPlaces) - decPlaces = decPl; - if (decPl > 0) - (void)sprintf(text, "%.*f", decPlaces, value); - else - (void)sprintf(text, "%d", nint(value)); - } - else if (wholeNdig == width || wholeNdig == width-1) { -/*----------------------------------------------------------------------------- -* The integer part just fits within the field. Print the value as an -* integer, without printing the superfluous decimal point. -*----------------------------------------------------------------------------*/ - (void)sprintf(text, "%d", nint(value)); - } - else { -/*----------------------------------------------------------------------------- -* The integer part is too large to fit within the caller's field. Print -* with an abbreviated E notation. -*----------------------------------------------------------------------------*/ - expWidth = 2; /* assume that En will work */ - excess = wholeNdig - (width - 2); - if (excess > 999) { - expWidth = 5; /* no! it must be Ennnn */ - excess += 3; - } - else if (excess > 99) { - expWidth = 4; /* no! it must be Ennn */ - excess += 2; - } - else if (excess > 9) { - expWidth = 3; /* no! it must be Enn */ - excess += 1; - } -/*----------------------------------------------------------------------------- -* Four progressively worse cases, with all or part of exponent fitting -* into field, but not enough room for any of the value -* Ennn positive value; exponent fits -* -Ennn negative value; exponent fits -* +**** positive value; exponent too big -* -**** negative value; exponent too big -*----------------------------------------------------------------------------*/ - if (value >= 0. && expWidth == width) - (void)sprintf(text, "E%d", nint(logVal)); - else if (value < 0. && expWidth == width-1) - (void)sprintf(text, "-E%d", nint(logVal)); - else if (value > 0. && expWidth > width) - (void)sprintf(text, "%.*s", width, "+*******"); - else if (value < 0. && expWidth > width-1) - (void)sprintf(text, "%.*s", width, "-*******"); - else { -/*----------------------------------------------------------------------------- -* The value can fit, in exponential notation -*----------------------------------------------------------------------------*/ - (void)sprintf(text, "%dE%d", - nint(value/exp10((double)excess)), excess); - } - } -} diff --git a/src/util/recordTest.c b/src/util/recordTest.c deleted file mode 100644 index cb8e52333..000000000 --- a/src/util/recordTest.c +++ /dev/null @@ -1,340 +0,0 @@ -/* recordTest.c */ -/* share/src/util $Id$ */ - -/* recordTest.c - Record Test Program - * - * Author: Janet Anderson - * Date: 02-05-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 02-10-92 jba initial version - * .02 09-14-93 jba modified includes and fixed strcmp - * -Need to do: - - 1. Change to DBR_STS_STRING ??? - 2. Terminate connections only when test for a new rec type are encountered - 3. Add handling of elementCount > 1 - 5. Add epics release info to output file - 6. Add date and IOC info to output file - */ - -#ifdef vxWorks -#include -#endif - -#include -#include -#include -#include - -#ifndef ERROR -#define ERROR -1 -#endif -#ifndef OK -#define OK 0 -#endif - -#define PUT 0 -#define GET 1 -#define FIELDS 4 -#define MAXLINE 150 -#define MAX_ELEMENTS 150 -#define MAX_STRING_SIZE 40 - -char errmsg[MAXLINE]; - -void recordTest(); -int connectChan(); -int disconnectChan(); -int doTestLine(); -int getPV(); -int putPV(); - -#ifndef vxWorks -main(argc,argv) -int argc; -char *argv[]; -{ - - - if(argc > 2){ - printf("usage: recordTest \n"); - printf("the following arguments were received\n"); - while(argc>0) { - printf("%s\n",argv[0]); - argv++; argc--; - } - return ERROR; - } - if ( argc == 2 ){ - printf("\n\n\n\n\n\nTest of record types:"); - while(--argc>0) printf(" %s",*++argv); - } else { - printf("Test of ALL record types"); - } - - printf("\n"); - - recordTest(argv); - -} -#endif - -void recordTest(argv) -char *argv[]; -{ - char str[MAXLINE]; - - char ioType[MAX_STRING_SIZE]; - char name[MAX_STRING_SIZE]; - char value[MAX_STRING_SIZE]; - char verify[MAX_STRING_SIZE]; - chid chanId; - int count; - long status; - - /* get test line */ - while ( gets(str)) { - - /* print and skip null lines and comment lines */ - if ( str[0]==NULL || str[0] == '!' ) { - printf("%s\n",str); - continue; - } - - /* parse input line for fields */ - count=sscanf(str,"%s %s \"%[^\"]\" %s",ioType,name,value,verify); - - /* check field count */ - if ( count != FIELDS ) { - printf("\n%s\n",str); - printf ("***** ERROR ***** field count %d is not equal to %d\n",count,FIELDS); - continue; - } - - /* check 1st char of name */ - if (((*name < ' ') || (*name > 'z'))){ - printf("\n%s\n",str); - printf ("***** ERROR ***** pv name check error "); - continue; - } - - /* check for blank string value */ - if ( *value == ' ' ) *value = '\0'; - - /* connect to a channel */ - status = connectChan(name,&chanId); - if( status ){ - printf("\n%s\n",str); - printf ("***** ERROR ***** %s \n",errmsg); - continue; - } - - /* execute test line */ - status=doTestLine(name,ioType,chanId,value,verify); - if ( status ){ - printf("\n%s\n",str); - printf ("***** ERROR ***** status=%d %s\n",status,errmsg); - } - - /* disconnect channel */ - status = disconnectChan(&chanId); - if( status ){ - printf("\n%s\n",str); - printf ("***** ERROR ***** %s \n",errmsg); - continue; - } - - } - printf ("\nrecordTest ALL DONE\n\n\n"); -} - -int connectChan(name,pchanId) -char name[]; -chid *pchanId; -{ - int status=0; - - /* connect to a channel */ - status = ca_search(name, pchanId); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_search"); - return ERROR; - } - - /* wait for connection */ - status = ca_pend_io(2.0); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_pend_io"); - return ERROR; - } - return OK; -} - -int disconnectChan(pchanId) -chid *pchanId; -{ - - /* terminate connection */ -/* - if(pchanId){ - status=ca_clear_channel(*pchanId); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_clear_channel"); - return ERROR; - } - } -*/ - return OK; -} - -int doTestLine(name,ioType,chanId,value,verify) -char name[]; -char *ioType; -chid chanId; -char value[]; -char verify[]; -{ - int status=0; - - if ( *ioType == 'P'){ - status=putPV(name,chanId,value,verify); - } - else if ( *ioType == 'G'){ - status=getPV(name,chanId,value,verify); - } - else { - status=ERROR; - strcpy(errmsg,"doTestLine"); - } - - return status; -} - - - -/* Read from a channel */ - -int getPV(name,chanId,value,verify) -char name[]; -chid chanId; -char value[]; -char verify[]; -{ - int status; - long elementCount; - char valueChan[MAX_ELEMENTS] [MAX_STRING_SIZE]; - - - /* fetch element count */ - elementCount=ca_element_count(chanId); - - /* fetch value */ - status = ca_array_get( - DBR_STRING, - elementCount, - chanId, - valueChan); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_array_get"); - return ERROR; - } - - status=ca_pend_io(2.0); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_pend_io"); - return ERROR; - } - - /* verify channel value*/ - if (*verify == 'V'){ - - status=strcmp(value,valueChan[0]); - if (status) { - sprintf(errmsg,"strcmp failed: valueChan=%s",valueChan); - return ERROR; - } - } - else printf(" %s=%s\n",name,valueChan); - - return OK; -} - - -/* Write to a process variable */ -int putPV(name,chanId,value,verify) -char name[]; -chid chanId; -char value[]; -char verify[]; -{ - char valueChan[MAX_ELEMENTS] [MAX_STRING_SIZE]; - int status; - long elementCount; - - /* fetch element count */ - elementCount=ca_element_count(chanId); - - - /* write value */ - status = ca_array_put( DBR_STRING, elementCount, chanId, value); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_array_put"); - return ERROR; - } - - status=ca_pend_io(2.0); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_pend_io"); - return ERROR; - } - - /* verify write */ - if (*verify == 'V'){ - - status = ca_array_get( DBR_STRING, elementCount, chanId, valueChan); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_put"); - return ERROR; - } - - status=ca_pend_io(2.0); - if(status != ECA_NORMAL){ - strcpy(errmsg,"ca_pend_io failed"); - return ERROR; - } - - /* compare channel value with value */ - status=strcmp(value,&valueChan[0][0]); - if (status) { - sprintf(errmsg,"strcmp failed: valueChan=%s",valueChan); - return ERROR; - } - } - - return OK; -} - diff --git a/src/util/sydPlot.c b/src/util/sydPlot.c deleted file mode 100644 index 15e51fff5..000000000 --- a/src/util/sydPlot.c +++ /dev/null @@ -1,4081 +0,0 @@ -/* base/src/util $Id$ - * Author: Roger A. Cole - * Date: 12-04-90 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991-93, 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-04-90 rac initial version - * .02 06-30-91 rac installed in SCCS - * .03 09-06-91 rac change pprAreaErase to pprRegionErase; add - * documentation - * .04 10-01-91 rac properly handle channels which aren't connected yet - * .05 10-20-91 rac avoid an abort on printing a plot to - * PostScript; for non-user-window plotting, - * defer the pprWinIsMono call until after - * the window is mapped - * .06 12-03-91 rac add some intelligence to auto ranging - * .07 01-23-92 rac don't take log10 of zero value - * .08 03-31-92 rac fix plotting of filled channels; set time axis - * scaling based on firstData to lastData rather - * than 0 to sampleCount; handle plotting mean and - * standard deviation; handle plotting restricted set - * of data; better annotate time axes; support a time - * cursor on a plot; add sydPlotChan_event to determine - * which channel a mouse event applies to; - * .09 08-27-92 rac add user-specified range for AutoRange; add more - * smarts to AutoRange; have only one X-axis annotation; - * add strip chart; discontinue use of special malloc; - * .10 10-01-92 rac continued work on strip chart; use pprWave routines; - * .11 01-12-93 rac get StripYY routines in sync with StripY routines - * .12 05-04-94 pg HPUX port changes. - * - * make options - * -DXWINDOWS makes a version for X11 - * -DNDEBUG don't compile assert() checking - * -DDEBUG compile various debug code - */ -/*+/mod*********************************************************************** -* TITLE sydPlot.c - plotting for synchronous data -* -* DESCRIPTION -* These routines provide high-level plotting capability in conjunction -* with the sydSubr.c routines. The data acquired by the sydSubr -* routines are accepted directly by these plotting routines. -* -* These routines support plotting in either batch or incremental mode. -* In batch mode, all the samples exist at the time of plotting; for -* incremental mode, only part (or none) of the samples exist when -* plotting starts, and additional samples are to be plotted as they -* arrive. -* -* Some windowing events, such as expose and resize, are transparently -* handled by these routines. Hard copy of plots to a PostScript -* printer is easily available. -* -* QUICK REFERENCE -* -* #include -* #include -* -* void sydPlotAxisAutoRange(pSlave, minVal, maxVal) -* long sydPlotAxisSetAttr(pSlave, attr, value, pArg) -* attr = SYD_PLATTR_{GC} -* SYD_PL_SLAVE *sydPlotChanAdd(pMstr, pSChan) -* SYD_PL_SLAVE *sydPlotChan_event(pMstr, x, y) -* long sydPlotDone(pMstr, quitFlag) -* long sydPlotEraseSamples(pMstr) -* long sydPlotInit(pMstr, pSspec, winType, dispName, winTitle, -* fullInit) -* long sydPlotInitUW(pMstr, pSspec, pDisp, window, gc) -* long sydPlotSamples(pMstr, begin, end, incrFlag) -* long sydPlotSetAttr(pMstr, attr, value, pArg) -* attr = SYD_PLATTR_{FG1,FG2,INCR,LINE,MARK,MONO,POINT,SHOW, -* UNDER,WRAP} -* long sydPlotSetTitles(pMstr, top, left, bottom, right) -* long sydPlotTimeCursor(pMstr, pStamp, pSlave) -* long sydPlotWinLoop(pMstr) -* long sydPlotWinReplot(pMstr) -* -* DESCRIPTION, continued -* These routines generally work with the concepts of `plot master' -* and `plot slave'. The plot master structure roughly corresponds -* to a plotting surface (i.e., X11 window or PostScript sheet) and -* contains most of the information necessary to perform plotting. -* The plot master contains a list of plot slave structures, each of -* which is analogous to a data channel. A plot slave structure -* contains channel specific information, including data. Time -* stamp information is provided via the plot master, through the -* use of its connection to synchronous sample structures. -* -* BUGS -* o sydPlotInitUW doesn't support SunView; some other routines have -* questionable support -* o there is no counterpart for sydTimeCursor for other than time-based -* plots -* o knows and uses many intimate details of the ppr structures -* -*-***************************************************************************/ -#include -#include -#include -#ifdef XWINDOWS -# include -# include -#endif -#define SYD_PLOT_PRIVATE -#include - -#ifdef vxWorks -/*---------------------------------------------------------------------------- -* includes and defines for VxWorks compile -*---------------------------------------------------------------------------*/ -# include -# include -# include -# include -#else -/*---------------------------------------------------------------------------- -* includes and defines for Sun compile -*---------------------------------------------------------------------------*/ -# include -# include -# include -# include -# include -#endif - -# ifdef _HPUX_SOURCE -# ifndef nint -# define nint(value) (value>=0 ? (int)((value)+.5) : (int)((value)-.5)) -# endif -# ifndef exp10 -# define exp10(value) (exp(value * log(10.))) -# endif -# endif - -/*----------------------------------------------------------------------------- -* prototypes -*----------------------------------------------------------------------------*/ -void sydPlot_SmithPlot(); -void sydPlot_SmithGrid(); -void sydPlot_SmithSamples(); -void sydPlot_SmithStats(); -void sydPlot_StripYPlot(); -void sydPlot_StripYGrid(); -void sydPlot_StripYRedisplay(); -void sydPlot_StripYSamples(); -void sydPlot_StripYYPlot(); -void sydPlot_StripYYGrid(); -void sydPlot_StripYYRedisplay(); -void sydPlot_StripYYSamples(); -void sydPlot_TYPlot(); -void sydPlot_TYGrid(); -void sydPlot_TYSamples(); -void sydPlot_TYStats(); -void sydPlot_TYYPlot(); -void sydPlot_TYYGrid(); -void sydPlot_XYPlot(); -void sydPlot_XYGrid(); -void sydPlot_XYSamples(); -void sydPlot_XYStats(); -void sydPlot_XYarray(); -void sydPlot_XYYPlot(); -void sydPlot_XYYGrid(); -void sydPlot_YPlot(); -void sydPlot_YGrid(); -void sydPlot_YSamples(); -void sydPlot_YStats(); -void sydPlot_Yarray(); -void sydPlot_YYPlot(); -void sydPlot_YYGrid(); - -/*+/internal****************************************************************** -* NAME sydAnnotVal - generate an array of value axis annotations -* -*-*/ -static void -sydAnnotVal(pSlave, pAnnot, annot) -SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ -char *pAnnot[]; -char annot[20][28]; -{ - int i; - double val, tick; - - assert(pSlave->nInt < 20); - - tick = (pSlave->extentVal - pSlave->originVal) / pSlave->nInt; - - for (i=0, val=pSlave->originVal; i<=pSlave->nInt; i++, val+=tick) { - if (i == pSlave->nInt) - val = pSlave->extentVal; - cvtDblToTxt(annot[i], 6, val, pSlave->decPl); - pAnnot[i] = annot[i]; - } -} - - -/*+/internal****************************************************************** -* NAME logGetOK - get log of minimum allowable tick size -* -* DESCRIPTION -* Find the minimum tick size based on a field width of 6 using -* cvtDblToTxt using for printing. -* -*-*/ -static int logGetOK(val) -double val; -{ - int logVal, logTickVal; - logVal = val != 0. ? nint(floor(log10(fabs(val)))) : -10; - if (val >= 0.) { - if (1 <= logVal && logVal <= 4) logTickVal = logVal - 4; - else if (logVal == 5) logTickVal = 0; - else if (logVal == -1) logTickVal = -4; - else logTickVal = logVal - 2; - } - else { - if (1 <= logVal && logVal <= 3) logTickVal = logVal - 3; - else if (logVal == 4) logTickVal = 0; - else if (logVal == 0) logTickVal = -3; - else if (logVal == -1) logTickVal = -4; - else logTickVal = logVal - 1; - } - return logTickVal; -} - -/*+/internal****************************************************************** -* NAME moveVal - move a value to it's tick mark -* -*-*/ -static double moveVal(val, tick, minFlag) -double val, tick; -int minFlag; -{ - double moved; - int awayFrom=0; - double temp; - - if (val < 0 && minFlag) awayFrom = 1; - else if (val > 0 && !minFlag) awayFrom = 1; - if (val > -1. * tick && val < tick && awayFrom == 0) - return 0.; - temp = fmod(val, tick); - moved = val - temp; - if (awayFrom && temp != 0.) { - if (val <= 0.) { if (moved > val) moved -= tick; } - else { if (moved < val) moved += tick; } - } - return moved; -} - -/*+/internal****************************************************************** -* NAME autoRange - compute auto range for an axis -* -*-*/ -static void -autoRange(pOrigin, pExtent, pNTicks, pTick, pDecPl) -double *pOrigin, *pExtent, *pTick; -int *pNTicks, *pDecPl; -{ - double origin, extent; - double min, min1, max, max1, logD, tick; - int logTick, logTickMin, logTickMax, logTickOK; - double maxVal; - int nTicks, decPl; - -#define MIN(a,b) (a<=b?a:b) -#define MAX(a,b) (a<=b?b:a) - - min = MIN(*pOrigin, *pExtent); - max = MAX(*pOrigin, *pExtent); - if (min == max) - min -= .001, max += .001; - min1 = min; max1 = max; -/*----------------------------------------------------------------------------- -* First, determine tick size and number of intervals without regard -* to the number of divisions which would result. Round the min -* and max to tick boundaries. -*----------------------------------------------------------------------------*/ - logD = floor(log10(max-min)); - tick = exp10(logD); - min = moveVal(min, tick, 1); - max = moveVal(max, tick, 0); - - nTicks = nint((max - min) / tick); - if (nTicks == 10) nTicks = 5, tick *= 2.; - else if (nTicks == 1) nTicks = 5, tick /= 5.; - else if (nTicks == 2) nTicks = 4, tick /= 2.; - else if (nTicks == 8) nTicks = 4, tick *= 2.; - else if (nTicks == 9) nTicks = 3, tick *= 3.; -/*----------------------------------------------------------------------------- -* Next, make sure the tick size is consistent with printing in a -* six character field with 3 significant digits. For example, if the -* max is 1000000, it will print as 100E4, allowing a minimum tick -* size of 10000. -*----------------------------------------------------------------------------*/ - logTick = nint(floor(log10(tick))); - logTickMax = logGetOK(max); - logTickMin = logGetOK(min); - logTickOK = MAX(logTickMin, logTickMax); - if (logTickOK > logTick) { - tick = exp10((double)logTickOK); - min = moveVal(min1, tick, 1); - max = moveVal(max1, tick, 0); - nTicks = 1; - } -/*----------------------------------------------------------------------------- -* Now, figure how many decimal places can be printed, based on the -* biggest endpoint, assuming a field width of 6 characters. -*----------------------------------------------------------------------------*/ - maxVal = fabs(max) > fabs(min) ? max : min; - if (maxVal >= 10000. || maxVal <= -1000.) decPl = 0; - else if (maxVal >= 1000. || maxVal <= -100.) decPl = 1; - else if (maxVal >= 100. || maxVal <= -10.) decPl = 2; - else if (maxVal >= 10. || maxVal <= -1.) decPl = 3; - else decPl = 4; - if (*pOrigin <= *pExtent) { - *pTick = tick; - *pOrigin = min; - *pExtent = max; - } - else { - *pOrigin = max; - *pExtent = min; - *pTick = 0. - tick; - } - *pNTicks = nTicks; - *pDecPl = decPl; -} - -/*+/subr********************************************************************** -* NAME sydPlotAxisAutoRange - set axis ends to min and max data values -* -* DESCRIPTION -* Sets the endpoints of the axis for the plot slave structure to -* `nice' values based on the minimum and maximum of the data for the -* slave. The number of intervals to divide the axis is also set. -* -* If the minimum and maximum values specified in the call aren't equal, -* they are used for scaling, rather than the min and max of the data. -* -* RETURNS -* void -* -* SEE ALSO -* -* EXAMPLE -* -* -*-*/ -void -sydPlotAxisAutoRange(pSlave, minVal, maxVal) -SYD_PL_SLAVE *pSlave; /* I pointer to plot slave structure */ -double minVal; /* I minimum value, for setting scaling */ -double maxVal; /* I maximum value, for setting scaling */ -{ - SYD_CHAN *pSChan=pSlave->pSChan; - double origin=pSlave->pSChan->restrictMinDataVal; - double extent=pSlave->pSChan->restrictMaxDataVal; - int nInt, decPl; - double tick; - - if (pSChan->dbrType == DBR_TIME_ENUM) - return; - if (minVal != maxVal) { - origin = minVal; - extent = maxVal; - } - - autoRange(&origin, &extent, &nInt, &tick, &decPl); - pSlave->originVal = origin; - pSlave->extentVal = extent; - pSlave->nInt = nInt; - pSlave->decPl = decPl; -} - -/*+/subr********************************************************************** -* NAME sydPlotAxisSetAttr - set plot axis attributes -* -* DESCRIPTION -* Setting an attribute doesn't automatically reset other related -* attributes. -* -* Declare a slave to be used as the x-axis channel when x vs. y -* plotting is done: -* sydPlotAxisSetAttr(pSlave, SYD_PLATTR_XCHAN, {0,1}, NULL) -* -* Set the background and/or foreground pixel values for X11 for -* a slave: -* sydPlotAxisSetAttr(pSlave, SYD_PLATTR_BG, 0, pBgPixelValue) -* sydPlotAxisSetAttr(pSlave, SYD_PLATTR_FG, 0, pFgPixelValue) -* -* RETURNS -* S_syd_OK -* -* BUGS -* o text -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydPlotAxisSetAttr(pSlave, attr, value, pArg) -SYD_PL_SLAVE *pSlave; /* I pointer to plot slave structure */ -SYD_PLATTR attr; /* I attribute selector--one of SYD_PLATTR_xxx */ -int value; /* I value for attribute */ -void *pArg; /* I pointer for value for attribute */ -{ - if (attr == SYD_PLATTR_XCHAN) pSlave->xChan = value; -#ifdef XWINDOWS - else if (attr == SYD_PLATTR_BG) - pSlave->bg = *(unsigned long *)pArg; - else if (attr == SYD_PLATTR_FG) - pSlave->fg = *(unsigned long *)pArg; -#endif - else assertAlways(0); - - return S_syd_OK; -} - -/*+/internal****************************************************************** -* NAME sydPlotAxisSetup - set up axis information for a channel -* -* DESCRIPTION -* Set up axis information. -* o the axis endpoints are set to LOPR and HOPR. If LOPR==HOPR, -* then minimum and maximum data values are used for endpoints. -* If min==max, then arbitrary values are used. -* o number of major intervals is set to 5 -* -* RETURNS -* void -* -* BUGS -* o in pathological cases, the setup is overly arbitrary -* o number of intervals is fixed at 5 -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -void -sydPlotAxisSetup(pSlave) -SYD_PL_SLAVE *pSlave; /* I pointer to plot slave structure */ -{ - SYD_CHAN *pSChan=pSlave->pSChan; - double originVal, extentVal; - int nInt=5; - - if (pSChan->dbrType == DBR_TIME_FLOAT) { - originVal = pSChan->grBuf.gfltval.lower_disp_limit; - extentVal = pSChan->grBuf.gfltval.upper_disp_limit; - } - else if (pSChan->dbrType == DBR_TIME_SHORT) { - originVal = pSChan->grBuf.gshrtval.lower_disp_limit; - extentVal = pSChan->grBuf.gshrtval.upper_disp_limit; - } - else if (pSChan->dbrType == DBR_TIME_DOUBLE) { - originVal = pSChan->grBuf.gdblval.lower_disp_limit; - extentVal = pSChan->grBuf.gdblval.upper_disp_limit; - } - else if (pSChan->dbrType == DBR_TIME_LONG) { - originVal = pSChan->grBuf.glngval.lower_disp_limit; - extentVal = pSChan->grBuf.glngval.upper_disp_limit; - } - else if (pSChan->dbrType == DBR_TIME_CHAR) { - originVal = pSChan->grBuf.gchrval.lower_disp_limit; - extentVal = pSChan->grBuf.gchrval.upper_disp_limit; - } - else if (pSChan->dbrType == DBR_TIME_ENUM) { - nInt = pSChan->grBuf.genmval.no_str-1; - originVal = 0; - extentVal = nInt; - if (originVal >= extentVal) { - if (nInt < 0) - (void)strcpy(pSChan->grBuf.genmval.strs[0], " "); - extentVal = nInt = 1; - pSChan->grBuf.genmval.no_str = 2; - (void)strcpy(pSChan->grBuf.genmval.strs[1], " "); - } - } - if (originVal == extentVal) { - originVal = pSlave->pSChan->minDataVal; - extentVal = pSlave->pSChan->maxDataVal; - } - if (originVal == extentVal) { - if (originVal == 0.) - extentVal = 10.; - else if (originVal < 0.) - extentVal = 0; - else - originVal = 0.; - } - pSlave->originVal = originVal; - pSlave->extentVal = extentVal; - pSlave->nInt = nInt; - pSlave->nSubInt = 0; - pSlave->decPl = 3; -} - -/*+/subr********************************************************************** -* NAME sydPlotChanAdd - add a plot slave -* -* DESCRIPTION -* Adds a slave to a master plot structure. Some of the items needed -* for actual plotting are set up by this routine: -* -* o endpoints for plotting. If HOPR and LOPR are present for the -* channel, they are used as the plotting endpoints. If they -* aren't present (or if they are equal), then some relatively -* arbitrary endpoints are picked. For DBF_ENUM channels, the -* endpoints are determined by the states. -* o number of major tick intervals. For DBF_ENUM channels, the -* number of states determines the number of intervals. -* o a default plot mark to be used for mark plotting -* o a default line key to be used for monochrome plotting. This -* line key also establishes a default color to be used for -* color plotting; the default color can be overridden using -* sydPlotAxisSetAttr. -* -* RETURNS -* SYD_PL_SLAVE *, or -* NULL -* -* BUGS -* o the scheme for establishing mark and key numbers won't work if -* deleting and re-adding plot channels is allowed -* -*-*/ -SYD_PL_SLAVE * -sydPlotChanAdd(pMstr, pSChan) -SYD_PL_MSTR *pMstr; /* I pointer to plot master */ -SYD_CHAN *pSChan; /* I pointer to synchronous data channel structure, - as from sydChanOpen */ -{ - SYD_PL_SLAVE *pSlave; /* pointer to slave structure */ - int i; - - assert(pMstr != NULL); - - if (dbr_type_is_STRING(pSChan->dbrType)) { - (void)printf("sydPlotChanAdd: can't plot DBF_STRING values\n"); - return NULL; - } - if ((pSlave = (SYD_PL_SLAVE *)malloc(sizeof(SYD_PL_SLAVE))) == NULL) { - (void)printf("sydPlotChanAdd: can't get memory\n"); - return NULL; - } - - pSlave->pSChan = pSChan; - pMstr->nSlaves++; - pSlave->markNum = pMstr->nSlaves - 1; - pSlave->lineKey = pMstr->nSlaves; - pSlave->xChan = 0; - pSlave->pArea = NULL; - pSlave->fg = pSlave->bg = 0; - pSlave->first = 1; - pSlave->xFracLeft = pSlave->xFracRight = 0.; - pSlave->yFracBot = pSlave->yFracTop = 0.; - pSlave->annotXFL = pSlave->annotXFR = 0.; - pSlave->annotYFB = pSlave->annotYFT = 0.; - - DoubleListAppend(pSlave, pMstr->pHead, pMstr->pTail); - sydPlotAxisSetup(pSlave); - if (dbr_type_is_ENUM(pSChan->dbrType)) { - for (i=0; i<=pSlave->extentVal; i++) - pSlave->pAnnot[i] = pSChan->grBuf.genmval.strs[i]; - pSlave->ppAnnot = pSlave->pAnnot; - } - else - pSlave->ppAnnot = NULL; - - return pSlave; -} - -/*+/subr********************************************************************** -* NAME sydPlotChan_event - find the plot slave corresponding to an event -* -* DESCRIPTION -* The x and y position for the event are used to find the corresponding -* plot slave. This search examines the bounding box for the grid and -* the annotation area. -* -* For a shared grid plot, the result will be ambiguous. -* -* RETURNS -* SYD_PL_SLAVE *, or -* NULL -* -*-*/ -SYD_PL_SLAVE * -sydPlotChan_event(pMstr, x, y) -SYD_PL_MSTR *pMstr; /* I pointer to plot master */ -int x, y; /* I the x and y position from the event */ -{ - SYD_PL_SLAVE *pSlave; /* pointer to slave structure */ - int i; - double xFrac, yFrac; - - assert(pMstr != NULL); - - xFrac = PprPixXToXFrac(pMstr->pWin, x); - yFrac = PprPixYToYFrac(pMstr->pWin, y); - for (pSlave=pMstr->pHead; pSlave!=NULL; pSlave=pSlave->pNext) { - if (xFrac >= pSlave->xFracLeft && xFrac <= pSlave->xFracRight && - yFrac >= pSlave->yFracBot && yFrac <= pSlave->yFracTop) - return pSlave; - if (xFrac >= pSlave->annotXFL && xFrac <= pSlave->annotXFR && - yFrac >= pSlave->annotYFB && yFrac <= pSlave->annotYFT) - return pSlave; - } - return NULL; -} - -/*+/subr********************************************************************** -* NAME sydPlotDone - plotting rundown -* -* DESCRIPTION -* Wrap up processing for a plot. Each slave is closed. The present -* size and position of the plot window are saved in the plot master -* structure. -* -* RETURNS -* S_syd_OK -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydPlotDone(pMstr, quitFlag) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int quitFlag; /* I use 0 for replot, 1 for total rundown */ -{ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - SYD_PL_SLAVE *pSlave1; /* pointer to individual slave struct */ - - assert(pMstr != NULL); - - if (quitFlag) { - pSlave = pMstr->pHead; - while (pSlave != NULL) { - pMstr->nSlaves--; - DoubleListRemove(pSlave, pMstr->pHead, pMstr->pTail); - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pSlave1 = pSlave; - pSlave = pSlave->pNext; - free((char *)pSlave1); - } - pprWinInfo(pMstr->pWin, &pMstr->x, &pMstr->y, - &pMstr->width, &pMstr->height); - pprWinClose(pMstr->pWin); - } - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydPlotEraseSamples - erase samples from the screen -* -* DESCRIPTION -* Erase the plot areas for the plot master. -* -* RETURNS -* S_syd_OK -* -* SEE ALSO -* -* EXAMPLE -* -*-*/ -long -sydPlotEraseSamples(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - - assert(pMstr != NULL); - - pSlave = pMstr->pHead; - while (pSlave != NULL) { - pSlave->first = 1; - if (pSlave->pArea != NULL) { - pprRegionErase(pSlave->pArea, 1., 1., -1., -1.); - } - pSlave = pSlave->pNext; - } - - return S_syd_OK; -} - -static void sydPlotInit_common(); -/*+/subr********************************************************************** -* NAME sydPlotInit - plotting initialization -* -* DESCRIPTION -* Initialize for plotting, using an automatically created window: -* o the window is created -* o if full initialization is requested, then the default window -* size and position are used; otherwise, the size and position -* in the plot master (as saved by sydPlotDone) are used. -* -* This routine doesn't perform any plotting--sydPlotWinLoop must -* be called to do the actual plotting. -* -* The type of plotting which is done depends both on the window type -* specified in the call to this routine and on the way that the plot -* master is set up at the time of the call to sydPlotWinLoop. -* -* RETURNS -* S_syd_OK, or -* S_syd_ERROR if initialization can't be completed -* -* BUGS -* o need an sdrXxx call to initialize a master with caller-supplied -* or default size and position -* -* SEE ALSO -* sydPlotInitUW, sydPlotDone, sydPlotWinLoop -* sydPlotSetAttr -* -* EXAMPLE -* -*-*/ -long -sydPlotInit(pMstr, pSspec, winType, dispName, winTitle, fullInit) -SYD_PL_MSTR *pMstr; /* I pointer to plot master structure */ -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -PPR_WIN_TY winType; /* I type of "plot window": PPR_WIN_xxx - PPR_WIN_SCREEN for an X11 window - PPR_WIN_POSTSCRIPT for a PostScript file - PPR_WIN_EPS for an Encapsulated PostScript file -char *dispName; /* I name of "plot window"--display, PostScript - file, EPS file, or NULL */ -char *winTitle; /* I title for window title bar and icon */ -int fullInit; /* I 0 or 1 to do partial or full initialization */ -{ - if (fullInit) { - pMstr->pWin = pprWinOpen(winType, dispName, winTitle, 0,0,0,0); - if (pMstr->pWin == NULL) - return S_syd_ERROR; - pprWinInfo(pMstr->pWin, &pMstr->x, &pMstr->y, &pMstr->width, - &pMstr->height); - } - else { - pMstr->pWin = pprWinOpen(winType, dispName, winTitle, - pMstr->x, pMstr->y, pMstr->width, pMstr->height); - if (pMstr->pWin == NULL) - return S_syd_ERROR; - } - - pMstr->winType = winType; - pMstr->plotAxis = SYD_PLAX_UNDEF; - pMstr->pSspec = pSspec; - sydPlotInit_common(pMstr); - return S_syd_OK; -} -/*+/internal****************************************************************** -* NAME sydPlotInit_common -* -*-*/ -static void -sydPlotInit_common(pMstr) -SYD_PL_MSTR *pMstr; -{ - pMstr->linePlot = 1; - pMstr->pointPlot = 0; - pMstr->markPlot = 0; - pMstr->showStat = 0; - pMstr->fillUnder = 0; - pMstr->noColor = 0; - pMstr->errBar = 0; -#ifdef XWINDOWS - pMstr->pDisp = NULL; - pMstr->window = NULL; - pMstr->bg = 0; - pMstr->fg = 0; - pMstr->altPixel1 = 0; - pMstr->altPixel2 = 0; -#endif - pMstr->label[0] = '\0'; - pMstr->title[0] = '\0'; - pMstr->lTitle[0] = '\0'; - pMstr->bTitle[0] = '\0'; - pMstr->rTitle[0] = '\0'; - pMstr->pHead = NULL; - pMstr->pTail = NULL; - pMstr->nSlaves = 0; - pMstr->originVal = 0.; - pMstr->extentVal = 0.; - pMstr->nInt = 1; - pMstr->nSubInt = 0; - pMstr->stripIncr = .2; - pMstr->wrapX = 0; - if (pMstr->pSspec->sampleCount >= 1) { - pMstr->originVal = - pMstr->pSspec->pDeltaSec[pMstr->pSspec->restrictFirstData] - - pMstr->pSspec->restrictDeltaSecSubtract; - pMstr->extentVal = - pMstr->pSspec->pDeltaSec[pMstr->pSspec->restrictLastData] - - pMstr->pSspec->restrictDeltaSecSubtract; - } -} - -#ifdef XWINDOWS -/*+/subr********************************************************************** -* NAME sydPlotInitUW - plotting initialization, using User Window -* -* DESCRIPTION -* Initialize for plotting, using a user-supplied window. -* -* This routine doesn't perform any actual plotting. When an expose -* or resize event occurs (or when additional samples are received -* when plotting in incremental mode), one of the following routines -* must be called to perform plotting: -* -* sydPlotWinReplot--plots all the samples in the synchronous data -* set. -* -* sydPlotSamples--plots the indicated subset of the samples in the -* synchronous data set. -* -* RETURNS -* S_syd_OK -* -* BUGS -* o available only for X11 -* -* SEE ALSO -* sydPlotInit, sydPlotDone, sydPlotWinReplot, sydPlotSamples -* sydPlotSetAttr -* -* EXAMPLE -* -*-*/ -long -sydPlotInitUW(pMstr, pSspec, pDisp, window, gc) -SYD_PL_MSTR *pMstr; /* I pointer to plot master structure */ -SYD_SPEC *pSspec; /* I pointer to synchronous set spec */ -Display *pDisp; /* I X11 display pointer */ -Window window; /* I X11 window handle */ -GC gc; /* I X11 gc handle */ -{ - long stat; - - pMstr->pWin = pprWinOpenUW(&pDisp, &window, &gc, NULL); - assertAlways(pMstr->pWin != NULL); - - pMstr->winType = PPR_WIN_SCREEN; - pMstr->plotAxis = SYD_PLAX_UNDEF; - pMstr->pSspec = pSspec; - sydPlotInit_common(pMstr); - if (pprWinIsMono(pMstr->pWin)) - pMstr->noColor = 1; - else - pMstr->noColor = 0; - pMstr->pDisp = pDisp; - pMstr->window = window; - - return S_syd_OK; -} -#endif XWINDOWS - -/*+/subr********************************************************************** -* NAME sydPlotSamples - plot one or more sync samples -* -* DESCRIPTION -* Plot one or more samples in the synchronous sample set (whose -* handle is held by the plot master). The sample range is specified -* as sample numbers within the sync sample set. -* -* This routine is for use only with sydPlotInitUW. When this routine -* is called, the sydPlot_xxx routine indicated by the .plotAxis -* member of the plot master structure is called. -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* sydPlotInitUW, sydPlotSetAttr, sydPlot_xxx -* -* NOTES -* 1. The `incrFlag' argument allows plotting in either batch or -* incremental mode. If incrFlag is 1, then this set of samples will -* be treated as a continuation of a prior set of samples. This is -* important primarily for line plots. Both sydPlotChanAdd and -* sydPlotEraseSamples set the flag (for one or all slaves, respectively) -* indicating there was no prior set of samples; this might be used -* to avoid having to change incrFlag back and forth. -* -*-*/ -void -sydPlotSamples(pMstr, begin, end, incrFlag) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin sample to plot */ -int end; /* I number of end sample to plot */ -int incrFlag; /* I 0,1 for batch,incremental plotting */ -{ - if (pMstr->plotAxis == SYD_PLAX_TY) - sydPlot_TYSamples(pMstr, begin, end, incrFlag); - else if (pMstr->plotAxis == SYD_PLAX_TYY) - sydPlot_TYSamples(pMstr, begin, end, incrFlag); - else if (pMstr->plotAxis == SYD_PLAX_XY) - sydPlot_XYSamples(pMstr, begin, end, incrFlag); - else if (pMstr->plotAxis == SYD_PLAX_XYY) - sydPlot_XYSamples(pMstr, begin, end, incrFlag); - else if (pMstr->plotAxis == SYD_PLAX_Y) - sydPlot_YSamples(pMstr, begin, end, incrFlag); - else if (pMstr->plotAxis == SYD_PLAX_YY) - sydPlot_YSamples(pMstr, begin, end, incrFlag); - else if (pMstr->plotAxis == SYD_PLAX_STRIP_Y) - sydPlot_StripYSamples(pMstr, begin, end, incrFlag); - else if (pMstr->plotAxis == SYD_PLAX_STRIP_YY) - sydPlot_StripYSamples(pMstr, begin, end, incrFlag); - else if (pMstr->plotAxis == SYD_PLAX_SMITH_IMP || - pMstr->plotAxis == SYD_PLAX_SMITH_ADM || - pMstr->plotAxis == SYD_PLAX_SMITH_IMM) - sydPlot_SmithSamples(pMstr, begin, end, incrFlag); - else - assertAlways(0); -} - -/*+/subr********************************************************************** -* NAME sydPlotSetAttr - set plot attributes -* -* DESCRIPTION -* Setting an attribute doesn't automatically reset other related -* attributes. -* -* sydPlotSetAttr(pMstr, SYD_PLATTR_FG1, 0, &fgPixVal) -* sydPlotSetAttr(pMstr, SYD_PLATTR_FG2, 0, &fgPixVal) -* sydPlotSetAttr(pMstr, SYD_PLATTR_INCR, 0, &stripIncr_sec) -* sydPlotSetAttr(pMstr, SYD_PLATTR_LINE, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_MARK, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_MONO, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_POINT, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_SHOW, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_STDDEV, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_UNDER, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_WRAP, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_XLAB, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_XANN, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_YLAB, {0,1}, NULL) -* sydPlotSetAttr(pMstr, SYD_PLATTR_YANN, {0,1}, NULL) -* -* RETURNS -* S_syd_OK -* -* BUGS -* o there should be a SYD_PLATTR_AXIS_TYPE, rather than having to -* explicitly set the .plotAxis member of the plot master structure -* -* SEE ALSO -* sydPlotSetTitles, sydPlotInit, sydPlotInitUW -* -* EXAMPLE -* -*-*/ -long -sydPlotSetAttr(pMstr, attr, value, pArg) -SYD_PL_MSTR *pMstr; /* I pointer to plot master structure */ -SYD_PLATTR attr; /* I attribute selector--one of SYD_PLATTR_xxx */ -int value; /* I value for attribute */ -void *pArg; /* I pointer for value for attribute */ -{ -#ifdef XWINDOWS - if (attr == SYD_PLATTR_FG1) pMstr->altPixel1 = *(unsigned long *)pArg; - else if (attr == SYD_PLATTR_FG2) pMstr->altPixel2 = *(unsigned long *)pArg; - else -#endif - if (attr == SYD_PLATTR_LINE) pMstr->linePlot = value; - else if (attr == SYD_PLATTR_MARK) pMstr->markPlot = value; - else if (attr == SYD_PLATTR_POINT) pMstr->pointPlot = value; - else if (attr == SYD_PLATTR_SHOW) pMstr->showStat = value; - else if (attr == SYD_PLATTR_UNDER) pMstr->fillUnder = value; - else if (attr == SYD_PLATTR_WRAP) pMstr->wrapX = value; - else if (attr == SYD_PLATTR_XLAB) pMstr->useXlabel = value; - else if (attr == SYD_PLATTR_XANN) pMstr->useXannot = value; - else if (attr == SYD_PLATTR_YLAB) pMstr->useYlabel = value; - else if (attr == SYD_PLATTR_YANN) pMstr->useYannot = value; - else if (attr == SYD_PLATTR_MONO) pMstr->noColor = value; - else if (attr == SYD_PLATTR_STDDEV) { - if (value == 1) - pMstr->errBar = SYD_PLATTR_STDDEV; - else - pMstr->errBar = 0; - } - else if (attr == SYD_PLATTR_INCR) pMstr->stripIncr = *(float *)pArg; - else assertAlways(0); - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydPlotSetTitles - establish or change titles for a plot -* -* DESCRIPTION -* Set the titles for a plot. -* -* By default, there are no titles for a plot. If the argument -* for a particular title isn't NULL, then that title is changed. -* -* RETURNS -* S_syd_OK -* -* BUGS -* o text -* -* SEE ALSO -* sydPlot_setup, sydPlotSetAttr -* -* EXAMPLE -* -*-*/ -long -sydPlotSetTitles(pMstr, top, left, bottom, right) -SYD_PL_MSTR *pMstr; /* I pointer to plot master structure */ -char *top; /* I title for top of plot, or NULL */ -char *left; /* I title for left of plot, or NULL */ -char *bottom; /* I title for bottom of plot, or NULL */ -char *right; /* I title for right of plot, or NULL */ -{ - if (top != NULL) { - assert(strlen(top) < sizeof(pMstr->title)); - strcpy(pMstr->title, top); - } - if (left != NULL) { - assert(strlen(left) < sizeof(pMstr->lTitle)); - strcpy(pMstr->lTitle, left); - } - if (bottom != NULL) { - assert(strlen(bottom) < sizeof(pMstr->bTitle)); - strcpy(pMstr->bTitle, bottom); - } - if (right != NULL) { - assert(strlen(right) < sizeof(pMstr->rTitle)); - strcpy(pMstr->rTitle, right); - } - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydPlotTimeCursor - plot a time `cursor' -* -* DESCRIPTION -* Draws or erases a vertical line corresponding to the specified -* time stamp. If a plot slave is specified, its annotation area -* is outlined (or the outline is erased). -* -* The drawing is done using the X GXxor function, so that the first -* call for a time stamp draws a line and the next call for the -* same time stamp erases the line. -* -* RETURNS -* S_syd_OK -* -* NOTES -* 1. Since alternate calls to this routine draw and erase, speciall -* handling is needed by the caller who wants to draw several time -* cursors and also outline the annotation area for a plot slave. -* For this case, the pointer to the plot slave should be used in only -* _one_ of the calls to this routine. -* -*-*/ -long -sydPlotTimeCursor(pMstr, pStamp, pSlave) -SYD_PL_MSTR *pMstr; /* I pointer to plot master structure */ -TS_STAMP *pStamp; /* I time stamp to position cursor */ -SYD_PL_SLAVE *pSlave; /* I pointer to plot slave structure, or NULL */ -{ - SYD_SPEC *pSspec = pMstr->pSspec; - double diff; /* offset of stamp from reference stamp */ - PPR_AREA *pArea; - - if (pMstr->plotAxis != SYD_PLAX_TY && pMstr->plotAxis != SYD_PLAX_TYY) - return S_syd_OK; - - TsDiffAsDouble(&diff, pStamp, &pSspec->restrictRefTs); - if (diff < pMstr->originVal || diff > pMstr->extentVal) - return S_syd_OK; - pArea = pprAreaOpen(pMstr->pWin, - pMstr->originFrac, 0., pMstr->extentFrac, 1., - pMstr->originVal, 0., pMstr->extentVal, 1., - 1, 1, 0.); - assertAlways(pArea != NULL); - XSetFunction(pArea->pWin->pDisp, pArea->attr.gc, GXinvert); - XSetPlaneMask(pArea->pWin->pDisp, pArea->attr.gc, 1); - pprLineSegD(pArea, diff, 0., diff, 1.); - pprAreaClose(pArea); - pArea = pprAreaOpen(pMstr->pWin, 0.,0.,1.,1., 0.,0.,1.,1., 1, 1, 0.); - assertAlways(pArea != NULL); - XSetFunction(pArea->pWin->pDisp, pArea->attr.gc, GXinvert); - XSetPlaneMask(pArea->pWin->pDisp, pArea->attr.gc, 1); - if (pSlave != NULL) { - double inX, inY; /* insets into the annot area */ - inX = (pSlave->annotXFR - pSlave->annotXFL) * .05; - inY = (pSlave->annotYFT - pSlave->annotYFB) * .05; - pprMoveD(pArea, pSlave->annotXFL+inX, pSlave->annotYFB+inY, 0); - pprMoveD(pArea, pSlave->annotXFL+inX, pSlave->annotYFT-inY, 1); - pprMoveD(pArea, pSlave->annotXFR-inX, pSlave->annotYFT-inY, 1); - pprMoveD(pArea, pSlave->annotXFR-inX, pSlave->annotYFB+inY, 1); - pprMoveD(pArea, pSlave->annotXFL+inX, pSlave->annotYFB+inY, 1); - } - pprAreaClose(pArea); - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydPlotWinLoop - do the actual plotting -* -* DESCRIPTION -* Perform the actual plotting for a plot master which was set up -* using sydPlotInit. -* -* This routine is for use only with sydPlotInit. When this routine -* is called, the sydPlot_xxx routine indicated by the .plotAxis -* member of the plot master structure is called. -* -* This routine creates and maps a window and draws the plot. This -* routine retains control (for processing expose and resize events) -* until the mouse pointer is placed in the plot window and the right -* button is clicked. -* -* RETURNS -* S_syd_OK -* -* BUGS -* o text -* -* SEE ALSO -* sydPlotInit, sydPlotSetAttr, sydPlot_xxx -* -* EXAMPLE -* -*-*/ -long -sydPlotWinLoop(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to plot master structure */ -{ - SYD_PLAX pltTy = pMstr->plotAxis; /* type of plot desired */ - long stat; - int npts, beg, end; - SYD_SPEC *pSspec = pMstr->pSspec; - - npts = pSspec->sampleCount; - beg = pSspec->restrictFirstData; - end = pSspec->restrictLastData; - if (npts <= 1 || pMstr->originVal == pMstr->extentVal) { - pMstr->originVal = 0.; - pMstr->extentVal = 100.; - strcpy(pMstr->label, "elapsed seconds"); - pMstr->nInt = 5; - } - - if (pprWinMap(pMstr->pWin) != 0) - return S_syd_ERROR; - if (pprWinIsMono(pMstr->pWin)) - pMstr->noColor = 1; - else - pMstr->noColor = 0; - stat = pprWinLoop(pMstr->pWin, sydPlot, pMstr); - if (stat != OK) - return S_syd_ERROR; - - pprWinInfo(pMstr->pWin, &pMstr->x, &pMstr->y,&pMstr->width,&pMstr->height); - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydPlotWinReplot - do the actual plotting -* -* DESCRIPTION -* Perform the actual plotting for a plot master which was set up -* using sydPlotInitUW. This routine calls the sydPlot_xxx routine -* indicated by the .plotAxis member of the plot master structure. -* -* RETURNS -* S_syd_OK -* -* BUGS -* o text -* -* SEE ALSO -* sydPlotInitUW, sydPlotSamples, sydPlot_xxx -* -* EXAMPLE -* -*-*/ -long -sydPlotWinReplot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to plot master structure */ -{ - int npts, beg, end; - SYD_SPEC *pSspec = pMstr->pSspec; - - npts = pSspec->sampleCount; - beg = pSspec->restrictFirstData; - end = pSspec->restrictLastData; - if (npts <= 1 || pMstr->originVal == pMstr->extentVal) { - pMstr->originVal = 0.; - pMstr->extentVal = 100.; - strcpy(pMstr->label, "elapsed seconds"); - pMstr->nInt = 5; - } - - pprWinErase(pMstr->pWin); - pprWinReplot(pMstr->pWin, sydPlot, pMstr); - - return S_syd_OK; -} - -/*+/subr********************************************************************** -* NAME sydPlot - call the plot routine appropriate for plot type -* -* DESCRIPTION -* Provides a generic interface for doing the actual plotting. This -* routine calls the specific plotting routine as dictated by the -* set up for the plot master. That routine will draw the grid(s) -* and plot the data. -* -* Prior to calling this routine, the caller must set several values -* in the plot master structure to control how plotting is done. Except -* for the .plotAxis member, the preferred method for setting the -* values is with the sydPlotSetAttr routine. -* -* .plotAxis--the type of axis used in plotting: -* SYD_PLAX_TY value vs time, separate grids -* SYD_PLAX_TYY value vs time, shared grid -* SYD_PLAX_XY value vs value, separate grids -* SYD_PLAX_XYY value vs value, shared grid -* SYD_PLAX_Y value vs bin number, separate grids -* SYD_PLAX_YY value vs bin number, shared grid -* SYD_PLAX_STRIP_Y value vs delta time, separate grids -* SYD_PLAX_STRIP_YY value vs delta time, shared grid -* SYD_PLAX_SMITH_IMP value vs value, with Smith impedance overlay -* SYD_PLAX_SMITH_ADM value vs value, with Smith admittance overlay -* SYD_PLAX_SMITH_IMM value vs value, with Smith immitance overlay -* -* .linePlot--1 to connect data points with lines, else 0 -* .markPlot--1 to plot a mark at each data point, else 0 -* .pointPlot--1 to plot a point at each data point, else 0 -* .showStat--1 to plot a status indicator at each data point, else 0 -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* sydPlotSetAttr, specific sydPlot_xxx routines -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot(pWin, pMstr) -PPR_WIN *pWin; /* I pointer to plot window structure */ -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - pprWinInfo(pWin, &pMstr->x, &pMstr->y, &pMstr->width, &pMstr->height); - if (pMstr->plotAxis == SYD_PLAX_TY) - sydPlot_TYPlot(pMstr); - else if (pMstr->plotAxis == SYD_PLAX_TYY) - sydPlot_TYYPlot(pMstr); - else if (pMstr->plotAxis == SYD_PLAX_XY) - sydPlot_XYPlot(pMstr); - else if (pMstr->plotAxis == SYD_PLAX_XYY) - sydPlot_XYYPlot(pMstr); - else if (pMstr->plotAxis == SYD_PLAX_Y) - sydPlot_YPlot(pMstr); - else if (pMstr->plotAxis == SYD_PLAX_YY) - sydPlot_YYPlot(pMstr); - else if (pMstr->plotAxis == SYD_PLAX_STRIP_Y) - sydPlot_StripYPlot(pMstr); - else if (pMstr->plotAxis == SYD_PLAX_STRIP_YY) - sydPlot_StripYYPlot(pMstr); - else if (pMstr->plotAxis == SYD_PLAX_SMITH_IMP || - pMstr->plotAxis == SYD_PLAX_SMITH_ADM || - pMstr->plotAxis == SYD_PLAX_SMITH_IMM) - sydPlot_SmithPlot(pMstr); - else - assertAlways(0); -} - -/*/macro----------------------------------------------------------------------- -* NAME FetchIthValInto - space saver for getting value as a double -* -*----------------------------------------------------------------------------*/ -#define FetchIthValInto(pSChan, dbl) \ - if (dbr_type_is_FLOAT(pSChan->dbrType)) \ - dbl = (double)((float *)pSChan->pData)[i]; \ - else if (dbr_type_is_SHORT(pSChan->dbrType)) { \ - if (pSChan->isRVAL) \ - dbl = (double)((unsigned short *)pSChan->pData)[i]; \ - else \ - dbl = (double)((short *)pSChan->pData)[i]; \ - } \ - else if (dbr_type_is_DOUBLE(pSChan->dbrType)) \ - dbl = (double)((double *)pSChan->pData)[i]; \ - else if (dbr_type_is_LONG(pSChan->dbrType)) { \ - if (pSChan->isRVAL) \ - dbl = (double)((unsigned long *)pSChan->pData)[i]; \ - else \ - dbl = (double)((long *)pSChan->pData)[i]; \ - } \ - else if (dbr_type_is_CHAR(pSChan->dbrType)) \ - dbl = (double)((char *)pSChan->pData)[i]; \ - else if (dbr_type_is_ENUM(pSChan->dbrType)) \ - dbl = (double)((short *)pSChan->pData)[i]; \ - else \ - assertAlways(0); -#if 0 - dbl = (double)((short *)pSChan->pData)[i]; -#endif - - -/*+/internal****************************************************************** -* NAME sydPlot_setup - set up titles and margins for a plot window -* -* DESCRIPTION -* Plots whatever titles are present in the plot master, reserving -* an appropriate margin when necessary. -* -* All slaves can be plotted in a shared grid, or separate grids -* can be used. This is controlled by the `nGrids' argument. -* -* This routine returns information to allow easily intermixing calls -* to the pprPlot routines with calls to sydPlot routines. -* -* If plotting is for PostScript, date and time are plotted in the -* upper right corner of the window. -* -* RETURNS -* void -* -* BUGS -* o handles only vertical subdividing of the plot window (i.e., into -* long horizontal strips) -* -*-*/ -static void -sydPlot_setup(pMstr, nGrids, pXlo,pYlo,pXhi,pYhi, pYpart, pCh,pChX,pChTY,pChTX) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int nGrids; /* I number of grids */ -double *pXlo; /* O pointer to X position of lower left corner of - first grid, as fraction of window width */ -double *pYlo; /* O pointer to Y position of lower left corner of - first grid, as fraction of window height */ -double *pXhi; /* O pointer to X position of upper right corner of - first grid, as fraction of window width */ -double *pYhi; /* O pointer to Y position of upper right corner of - first grid, as fraction of window height */ -double *pYpart; /* O pointer to fraction of window height occupied - by a single grid (all grids are equal) */ -double *pCh; /* O pointer to character height, as fraction - of window height */ -double *pChX; /* O pointer to character height for rotated text, - as fraction of window width */ -double *pChTY; /* O pointer to title character height, as fraction - of window height */ -double *pChTX; /* O pointer to title character height for rotated - text, as fraction of window width */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - double xlo, ylo, xhi, yhi, yPart, charHtTY, charHtTX, charHt, charHtX; - PPR_AREA *pArea; - TS_STAMP now; - char nowText[32]; - - pWin = pMstr->pWin; - xlo = 0.; - xhi = .98; - ylo = 0.; - yhi = .98; - charHtTY = .012; - charHtTX = pprYFracToXFrac(pWin, charHtTY); -/*----------------------------------------------------------------------------- -* initialize a plot area covering the whole window, with diagonal corners -* of 0,0 1,1 for plotting the titles -* -* for PostScript, plot current date and time -* plot the titles which aren't empty -*----------------------------------------------------------------------------*/ - pArea = pprAreaOpen(pWin, 0.,0., 1.,1., 0.,0., 1.,1., 1, 1, 0.); - assertAlways(pArea != NULL); - if (pMstr->winType == PPR_WIN_POSTSCRIPT) { - (void)tsLocalTime(&now); - (void)tsStampToText(&now, TS_TEXT_MONDDYYYY, nowText); - pprText(pArea, .98, .995, nowText, PPR_TXT_RJ, .008, 0.); - } - if (strlen(pMstr->title) > 0) { - yhi = 1. - charHtTY; - pprText(pArea, .5, yhi, pMstr->title, PPR_TXT_CEN, charHtTY, 0.); - yhi -= 2. * charHtTY; - } - if (strlen(pMstr->lTitle) > 0) { - xlo = 2. * charHtTX; - pprText(pArea, xlo, .5, pMstr->lTitle, PPR_TXT_CEN, charHtTX, 90.); - xlo += 2. * charHtTX; - } - if (strlen(pMstr->bTitle) > 0) { - ylo = 2. * charHtTY; - pprText(pArea, .5, ylo, pMstr->bTitle, PPR_TXT_CEN, charHtTY, 0.); - ylo += 2. * charHtTY; - } - if (strlen(pMstr->rTitle) > 0) { - xhi = 1. - 2. * charHtTX; - pprText(pArea, xhi, .5, pMstr->rTitle, PPR_TXT_CEN, charHtTX, 90.); - xhi -= 2. * charHtTX; - } - pprAreaClose(pArea); - - ylo += 4. * charHtTY; /* allow for x axis label and annotation */ - - yPart = (yhi - ylo)/(double)nGrids; - yhi = yPart + ylo; - charHt = PprDfltCharHt(ylo, yhi); - charHtX = pprYFracToXFrac(pWin, charHt); - - *pXlo = xlo; - *pXhi = xhi; - *pYlo = ylo; - *pYhi = yhi; - *pYpart = yPart; - *pCh = charHt; - *pChX = charHtX; - *pChTY = charHtTY; - *pChTX = charHtTX; -} - -/*----------------------------------------------------------------------------- -* structure for annotating time axis -*----------------------------------------------------------------------------*/ -static struct { - unsigned long threshold; /* seconds for start of partition */ - unsigned long modForEnds; /* rounding interval for axis ends */ - short firstForEnds; /* index in mm/dd/yy hh:mm:ss.msec */ - short nCharForEnds; /* # char from mm/dd/... for end label */ - unsigned long modForTicks; /* rounding interval for axis tick marks */ - short nSubInt; /* number of subintervals */ - short firstForTicks; /* index in mm/dd/yy hh:mm:ss.msec */ - short nCharForTicks; /* # char from mm/dd/... for tick label */ -} timeCal[]={ - 7*86400+1, 86400, 0, 5, 86400, 24, 0, 5, /* more than 7 days */ - 43201, 86400, 0, 5, 43200, 12, 9, 5, /* more than 12 hours */ - 3601, 3600, 9, 5, 3600, 6, 9, 5, /* more than 1 hour */ - 601, 600, 9, 5, 600, 10, 9, 5, /* more than 10 minutes */ - 61, 60, 12, 5, 60, 6, 12, 5, /* more than 60 seconds */ - 11, 10, 12, 5, 10, 10, 12, 5, /* more than 10 seconds */ - 0, 1, 15, 6, 1, 0, 15, 6 /* <= 10 seconds */ -}; -/*+/internal****************************************************************** -* NAME sydPlot_setupTime - handle time axis -* -*-*/ -sydPlot_setupTime(pMstr, pAnnot, annot) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -char *pAnnot[20], annot[20][28]; -{ - SYD_SPEC *pSspec = pMstr->pSspec; - unsigned long xminUL, xmaxUL, elapsedUL, xTickDeltaUL; - TS_STAMP stamp, refStamp, xminTs, xmaxTs, elapsedTs; - char xminText[28], xmaxText[28], stampText[28]; - int xNint; - double xtemp, xdelta, xmin, xmax, ymin, ymax; - int i, calNum; -/*----------------------------------------------------------------------------- -* get start and end times (as set by sydPlotInit) referenced to the -* restrictRefTs. Round them to something `sane' based on the total -* time range, then build the table of annotation labels. The rounding -* is based on local time, rather than UTC. -*----------------------------------------------------------------------------*/ - if (pSspec->restrictRefTs.secPastEpoch > 0) { - tsAddDouble(&xminTs, &pSspec->restrictRefTs, pMstr->originVal); - xminTs.nsec = 0; - tsAddDouble(&xmaxTs, &pSspec->restrictRefTs, pMstr->extentVal); - if (xmaxTs.nsec > 0) { - xmaxTs.secPastEpoch++; - xmaxTs.nsec = 0; - } - TsDiffAsStamp(&elapsedTs, &xmaxTs, &xminTs); - for (calNum=0; ; calNum++) { - if (timeCal[calNum].threshold <= elapsedTs.secPastEpoch) - break; - } - tsRoundDownLocal(&xminTs, timeCal[calNum].modForEnds); - tsRoundUpLocal(&xmaxTs, timeCal[calNum].modForEnds); - - if (xminTs.secPastEpoch == xmaxTs.secPastEpoch) - xmaxTs.secPastEpoch += timeCal[calNum].modForEnds; - refStamp = xminTs; - - xminUL = xminTs.secPastEpoch; - xmaxUL = xmaxTs.secPastEpoch; - elapsedUL = xmaxUL - xminUL; - xTickDeltaUL = timeCal[calNum].modForTicks; - xNint = (xmaxUL - xminUL) / xTickDeltaUL; - if (xNint >= 20) { - xNint = 5; - xTickDeltaUL = elapsedUL / xNint; - } - pMstr->nInt = xNint; - pMstr->nSubInt = timeCal[calNum].nSubInt; - for (i=0; i<=xNint; i++) { - tsStampToText(&refStamp, TS_TEXT_MMDDYY, stampText); - if (i == 0 || i == xNint) { - strcpy(annot[i], &stampText[timeCal[calNum].firstForEnds]); - annot[i][timeCal[calNum].nCharForEnds] = '\0'; - if (i == 0) - TsDiffAsDouble(&xmin, &refStamp, &pSspec->restrictRefTs); - else - TsDiffAsDouble(&xmax, &refStamp, &pSspec->restrictRefTs); - } - else { - strcpy(annot[i], &stampText[timeCal[calNum].firstForTicks]); - annot[i][timeCal[calNum].nCharForTicks] = '\0'; - } - pAnnot[i] = annot[i]; - refStamp.secPastEpoch += xTickDeltaUL; - } - - (void)tsStampToText(&xminTs, TS_TEXT_MMDDYY, xminText); - (void)tsStampToText(&xmaxTs, TS_TEXT_MMDDYY, xmaxText); - (void)sprintf(pMstr->label, "%s to %s", xminText, xmaxText); - } - else { - xmin = pMstr->originVal; - xmax = pMstr->extentVal; - if (xmin == xmax) - xmax += 10.; - pprAutoEnds(xmin, xmax, &xmin, &xmax); - pprAutoInterval(xmin, xmax, &xNint); - if (xNint > 19) - xNint = 19; - xdelta = (xmax - xmin) / xNint; - for (i=0, xtemp=xmin; i<=xNint; i++,xtemp+=xdelta) { - if (i == xNint) - xtemp=xmax; - pprCvtDblToTxt(annot[i], 8, xtemp, 2); - pAnnot[i] = annot[i]; - } - (void)sprintf(pMstr->label, "delta seconds"); - } - pMstr->originVal = xmin; - pMstr->extentVal = xmax; - pMstr->nInt = xNint; -} - -/*+/subr********************************************************************** -* NAME sydPlot_SmithPlot - handle Smith Chart plots -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* sydPlot_SmithGrid, sydPlot_SmithSamples -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_SmithPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_SmithGrid(pMstr); - if (pSspec->useStats == 0) { - sydPlot_SmithSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); - } - else - sydPlot_SmithStats(pMstr, 0, pSspec->statCount-1); -} - -/*+/subr********************************************************************** -* NAME sydPlot_SmithGrid - draw a Smith chart overlay -* -* DESCRIPTION -* Draws a Smith chart overlay, to be used in plotting X vs Y data. -* Three overlays are available, with axis type controlling which is -* drawn: -* -* SYD_PLAX_SMITH_IMP results in an impedance overlay, with -* circles tangent on the right. If SYD_PLATTR_FG1 has been -* used to set an alternate foreground pixel value, then, on -* color displays, the overlay is drawn using that pixel value. -* SYD_PLAX_SMITH_ADM results in an admittance overlay, with -* circles tangent on the left. If SYD_PLATTR_FG2 has been -* used to set an alternate foreground pixel value, then, on -* color displays, the overlay is drawn using that pixel value. -* SYD_PLAX_SMITH_IMM results in an "immittance" overlay, which is -* a combination of the impedance overlay on top of the -* admittance overlay. On color displays when alternate -* foreground pixel values have been specified, the overlays -* are drawn as described above. On monochrome displays, or -* when no alternate foreground pixel values are specified, -* the impedance overlay is drawn with a solid line and the -* admittance overlay is drawn with a dashed line. -* -* On color displays, if no alternate foreground pixel values have been -* set, then the overlays are drawn using the color of the plot window. -* -* RETURNS -* void -* -* BUGS -* o channel names aren't displayed -* o colors are done only under X11 -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -*-*/ -void -sydPlot_SmithGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; - PPR_AREA *pArea; - double incr=5.; /* use 5 degree increments */ - double x, y, rad; - int r; - static char *xTxt[]={"5","2","1","0.5","0.2","0"}; - double xlo, ylo, xhi, yhi; - double xmin, ymin, xmax, ymax; - double yPart; - double charHt, charHtX, charHtTY, charHtTX; - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - SYD_PL_SLAVE *pSlaveX; /* pointer to X axis slave struct */ - - pWin = pMstr->pWin; - - sydPlot_setup(pMstr, 1, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - - xlo += 3. * charHtX; - ylo += 2. * charHt; - xhi -= charHt; - yhi -= 2. * charHt; - - pSlaveX = pMstr->pHead; - while (1) { - if (pSlaveX->xChan) - break; - pSlaveX = pSlaveX->pNext; - if (pSlaveX == NULL) { - pSlaveX = pMstr->pHead; - break; - } - } - if (pSlaveX == pMstr->pHead) - pSlave = pSlaveX->pNext; - else - pSlave = pMstr->pHead; - - pArea = pprAreaOpen(pWin, xlo,ylo, xhi,yhi, 0.,0., 1.,1., 1, 1, 0.); - - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM || - pMstr->plotAxis == SYD_PLAX_SMITH_IMM) { -/*----------------------------------------------------------------------------- -* admittance overlay, with circles tangent at x=0,y=.5 -* -* For immitance plots, with this as a secondary overlay, a dashed -* line pattern is used if the screen is monochrome. The outer -* circle isn't drawn and annotations aren't drawn. -*----------------------------------------------------------------------------*/ -#ifdef XWINDOWS - if (pMstr->noColor == 0 && pMstr->altPixel2 != 0) - pprAreaSetAttr(pArea, PPR_ATTR_FG, 0, &pMstr->altPixel2); - else { -#else - if (1) { -#endif - if (pMstr->plotAxis == SYD_PLAX_SMITH_IMM || pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, 1, NULL); - } - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprLineSegD(pArea, 0.,.5, 1.,.5); - y = .5; - for (r=6; r>0; r--) { - rad = (double)r / 12.; - x = rad; - if (r != 6 || pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprArcD(pArea, x, y, rad, 0., 360., incr); - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprText(pArea, x+rad+.015, y, xTxt[r-1], PPR_TXT_LJ, 0., 0.); - } - x = 0.; - rad = .25, y = .5 + rad; - pprArcD(pArea, x, y, rad, 270., 37., incr); - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprText(pArea, .19, .92, "2", PPR_TXT_RJ, 0., 0.); - y = .5 - rad; - pprArcD(pArea, x, y, rad, 323., 90., incr); - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprText(pArea, .19, .08, "2", PPR_TXT_RJ, 0., 0.); - rad = .5, y = .5 + rad; - pprArcD(pArea, x, y, rad, 270., 0., incr); - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprText(pArea, .5, 1.02, "1", PPR_TXT_CEN, 0., 0.); - y = .5 - rad; - pprArcD(pArea, x, y, rad, 0., 90., incr); - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprText(pArea, .5, -.02, "1", PPR_TXT_CEN, 0., 0.); - rad = 1., y = .5 + rad; - pprArcD(pArea, x, y, rad, 270., 323., incr); - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprText(pArea, .81, .92, "0.5", PPR_TXT_LJ, 0., 0.); - y = .5 - rad; - pprArcD(pArea, x, y, rad, 37., 90., incr); - if (pMstr->plotAxis == SYD_PLAX_SMITH_ADM) - pprText(pArea, .81, .08, "0.5", PPR_TXT_LJ, 0., 0.); - } - if (pMstr->plotAxis == SYD_PLAX_SMITH_IMP || - pMstr->plotAxis == SYD_PLAX_SMITH_IMM) { -/*----------------------------------------------------------------------------- -* impedance overlay, with circles tangent at x=1,y=.5 -*----------------------------------------------------------------------------*/ -#ifdef XWINDOWS - if (pMstr->noColor == 0 && pMstr->altPixel1 != 0) - pprAreaSetAttr(pArea, PPR_ATTR_FG, 0, &pMstr->altPixel1); - else { -#else - if (1) { -#endif - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, 0, NULL); - } - pprLineSegD(pArea, 0.,.5, 1.,.5); - y = .5; - for (r=6; r>0; r--) { - rad = (double)r / 12.; - x = 1. - rad; - pprArcD(pArea, x, y, rad, 0., 360., incr); - pprText(pArea, x-rad-.015, y, xTxt[r-1], PPR_TXT_RJ, 0., 0.); - } - x = 1.; - rad = .25, y = .5 + rad; - pprArcD(pArea, x, y, rad, 143., 270., incr); - pprText(pArea, .81, .92, "2", PPR_TXT_LJ, 0., 0.); - y = .5 - rad; - pprArcD(pArea, x, y, rad, 90., 217., incr); - pprText(pArea, .81, .08, "2", PPR_TXT_LJ, 0., 0.); - rad = .5, y = .5 + rad; - pprArcD(pArea, x, y, rad, 180., 270., incr); - pprText(pArea, .5, 1.02, "1", PPR_TXT_CEN, 0., 0.); - y = .5 - rad; - pprArcD(pArea, x, y, rad, 90., 180., incr); - pprText(pArea, .5, -.02, "1", PPR_TXT_CEN, 0., 0.); - rad = 1., y = .5 + rad; - pprArcD(pArea, x, y, rad, 217., 270., incr); - pprText(pArea, .19, .92, "0.5", PPR_TXT_RJ, 0., 0.); - y = .5 - rad; - pprArcD(pArea, x, y, rad, 90., 143., incr); - pprText(pArea, .19, .08, "0.5", PPR_TXT_RJ, 0., 0.); - } - pprAreaClose(pArea); - - pSlaveX->pArea = NULL; - xmin = pSlaveX->originVal; - xmax = pSlaveX->extentVal; - while (pSlave != NULL) { - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, - xlo,ylo, xhi,yhi, xmin, ymin, xmax, ymax, 1, 1, 0.); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo + 12. * charHtX; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo + 6. * charHt; - pSlave->yFracTop = yhi; - pSlave->annotXFL = xlo; - pSlave->annotXFR = pSlave->xFracLeft; - pSlave->annotYFB = pSlave->yFracBot; - pSlave->annotYFT = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - pSlave = pSlave->pNext; - if (pSlave == pSlaveX) - pSlave = pSlave->pNext; - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_SmithSamples - plot one or more samples for a Smith Chart plot -* -* DESCRIPTION -* the first channel in the plot spec is used for the X axis -* -* RETURNS -* void -* -* BUGS -* o this isn't a true Smith chart plot--the caller must have transformed -* the data into simple X vs Y data -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_SmithSamples(pMstr, begin, end, incr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin sample to plot */ -int end; /* I number of end sample to plot */ -int incr; /* I 0,1 for batch,incremental plotting */ -{ - sydPlot_XYSamples(pMstr, begin, end, incr); -} - -/*+/subr********************************************************************** -* NAME sydPlot_SmithStats - plot one or more snapshots for a Smith Chart plot -* -* DESCRIPTION -* the first channel in the plot spec is used for the X axis -* -* RETURNS -* void -* -* BUGS -* o this isn't a true Smith chart plot--the caller must have transformed -* the data into simple X vs Y data -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_SmithStats(pMstr, begin, end) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin snapshot to plot */ -int end; /* I number of end snapshot to plot */ -{ - sydPlot_XYStats(pMstr, begin, end); -} - -/*+/subr********************************************************************** -* NAME sydPlot_StripYPlot - handle strip chart, Y plots -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_StripYPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_StripYGrid(pMstr); - sydPlot_StripYSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); -} - -/*+/subr********************************************************************** -* NAME sydPlot_StripYGrid - draw a grid for a strip chart, Y plot -* -* DESCRIPTION -* -* RETURNS -* void -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_StripYGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - double xlo, ylo, xhi, yhi; - double yPart; - PPR_AREA *pArea; - double xmin, xmax, ymin, ymax; - char **ppAnnotVal, *pAnnotVal[20], annotVal[20][28]; - double charHt, charHtX, charHtTY, charHtTX; - SYD_SPEC *pSspec = pMstr->pSspec; - SYD_CHAN *pSChan; - int thick=3; - int nGrids; - int i; - - pWin = pMstr->pWin; - - nGrids = pMstr->nSlaves; - sydPlot_setup(pMstr, nGrids, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - if (pMstr->pSspec->sampleCount > 0) { - xmax = pMstr->pSspec->pDeltaSec[pMstr->pSspec->lastData]; - xmin = xmax - pMstr->stripIncr * pMstr->pSspec->reqCount; - } - else if (pMstr->winType == PPR_WIN_SCREEN) { - xmin = -1. * (pMstr->stripIncr * pMstr->pSspec->reqCount); - xmax = 0.; - } - else { - xmin = 0.; - xmax = pMstr->stripIncr * pMstr->pSspec->reqCount; - } - - pSlave = pMstr->pHead; - while (pSlave != NULL) { -/*----------------------------------------------------------------------------- -* for each channel, initialize a plot area. -* -* plot a perimeter with grid lines -*----------------------------------------------------------------------------*/ - pSChan = pSlave->pSChan; - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - if (pSlave->ppAnnot == NULL) { - sydAnnotVal(pSlave, pAnnotVal, annotVal); - ppAnnotVal = pAnnotVal; - } - else - ppAnnotVal = pSlave->ppAnnot; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, - xlo+12.*charHtX, ylo+2.*charHt, xhi, yhi, - xmin, ymin, xmax, ymax, 1, pSlave->nInt, charHt); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo + 12. * charHtX; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo + 2.*charHt; - pSlave->yFracTop = yhi; - pSlave->annotXFL = xlo; - pSlave->annotXFR = pSlave->xFracLeft; - pSlave->annotYFB = pSlave->yFracBot; - pSlave->annotYFT = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - else if (pMstr->linePlot) { - if (dbr_type_is_ENUM(pSChan->dbrType)) - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - } - pprAnnotY(pArea, 0, ymin, ymax, pSlave->nInt, 0, - pSlave->pSChan->label, ppAnnotVal, 0.); - if (pSlave == pMstr->pHead) { - pArea->charHt = charHtTY * pWin->height; - pprAnnotX(pArea, 0, xmin, xmax, 1, 0, "delta seconds", NULL, 0.); - pArea->charHt = charHt * pWin->height; - } - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_STRIP, 1, NULL); - pprGrid(pArea); - ylo += yPart; - yhi += yPart; - pSlave = pSlave->pNext; - } - pSlave = pMstr->pHead; - pMstr->originFrac = pSlave->xFracLeft; - pMstr->extentFrac = pSlave->xFracRight; - -} - -/*+/subr********************************************************************** -* NAME sydPlot_StripYSamples - plot samples for a strip chart, Y plot -* -* DESCRIPTION -* -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_StripYSamples(pMstr, begin, end, incr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin sample to plot */ -int end; /* I number of end sample to plot */ -int incr; /* I 0,1 for batch,incremental plotting */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - PPR_AREA *pArea; - int i, j; - SYD_SPEC *pSspec; - SYD_CHAN *pSChan; - double oldX, oldY, newX, newY; - int skip; - int showStat; /* 1 to show status code on plot */ - int pointPlot; /* 1 for point plot */ - int linePlot; /* 1 to connect points with lines */ - int markPlot; /* 1 to draw marks at points */ - int markNum; /* number of mark to use */ - int nEl; /* number of array elements */ - int first; /* ==1 if this is the first sample */ - float shift; /* amount to shift the strip chart(s) */ - int pixEnd; /* pixel coordinate for end time */ - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - pWin = pMstr->pWin; - - linePlot = pMstr->linePlot; - pointPlot = pMstr->pointPlot; - markPlot = pMstr->markPlot; - showStat = pMstr->showStat; - - pArea = pMstr->pHead->pArea; - pixEnd = pArea->xPixRight + - .5 + (pSspec->pDeltaSec[end] - pArea->xRight) * pArea->xScale; - if (pixEnd >= pArea->xPixRight) { - shift = pSspec->pDeltaSec[end] - pMstr->pHead->pArea->xRight; - if (shift < pMstr->stripIncr) - shift = pMstr->stripIncr; - } - else - shift = 0.; - pSlave = pMstr->pHead; - while (pSlave != NULL) { - pArea = pSlave->pArea; - pSChan = pSlave->pSChan; - markNum = pSlave->markNum; - - if (pSChan->pData == NULL || pSChan->dataChan == 0) - ; /* no action if never connected or not data channel */ - else { - if (shift > 0.) { - pprAreaShiftLeft(pArea, shift); - if (pArea == pMstr->pHead->pArea) { - pMstr->originVal = pArea->xLeft; - pMstr->extentVal = pArea->xRight; - } - } - - nEl = pSChan->elCount; - - i = begin; - if (!incr) - first = 1; - else { - first = pSlave->first; - oldX = pSlave->oldX; - oldY = pSlave->oldY; - skip = pSlave->skip; - } - while (i >= 0) { - int restart, restart1; - restart = restart1 = 0; - if (pSChan->pFlags[i].restart) { - if (!pSChan->pFlags[i].snapstart) - restart = 1; - else if (!pSChan->pFlags[i].snapend) - restart = 1; - } - if (i != end && pSChan->pFlags[i+1].restart) { - if (!pSChan->pFlags[i+1].snapstart) - restart1 = 1; - else if (!pSChan->pFlags[i+1].snapend) - restart1 = 1; - } - if (pSChan->pFlags[i].missing) - skip = 1; - else if (first || skip || restart) { - oldX = pSspec->pDeltaSec[i] - - pMstr->pSspec->restrictDeltaSecSubtract; - if (oldX >= pArea->xLeft) { - FetchIthValInto(pSChan, oldY) - if (markPlot) - pprMarkD(pArea, oldX, oldY, markNum); - if (showStat && pSChan->pDataCodeR[i] != ' ') { - pprChar(pArea, oldX, oldY, - pSChan->pDataCodeR[i], 0., 0.); - } - else if (pointPlot) - pprPointD(pArea, oldX, oldY); - skip = 0; - } - } - else if (pSChan->pFlags[i].filled && restart1 == 0 && i != end) - ; /* no action */ - else { - newX = pSspec->pDeltaSec[i] - - pMstr->pSspec->restrictDeltaSecSubtract; - if (linePlot && dbr_type_is_ENUM(pSChan->dbrType)) { - if (oldX >= pArea->xLeft) - pprLineSegD(pArea, oldX, oldY, newX, oldY); - oldX = newX; - } - FetchIthValInto(pSChan, newY) - if (oldX >= pArea->xLeft) { - if (linePlot) - pprLineSegD(pArea, oldX, oldY, newX, newY); - if (markPlot) - pprMarkD(pArea, newX, newY, markNum); - if (showStat && pSChan->pDataCodeR[i] != ' ') { - pprChar(pArea, newX, newY, - pSChan->pDataCodeR[i], 0., 0.); - } - else if (pointPlot) - pprPointD(pArea, newX, newY); - } - oldX = newX; - oldY = newY; - } - if (i == end) - i = -1; - else if (++i >= pSspec->dataDim) - i = 0; - first = 0; - } - } - pSlave->first = first; - pSlave->oldX = oldX; - pSlave->oldY = oldY; - pSlave->skip = skip; - pSlave = pSlave->pNext; - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_StripYYPlot - handle strip chart, multiple Y plots -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o labeling of x axis is un-esthetic. It should be time based, with -* some intelligent adaptation, based on time interval for X -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_StripYYPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_StripYYGrid(pMstr); - sydPlot_StripYSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); -} - -/*+/subr********************************************************************** -* NAME sydPlot_StripYYGrid - draw a grid for a strip chart, multiple Y plot -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_StripYYGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - double xlo, ylo, xhi, yhi; - double yPart; - PPR_AREA *pArea; - double xmin, xmax, ymin, ymax; - double charHt, charHtX, charHtTY, charHtTX; - char **ppAnnotVal, *pAnnotVal[20], annotVal[20][28]; - SYD_SPEC *pSspec = pMstr->pSspec; - SYD_CHAN *pSChan; - int thick=3; - int nGrids; - int i, calNum; - int offsetAnnotY=0; - int drawAxis=0; - - pWin = pMstr->pWin; - - nGrids = 1; - sydPlot_setup(pMstr, nGrids, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - if (pMstr->pSspec->sampleCount > 0) { - xmax = pMstr->pSspec->pDeltaSec[pMstr->pSspec->lastData]; - xmin = xmax - pMstr->stripIncr * pMstr->pSspec->reqCount; - } - else if (pMstr->winType == PPR_WIN_SCREEN) { - xmin = -1. * (pMstr->stripIncr * pMstr->pSspec->reqCount); - xmax = 0.; - } - else { - xmin = 0.; - xmax = pMstr->stripIncr * pMstr->pSspec->reqCount; - } - - xlo += 6. * charHtX * (double)pMstr->nSlaves; - - pSlave = pMstr->pHead; - while (pSlave != NULL) { -/*----------------------------------------------------------------------------- -* for the first channel: -* initialize a plot area; its fractional size depends on how many -* "sub-plots" there are -* plot a perimeter with grid lines -* for the other channels: -* initialize an overlapping plot area -* set a dashed line pattern (unless this is a mark or point plot) -* draw a "floating" Y axis -*----------------------------------------------------------------------------*/ - pSChan = pSlave->pSChan; - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - if (pSlave->ppAnnot == NULL) { - sydAnnotVal(pSlave, pAnnotVal, annotVal); - ppAnnotVal = pAnnotVal; - } - else - ppAnnotVal = pSlave->ppAnnot; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, xlo, ylo+2.*charHt, xhi, yhi, - xmin, ymin, xmax, ymax, pMstr->nInt, pSlave->nInt, charHt); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo; - pSlave->yFracTop = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - else if (pMstr->linePlot) { - if (dbr_type_is_ENUM(pSChan->dbrType)) - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - if (pSlave->lineKey > 1 || pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, pSlave->lineKey, NULL); - } - else if (pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_COLORNUM, pSlave->lineKey, NULL); - pprAnnotY(pArea, offsetAnnotY, pSlave->originVal, pSlave->extentVal, - pSlave->nInt, drawAxis, - pSlave->pSChan->label, ppAnnotVal, 90.); - if (drawAxis == 0) { - if (pSlave == pMstr->pHead) { - pArea->charHt = charHtTY * pWin->height; - pprAnnotX(pArea, 0, xmin,xmax,1,0,"delta seconds",NULL,0.); - pArea->charHt = charHt * pWin->height; - } - pprAreaSetAttr(pArea, PPR_ATTR_STRIP, 1, NULL); - pprGrid(pArea); - } - else - pprAreaSetAttr(pArea, PPR_ATTR_STRIP, 1, pMstr->pHead->pArea); - if (pMstr->markPlot) - pprAnnotYMark(pArea, offsetAnnotY, pSlave->markNum); - offsetAnnotY += 6; - drawAxis = 1; /* draw an "auxiliary" axis next time */ - pSlave->annotXFL = xlo - offsetAnnotY * charHtX; - pSlave->annotXFR = pSlave->annotXFL + 6. * charHtX; - pSlave->annotYFB = ylo; - pSlave->annotYFT = yhi; - pSlave = pSlave->pNext; - } - pSlave = pMstr->pHead; - pMstr->originFrac = pSlave->xFracLeft; - pMstr->extentFrac = pSlave->xFracRight; -} - -/*+/subr********************************************************************** -* NAME sydPlot_TYPlot - handle time vs Y plots -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_TYPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_TYGrid(pMstr); - if (pSspec->useStats == 0) { - sydPlot_TYSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); - } - else - sydPlot_TYStats(pMstr, 0, pSspec->statCount-1); -} - -/*+/subr********************************************************************** -* NAME sydPlot_TYGrid - draw a grid for a time vs Y plot -* -* DESCRIPTION -* -* RETURNS -* void -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_TYGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - double xlo, ylo, xhi, yhi; - double yPart; - PPR_AREA *pArea; - double xmin, xmax, ymin, ymax; - char *pAnnot[20], annot[20][28]; /* annot for time axis */ - char **ppAnnotVal, *pAnnotVal[20], annotVal[20][28]; - double charHt, charHtX, charHtTY, charHtTX; - SYD_SPEC *pSspec = pMstr->pSspec; - SYD_CHAN *pSChan; - int thick=3; - int nGrids; - int i; - - pWin = pMstr->pWin; - - nGrids = pMstr->nSlaves; - sydPlot_setup(pMstr, nGrids, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - sydPlot_setupTime(pMstr, pAnnot, annot); - xmin = pMstr->originVal; - xmax = pMstr->extentVal; - - pSlave = pMstr->pHead; - while (pSlave != NULL) { -/*----------------------------------------------------------------------------- -* for each channel, initialize a plot area. -* -* plot a perimeter with grid lines -*----------------------------------------------------------------------------*/ - pSChan = pSlave->pSChan; - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - if (pSlave->ppAnnot == NULL) { - sydAnnotVal(pSlave, pAnnotVal, annotVal); - ppAnnotVal = pAnnotVal; - } - else - ppAnnotVal = pSlave->ppAnnot; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, - xlo+12.*charHtX, ylo+2.*charHt, xhi, yhi, - xmin, ymin, xmax, ymax, pMstr->nInt, pSlave->nInt, charHt); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo + 12. * charHtX; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo + 2.*charHt; - pSlave->yFracTop = yhi; - pSlave->annotXFL = xlo; - pSlave->annotXFR = pSlave->xFracLeft; - pSlave->annotYFB = pSlave->yFracBot; - pSlave->annotYFT = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - else if (pMstr->linePlot) { - if (dbr_type_is_ENUM(pSChan->dbrType)) - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - } - pprGrid(pArea); - pprAnnotY(pArea, 0, ymin, ymax, pSlave->nInt, 0, - pSlave->pSChan->label, ppAnnotVal, 0.); - if (pSlave == pMstr->pHead) { - pArea->charHt = charHtTY * pWin->height; - pArea->xNsubint = pMstr->nSubInt; - pprAnnotX(pArea, 0, xmin, xmax, pMstr->nInt, 0, - pMstr->label, pAnnot, 0.); - pArea->charHt = charHt * pWin->height; - } - ylo += yPart; - yhi += yPart; - pSlave = pSlave->pNext; - } - pSlave = pMstr->pHead; - pMstr->originFrac = pSlave->xFracLeft; - pMstr->extentFrac = pSlave->xFracRight; - -} - -/*+/subr********************************************************************** -* NAME sydPlot_TYSamples - plot one or more samples for a time vs Y plot -* -* DESCRIPTION -* -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_TYSamples(pMstr, begin, end, incr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin sample to plot */ -int end; /* I number of end sample to plot */ -int incr; /* I 0,1 for batch,incremental plotting */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - PPR_AREA *pArea; - int i, j; - SYD_SPEC *pSspec; - SYD_CHAN *pSChan; - double oldX, oldY, newX, newY; - int skip; - int showStat; /* 1 to show status code on plot */ - int pointPlot; /* 1 for point plot */ - int linePlot; /* 1 to connect points with lines */ - int markPlot; /* 1 to draw marks at points */ - int markNum; /* number of mark to use */ - int nEl; /* number of array elements */ - int first; /* ==1 if this is the first sample */ - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - pWin = pMstr->pWin; - - linePlot = pMstr->linePlot; - pointPlot = pMstr->pointPlot; - markPlot = pMstr->markPlot; - showStat = pMstr->showStat; - - pSlave = pMstr->pHead; - while (pSlave != NULL) { - pArea = pSlave->pArea; - pSChan = pSlave->pSChan; - markNum = pSlave->markNum; - - if (pSChan->pData == NULL || pSChan->dataChan == 0) - ; /* no action if never connected or not data channel */ - else { - nEl = pSChan->elCount; - - i = begin; - if (!incr) - first = 1; - else { - first = pSlave->first; - oldX = pSlave->oldX; - oldY = pSlave->oldY; - skip = pSlave->skip; - } - while (i >= 0) { - int restart, restart1; - restart = restart1 = 0; - if (pSChan->pFlags[i].restart) { - if (!pSChan->pFlags[i].snapstart) - restart = 1; - else if (!pSChan->pFlags[i].snapend) - restart = 1; - } - if (i != end && pSChan->pFlags[i+1].restart) { - if (!pSChan->pFlags[i+1].snapstart) - restart1 = 1; - else if (!pSChan->pFlags[i+1].snapend) - restart1 = 1; - } - if (pSChan->pFlags[i].missing) - skip = 1; - else if (first || skip || restart) { - oldX = pSspec->pDeltaSec[i] - - pMstr->pSspec->restrictDeltaSecSubtract; - if (pMstr->wrapX) { - while (oldX > pMstr->extentVal) - oldX -= pMstr->extentVal; - } - FetchIthValInto(pSChan, oldY) - if (markPlot) - pprMarkD(pArea, oldX, oldY, markNum); - if (showStat && pSChan->pDataCodeR[i] != ' ') { - pprChar(pArea, oldX,oldY, pSChan->pDataCodeR[i],0.,0.); - } - else if (pointPlot) - pprPointD(pArea, oldX, oldY); - skip = 0; - } - else if (pSChan->pFlags[i].filled && restart1 == 0 && i != end) - ; /* no action */ - else { - newX = pSspec->pDeltaSec[i] - - pMstr->pSspec->restrictDeltaSecSubtract; - if (pMstr->wrapX) { - while (newX > pMstr->extentVal) - newX -= pMstr->extentVal; - } - if (linePlot && dbr_type_is_ENUM(pSChan->dbrType)) { - pprLineSegD(pArea, oldX, oldY, newX, oldY); - oldX = newX; - } - FetchIthValInto(pSChan, newY) - if (linePlot) - pprLineSegD(pArea, oldX, oldY, newX, newY); - if (markPlot) - pprMarkD(pArea, newX, newY, markNum); - if (showStat && pSChan->pDataCodeR[i] != ' ') { - pprChar(pArea, newX,newY, pSChan->pDataCodeR[i],0.,0.); - } - else if (pointPlot) - pprPointD(pArea, newX, newY); - oldX = newX; - oldY = newY; - } - if (i == end) - i = -1; - else if (++i >= pSspec->dataDim) - i = 0; - first = 0; - } - } - pSlave->first = first; - pSlave->oldX = oldX; - pSlave->oldY = oldY; - pSlave->skip = skip; - pSlave = pSlave->pNext; - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_TYStats - plot one or more snapshots for a time vs Y plot -* -* DESCRIPTION -* -* -* RETURNS -* void -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -*-*/ -void -sydPlot_TYStats(pMstr, begin, end) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin snapshot to plot */ -int end; /* I number of end snapshot to plot */ -{ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - PPR_AREA *pArea; - int i; - SYD_SPEC *pSspec; - SYD_CHAN *pSChan; - double oldX, oldY, newX, newY, err; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - for (pSlave=pMstr->pHead; pSlave!=NULL; pSlave=pSlave->pNext) { - pArea = pSlave->pArea; - pSChan = pSlave->pSChan; - for (i=begin; i<=end; i++) { - if (i == begin) { - oldX = pSspec->pStatDeltaSec[i] - - pMstr->pSspec->restrictDeltaSecSubtract; - if (pMstr->wrapX) { - while (oldX > pMstr->extentVal) - oldX -= pMstr->extentVal; - } - oldY = pSChan->pStats[i].mean; - } - else { - newX = pSspec->pStatDeltaSec[i] - - pMstr->pSspec->restrictDeltaSecSubtract; - if (pMstr->wrapX) { - while (newX > pMstr->extentVal) - newX -= pMstr->extentVal; - } - newY = pSChan->pStats[i].mean; - if (pMstr->linePlot) - pprLineSegD(pArea, oldX, oldY, newX, newY); - oldX = newX; - oldY = newY; - } - if (pMstr->markPlot) - pprMarkD(pArea, oldX, oldY, pSlave->markNum); - else - pprPointD(pArea, oldX, oldY); - if (pMstr->errBar == SYD_PLATTR_STDDEV) { - err = pSChan->pStats[i].stdDev; - pprErrorBar(pArea, oldX, oldY-err, oldX, oldY+err); - } - } - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_TYYPlot - handle time vs multiple Y plots -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o labeling of x axis is un-esthetic. It should be time based, with -* some intelligent adaptation, based on time interval for X -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_TYYPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_TYYGrid(pMstr); - if (pSspec->useStats == 0) { - sydPlot_TYSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); - } - else - sydPlot_TYStats(pMstr, 0, pSspec->statCount-1); -} - -/*+/subr********************************************************************** -* NAME sydPlot_TYYGrid - draw a grid for a time vs multiple Y plot -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_TYYGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - double xlo, ylo, xhi, yhi; - double yPart; - PPR_AREA *pArea; - double xmin, xmax, ymin, ymax; - char *pAnnot[20], annot[20][28]; /* annot for time axis */ - double charHt, charHtX, charHtTY, charHtTX; - SYD_SPEC *pSspec = pMstr->pSspec; - SYD_CHAN *pSChan; - int thick=3; - int nGrids; - int i, calNum; - int offsetAnnotY=0; - int drawAxis=0; - char **ppAnnotVal, *pAnnotVal[20], annotVal[20][28]; - - pWin = pMstr->pWin; - - nGrids = 1; - sydPlot_setup(pMstr, nGrids, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - sydPlot_setupTime(pMstr, pAnnot, annot); - xmin = pMstr->originVal; - xmax = pMstr->extentVal; - - xlo += 6. * charHtX * (double)pMstr->nSlaves; - - pSlave = pMstr->pHead; - while (pSlave != NULL) { -/*----------------------------------------------------------------------------- -* for the first channel: -* initialize a plot area; its fractional size depends on how many -* "sub-plots" there are -* plot a perimeter with grid lines -* for the other channels: -* initialize an overlapping plot area -* set a dashed line pattern (unless this is a mark or point plot) -* draw a "floating" Y axis -*----------------------------------------------------------------------------*/ - pSChan = pSlave->pSChan; - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - if (pSlave->ppAnnot == NULL) { - sydAnnotVal(pSlave, pAnnotVal, annotVal); - ppAnnotVal = pAnnotVal; - } - else - ppAnnotVal = pSlave->ppAnnot; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, xlo, ylo+2.*charHt, xhi, yhi, - xmin, ymin, xmax, ymax, pMstr->nInt, pSlave->nInt, charHt); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo; - pSlave->yFracTop = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - else if (pMstr->linePlot) { - if (dbr_type_is_ENUM(pSChan->dbrType)) - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - if (pSlave->lineKey > 1 || pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, pSlave->lineKey, NULL); - } - else if (pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_COLORNUM, pSlave->lineKey, NULL); - if (drawAxis == 0) { - pprGrid(pArea); - if (pSlave == pMstr->pHead) { - pArea->charHt = charHtTY * pWin->height; - pArea->xNsubint = pMstr->nSubInt; - pprAnnotX_wc(pArea, 0, - xmin, xmax, pMstr->nInt, 0, pMstr->label, pAnnot, 0.); - pArea->charHt = charHt * pWin->height; - } - } - pprAnnotY(pArea, offsetAnnotY, pSlave->originVal, pSlave->extentVal, - pSlave->nInt, drawAxis, - pSlave->pSChan->label, ppAnnotVal, 90.); - if (pMstr->markPlot) - pprAnnotYMark(pArea, offsetAnnotY, pSlave->markNum); - offsetAnnotY += 6; - drawAxis = 1; /* draw an "auxiliary" axis next time */ - pSlave->annotXFL = xlo - offsetAnnotY * charHtX; - pSlave->annotXFR = pSlave->annotXFL + 6. * charHtX; - pSlave->annotYFB = ylo; - pSlave->annotYFT = yhi; - pSlave = pSlave->pNext; - } - pSlave = pMstr->pHead; - pMstr->originFrac = pSlave->xFracLeft; - pMstr->extentFrac = pSlave->xFracRight; -} - -/*+/subr********************************************************************** -* NAME sydPlot_XYPlot - handle X vs Y plots -* -* DESCRIPTION -* the first channel in the plot spec is used for the X axis -* -* alarm state of the "X" channel is not displayed -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_XYPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_XYGrid(pMstr); - if (pSspec->useStats == 0) { - sydPlot_XYSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); - } - else - sydPlot_XYStats(pMstr, 0, pSspec->statCount-1); -} - -/*+/subr********************************************************************** -* NAME sydPlot_XYGrid - draw a grid for an X vs Y plot -* -* DESCRIPTION -* the first channel in the plot spec is used for the X axis -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_XYGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - SYD_PL_SLAVE *pSlaveX; /* pointer to X axis slave struct */ - double xlo, ylo, xhi, yhi; - double yPart; - PPR_AREA *pArea; - double xmin, xmax, ymin, ymax; - double charHt, charHtX, charHtTY, charHtTX; - SYD_CHAN *pSChan; - SYD_CHAN *pSChanX; - int nGrids; - char **ppAnnotVal, *pAnnotVal[20], annotVal[20][28]; - char **ppAnnotXVal, *pAnnotXVal[20], annotXVal[20][28]; - int first=1; - - pWin = pMstr->pWin; - - pSlaveX = pMstr->pHead; - while (1) { - if (pSlaveX->xChan) - break; - pSlaveX = pSlaveX->pNext; - if (pSlaveX == NULL) { - pSlaveX = pMstr->pHead; - break; - } - } - if (pSlaveX == pMstr->pHead) - pSlave = pSlaveX->pNext; - else - pSlave = pMstr->pHead; - nGrids = pMstr->nSlaves - 1; - sydPlot_setup(pMstr, nGrids, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - - pSlaveX->pArea = NULL; - pSChanX = pSlaveX->pSChan; - if (pSlaveX->ppAnnot == NULL) { - sydAnnotVal(pSlaveX, pAnnotXVal, annotXVal); - ppAnnotXVal = pAnnotXVal; - } - else - ppAnnotVal = pSlave->ppAnnot; - xmin = pSlaveX->originVal; - xmax = pSlaveX->extentVal; - while (pSlave != NULL) { -/*----------------------------------------------------------------------------- -* for each Y channel, plot a perimeter with grid lines -*----------------------------------------------------------------------------*/ - pSChan = pSlave->pSChan; - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - if (pSlave->ppAnnot == NULL) { - sydAnnotVal(pSlave, pAnnotVal, annotVal); - ppAnnotVal = pAnnotVal; - } - else - ppAnnotVal = pSlave->ppAnnot; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, - xlo+12.*charHtX, ylo+2.*charHt, xhi, yhi, - xmin, ymin, xmax, ymax, pSlaveX->nInt, pSlave->nInt, charHt); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo + 12. * charHtX; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo + 2. * charHt; - pSlave->yFracTop = yhi; - pSlave->annotXFL = xlo; - pSlave->annotXFR = pSlave->xFracLeft; - pSlave->annotYFB = pSlave->yFracBot; - pSlave->annotYFT = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - pprGrid(pArea); - pprAnnotY(pArea, 0, ymin, ymax, pSlave->nInt, 0, - pSlave->pSChan->label, ppAnnotVal, 0.); - if (first) { - pArea->charHt = charHtTY * pWin->height; - pprAnnotX(pArea, 0, xmin, xmax, pSlaveX->nInt, 0, - pSlaveX->pSChan->label, ppAnnotXVal, 0.); - pArea->charHt = charHt * pWin->height; - first = 0; - } - ylo += yPart; - yhi += yPart; - pSlave = pSlave->pNext; - if (pSlave == pSlaveX) - pSlave = pSlave->pNext; - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_XYSamples - plot one or more samples for an X vs Y plot -* -* DESCRIPTION -* the first channel in the plot spec is used for the X axis -* -* alarm state of the "X" channel is not displayed -* -* RETURNS -* void -* -* BUGS -* o line plot isn't handled -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_XYSamples(pMstr, begin, end, incr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin sample to plot */ -int end; /* I number of end sample to plot */ -int incr; /* I 0,1 for batch,incremental plotting */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - SYD_PL_SLAVE *pSlaveX; /* pointer to X axis slave struct */ - PPR_AREA *pArea; - int i, j; - SYD_SPEC *pSspec; - SYD_CHAN *pSChan; - SYD_CHAN *pSChanX; - double oldX, oldY, newX, newY; - int skip; - int showStat; /* 1 to show status code on plot */ - int pointPlot; /* 1 for point plot */ - int linePlot; /* 1 to connect points with lines */ - int markPlot; /* 1 to draw marks at points */ - int markNum; /* number of mark to use */ - int nEl; /* number of array elements */ - int first; /* ==1 if this is the first sample */ - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - pWin = pMstr->pWin; - - linePlot = pMstr->linePlot; - pointPlot = pMstr->pointPlot; - markPlot = pMstr->markPlot; - showStat = pMstr->showStat; - - pSlaveX = pMstr->pHead; - while (1) { - if (pSlaveX->xChan) - break; - pSlaveX = pSlaveX->pNext; - if (pSlaveX == NULL) { - pSlaveX = pMstr->pHead; - break; - } - } - if (pSlaveX == pMstr->pHead) - pSlave = pSlaveX->pNext; - else - pSlave = pMstr->pHead; - pSChanX = pSlaveX->pSChan; - while (pSlave != NULL) { - pArea = pSlave->pArea; - pSChan = pSlave->pSChan; - if (pSChan->pData == NULL || pSChan->dataChan == 0) - ; /* no action if never connected or not data channel */ - else { - markNum = pSlave->markNum; - - nEl = pSChanX->elCount; - if (nEl > pSChan->elCount) - nEl = pSChan->elCount; - - i = begin; - if (!incr) - first = 1; - else { - first = pSlave->first; - oldX = pSlave->oldX; - oldY = pSlave->oldY; - skip = pSlave->skip; - } - while (i >= 0) { - int restart, restart1; - restart = restart1 = 0; - if (pSChan->pFlags[i].restart) { - if (!pSChan->pFlags[i].snapstart) - restart = 1; - else if (!pSChan->pFlags[i].snapend) - restart = 1; - } - if (i != end && pSChan->pFlags[i+1].restart) { - if (!pSChan->pFlags[i+1].snapstart) - restart1 = 1; - else if (!pSChan->pFlags[i+1].snapend) - restart1 = 1; - } - if (pSChan->pFlags[i].missing || pSChanX->pFlags[i].missing) - skip = 1; - else if (first || skip || restart || - pSChanX->pFlags[i].restart) { - if (nEl == 1) { - FetchIthValInto(pSChanX, oldX) - FetchIthValInto(pSChan, oldY) - if (markPlot) - pprMarkD(pArea, oldX, oldY, markNum); - if (showStat && pSChan->pDataCodeR[i] != ' ') { - pprChar(pArea, - oldX, oldY, pSChan->pDataCodeR[i], 0., 0.); - } - else if (pointPlot) - pprPointD(pArea, oldX, oldY); - } - else { - sydPlot_XYarray(pArea, pSChanX, pSChan, i); - } - skip = 0; - } -#if 0 /* don't "optimize" filled--show each x,y */ - else if (pSChan->pFlags[i].filled && i != end && - pSChan->pFlags[i+1].restart == 0) - ; /* no action */ -#endif - else { - if (nEl == 1) { - FetchIthValInto(pSChanX, newX) - FetchIthValInto(pSChan, newY) - if (linePlot) - pprLineSegD(pArea, oldX, oldY, newX, newY); - if (markPlot) - pprMarkD(pArea, newX, newY, markNum); - if (showStat && pSChan->pDataCodeR[i] != ' ') { - pprChar(pArea, - newX, newY, pSChan->pDataCodeR[i], 0., 0.); - } - else if (pointPlot) - pprPointD(pArea, newX, newY); - oldX = newX; - oldY = newY; - } - else { - sydPlot_XYarray(pArea, pSChanX, pSChan, i); - } - } - if (i == end) - i = -1; - else if (++i >= pSspec->dataDim) - i = 0; - first = 0; - } - } - pSlave->first = first; - pSlave->oldX = oldX; - pSlave->oldY = oldY; - pSlave->skip = skip; - pSlave = pSlave->pNext; - if (pSlave == pSlaveX) - pSlave = pSlave->pNext; - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_XYStats - plot one or more snapshots for an X vs Y plot -* -* DESCRIPTION -* the first channel in the plot spec is used for the X axis -* -* alarm state of the "X" channel is not displayed -* -* RETURNS -* void -* -* BUGS -* o line plot isn't handled -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_XYStats(pMstr, begin, end) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin snapshots to plot */ -int end; /* I number of end snapshots to plot */ -{ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - SYD_PL_SLAVE *pSlaveX; /* pointer to X axis slave struct */ - PPR_AREA *pArea; - int i; - SYD_SPEC *pSspec; - SYD_CHAN *pSChan; - SYD_CHAN *pSChanX; - double oldX, oldY, newX, newY, err; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - pSlaveX = pMstr->pHead; - while (1) { - if (pSlaveX->xChan) - break; - pSlaveX = pSlaveX->pNext; - if (pSlaveX == NULL) { - pSlaveX = pMstr->pHead; - break; - } - } - if (pSlaveX == pMstr->pHead) - pSlave = pSlaveX->pNext; - else - pSlave = pMstr->pHead; - pSChanX = pSlaveX->pSChan; - while (pSlave != NULL) { - pArea = pSlave->pArea; - pSChan = pSlave->pSChan; - for (i=begin; i<=end; i++) { - if (i == begin) { - oldX = pSChanX->pStats[i].mean; - oldY = pSChan->pStats[i].mean; - } - else { - newX = pSChanX->pStats[i].mean; - newY = pSChan->pStats[i].mean; - if (pMstr->linePlot) - pprLineSegD(pArea, oldX, oldY, newX, newY); - oldX = newX; - oldY = newY; - } - if (pMstr->markPlot) - pprMarkD(pArea, oldX, oldY, pSlave->markNum); - else - pprPointD(pArea, oldX, oldY); - if (pMstr->errBar == SYD_PLATTR_STDDEV) { - err = pSChan->pStats[i].stdDev; - pprErrorBar(pArea, oldX, oldY-err, oldX, oldY+err); - err = pSChanX->pStats[i].stdDev; - pprErrorBar(pArea, oldX-err, oldY, oldX+err, oldY); - } - } - pSlave = pSlave->pNext; - if (pSlave == pSlaveX) - pSlave = pSlave->pNext; - } -} - -/*+/internal****************************************************************** -* NAME sydPlot_XYarray - plot array vs array -* -* DESCRIPTION -* -* RETURNS -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -static void -sydPlot_XYarray(pArea, pSChanX, pSChan, sub) -PPR_AREA *pArea; -SYD_CHAN *pSChan; -SYD_CHAN *pSChanX; -int sub; -{ - int nEl, nElX, nElY, i; - char *pSrcX, *pSrcY; - double newX, newY, oldX, oldY; - int nByteX, nByteY; - - nEl = nElX = pSChanX->elCount; - nElY = pSChan->elCount; - if (nElX > nElY) - nEl = nElY; - nByteX = dbr_value_size[pSChanX->dbrType]; - pSrcX = (char *)pSChanX->pData + sub * nByteX * nElX; - nByteY = dbr_value_size[pSChan->dbrType]; - pSrcY = (char *)pSChan->pData + sub * nByteY * nElY; - for (i=0; idbrType)) - newX = *(float *)pSrcX; - else if (dbr_type_is_SHORT(pSChanX->dbrType)) - newX = *(short *)pSrcX; - else if (dbr_type_is_DOUBLE(pSChanX->dbrType)) - newX = *(double *)pSrcX; - else if (dbr_type_is_LONG(pSChanX->dbrType)) - newX = *(long *)pSrcX; - else if (dbr_type_is_CHAR(pSChanX->dbrType)) - newX = *(unsigned char *)pSrcX; - else if (dbr_type_is_ENUM(pSChanX->dbrType)) - newX = *(short *)pSrcX; - if (dbr_type_is_FLOAT(pSChan->dbrType)) - newY = *(float *)pSrcY; - else if (dbr_type_is_SHORT(pSChan->dbrType)) - newY = *(short *)pSrcY; - else if (dbr_type_is_DOUBLE(pSChan->dbrType)) - newY = *(double *)pSrcY; - else if (dbr_type_is_LONG(pSChan->dbrType)) - newY = *(long *)pSrcY; - else if (dbr_type_is_CHAR(pSChan->dbrType)) - newY = *(unsigned char *)pSrcY; - else if (dbr_type_is_ENUM(pSChan->dbrType)) - newY = *(short *)pSrcY; - if (i > 0) - pprLineSegD(pArea, oldX, oldY, newX, newY); - oldX = newX; - oldY = newY; - pSrcX += nByteX; - pSrcY += nByteY; - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_XYYPlot - handle X vs multiple Y plots -* -* DESCRIPTION -* the first channel in the plot spec is used for the X axis -* -* alarm state of the "X" channel is not displayed -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_XYYPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_XYYGrid(pMstr); - if (pSspec->useStats == 0) { - sydPlot_XYSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); - } - else - sydPlot_XYStats(pMstr, 0, pSspec->statCount-1); -} - -/*+/subr********************************************************************** -* NAME sydPlot_XYYGrid - draw a grid for an X vs multiple Y plot -* -* DESCRIPTION -* the first channel in the plot spec is used for the X axis -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_XYYGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - SYD_PL_SLAVE *pSlaveX; /* pointer to X axis slave struct */ - double xlo, ylo, xhi, yhi, yPart; - PPR_AREA *pArea; - double xmin, xmax, ymin, ymax; - double charHt, charHtX, charHtTY, charHtTX; - SYD_CHAN *pSChan; - SYD_CHAN *pSChanX; - int offsetAnnotY=0; - int drawAxis=0; - int nGrids; - char **ppAnnotVal, *pAnnotVal[20], annotVal[20][28]; - char **ppAnnotXVal, *pAnnotXVal[20], annotXVal[20][28]; - - pWin = pMstr->pWin; - - pSlaveX = pMstr->pHead; - while (1) { - if (pSlaveX->xChan) - break; - pSlaveX = pSlaveX->pNext; - if (pSlaveX == NULL) { - pSlaveX = pMstr->pHead; - break; - } - } - if (pSlaveX == pMstr->pHead) - pSlave = pSlaveX->pNext; - else - pSlave = pMstr->pHead; - pSChanX = pSlaveX->pSChan; - - nGrids = 1; - sydPlot_setup(pMstr, nGrids, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - xlo += 6. * charHtX * (double)(pMstr->nSlaves - 1); - - pSlaveX->pArea = NULL; - xmin = pSlaveX->originVal; - xmax = pSlaveX->extentVal; - if (pSlaveX->ppAnnot == NULL) { - sydAnnotVal(pSlaveX, pAnnotXVal, annotXVal); - ppAnnotXVal = pAnnotXVal; - } - else - ppAnnotXVal = pSlaveX->ppAnnot; - pSlaveX->yFracBot = pSlaveX->yFracTop = 0.; - while (pSlave != NULL) { -/*----------------------------------------------------------------------------- -* for the first Y channel: -* initialize a plot area; its fractional size depends on how many -* "sub-plots" there are -* plot a perimeter with grid lines -* set for solid line -* for the other channels: -* initialize an overlapping plot area -* set a dashed line pattern (unless this is a mark or point plot) -* draw a "floating" Y axis -*----------------------------------------------------------------------------*/ - pSChan = pSlave->pSChan; - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - if (pSlave->ppAnnot == NULL) { - sydAnnotVal(pSlave, pAnnotVal, annotVal); - ppAnnotVal = pAnnotVal; - } - else - ppAnnotVal = pSlave->ppAnnot; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, xlo, ylo+2.*charHt, xhi, yhi, - xmin, ymin, xmax, ymax, pSlaveX->nInt, pSlave->nInt, charHt); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo; - pSlave->yFracTop = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - else if (pMstr->linePlot) { - /* set keynum if color is being used or if this is auxiliary axis */ - if (drawAxis || pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, pSlave->lineKey, NULL); - } - else if (pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_COLORNUM, pSlave->lineKey, NULL); - if (drawAxis == 0) { - pprGrid(pArea); - pArea->charHt = charHtTY * pWin->height; - pprAnnotX_wc(pArea, 0, pSlaveX->originVal, pSlaveX->extentVal, - pSlaveX->nInt, 0, pSlaveX->pSChan->label, ppAnnotXVal, 0.); - pArea->charHt = charHt * pWin->height; - } - pprAnnotY(pArea, offsetAnnotY, pSlave->originVal, pSlave->extentVal, - pSlave->nInt, drawAxis, pSlave->pSChan->label, ppAnnotVal, 90.); - if (pMstr->markPlot) - pprAnnotYMark(pArea, offsetAnnotY, pSlave->markNum); - offsetAnnotY += 6; - drawAxis = 1; /* draw an "auxiliary" axis next time */ - pSlave->annotXFL = xlo - offsetAnnotY * charHtX; - pSlave->annotXFR = pSlave->annotXFL + 6. * charHtX; - pSlave->annotYFB = ylo; - pSlave->annotYFT = yhi; - pSlave = pSlave->pNext; - if (pSlave == pSlaveX) - pSlave = pSlave->pNext; - } - - return; -} - -/*+/subr********************************************************************** -* NAME sydPlot_YPlot - handle Y plots -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_YPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_YGrid(pMstr); - if (pSspec->useStats == 0) { - sydPlot_YSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); - } - else - sydPlot_YStats(pMstr, 0, pSspec->statCount-1); -} - -/*+/subr********************************************************************** -* NAME sydPlot_YGrid - draw a grid for a Y plot -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_YGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - double xlo, ylo, xhi, yhi; - double yPart; - PPR_AREA *pArea; - double xmin, xmax, ymin, ymax; - int xNint; - double charHt, charHtX, charHtTY, charHtTX; - SYD_CHAN *pSChan; - int thick=3; - int nGrids; - char **ppAnnotVal, *pAnnotVal[20], annotVal[20][28]; - - pWin = pMstr->pWin; - - nGrids = pMstr->nSlaves; - sydPlot_setup(pMstr, nGrids, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - - xmin = xmax = 0.; - pSlave = pMstr->pHead; - while (pSlave != NULL) { - if (pSlave->pSChan->elCount > xmax) - xmax = pSlave->pSChan->elCount; - pSlave = pSlave->pNext; - } - xNint = 1; - if (xmax == 1.) - xmax = pMstr->pSspec->reqCount - 1; - - pSlave = pMstr->pHead; - while (pSlave != NULL) { -/*----------------------------------------------------------------------------- -* for each channel, initialize a plot area. -* -* plot a perimeter with grid lines -*----------------------------------------------------------------------------*/ - pSChan = pSlave->pSChan; - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - charHt = PprDfltCharHt(ylo, yhi); - charHtX = pprYFracToXFrac(pWin, charHt); - if (pSlave->ppAnnot == NULL) { - sydAnnotVal(pSlave, pAnnotVal, annotVal); - ppAnnotVal = pAnnotVal; - } - else - ppAnnotVal = pSlave->ppAnnot; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, - xlo+12.*charHtX, ylo+2.*charHt, xhi, yhi, - xmin, ymin, xmax, ymax, xNint, pSlave->nInt, charHt); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo + 12. * charHtX; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo + 6. * charHt; - pSlave->yFracTop = yhi; - pSlave->annotXFL = xlo; - pSlave->annotXFR = pSlave->xFracLeft; - pSlave->annotYFB = pSlave->yFracBot; - pSlave->annotYFT = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - else if (pMstr->linePlot) { - if (dbr_type_is_ENUM(pSChan->dbrType)) - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - } - pprGrid(pArea); - pprAnnotY(pArea, 0, ymin, ymax, pSlave->nInt, 0, - pSlave->pSChan->label, ppAnnotVal, 0.); - if (pSlave == pMstr->pHead) { - pArea->charHt = charHtTY * pWin->height; - pprAnnotX(pArea, 0, xmin, xmax, xNint, 0, "bin number", NULL, 0.); - pArea->charHt = charHt * pWin->height; - } - ylo += yPart; - yhi += yPart; - pSlave = pSlave->pNext; - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_YSamples - plot one or more samples for a Y plot -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_YSamples(pMstr, begin, end, incr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin sample to plot */ -int end; /* I number of end sample to plot */ -int incr; /* I 0,1 for batch,incremental plotting */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - PPR_AREA *pArea; - int i, j; - SYD_SPEC *pSspec; - SYD_CHAN *pSChan; - double oldX, oldY, newX, newY; - int skip; - int showStat; /* 1 to show status code on plot */ - int pointPlot; /* 1 for point plot */ - int linePlot; /* 1 to connect points with lines */ - int markPlot; /* 1 to draw marks at points */ - int markNum; /* number of mark to use */ - int nEl; /* number of array elements */ - int first; /* ==1 if this is the first sample */ - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - pWin = pMstr->pWin; - - linePlot = pMstr->linePlot; - pointPlot = pMstr->pointPlot; - markPlot = pMstr->markPlot; - showStat = pMstr->showStat; - - pSlave = pMstr->pHead; - while (pSlave != NULL) { - pArea = pSlave->pArea; - pSChan = pSlave->pSChan; - if (pSChan->pData == NULL || pSChan->dataChan == 0) - ; /* no action if never connected or not data channel */ - else { - markNum = pSlave->markNum; - - nEl = pSChan->elCount; - - i = begin; - if (!incr) - first = 1; - else { - first = pSlave->first; - oldX = pSlave->oldX; - oldY = pSlave->oldY; - skip = pSlave->skip; - } - while (i >= 0) { - int restart, restart1; - restart = restart1 = 0; - if (pSChan->pFlags[i].restart) { - if (!pSChan->pFlags[i].snapstart) - restart = 1; - else if (!pSChan->pFlags[i].snapend) - restart = 1; - } - if (i != end && pSChan->pFlags[i+1].restart) { - if (!pSChan->pFlags[i+1].snapstart) - restart1 = 1; - else if (!pSChan->pFlags[i+1].snapend) - restart1 = 1; - } - if (pSChan->pFlags[i].missing) - skip = 1; - else if (first || skip || restart) { - if (nEl == 1) { - oldX = i; - FetchIthValInto(pSChan, oldY) - if (markPlot) - pprMarkD(pArea, oldX, oldY, markNum); - if (showStat && pSChan->pDataCodeR[i] != ' ') { - pprChar(pArea, oldX, oldY, - pSChan->pDataCodeR[i], 0., 0.); - } - else if (pointPlot) - pprPointD(pArea, oldX, oldY); - } - else { - sydPlot_Yarray(pArea, pSChan, i); - } - skip = 0; - } - else if (pSChan->pFlags[i].filled && restart1 == 0 && i != end) - ; /* no action */ - else { - if (nEl == 1) { - newX = i; - if (linePlot && dbr_type_is_ENUM(pSChan->dbrType)) { - pprLineSegD(pArea, oldX, oldY, newX, oldY); - oldX = newX; - } - FetchIthValInto(pSChan, newY) - if (linePlot) - pprLineSegD(pArea, oldX, oldY, newX, newY); - if (markPlot) - pprMarkD(pArea, newX, newY, markNum); - if (showStat && pSChan->pDataCodeR[i] != ' ') { - pprChar(pArea, newX, newY, - pSChan->pDataCodeR[i], 0., 0.); - } - else if (pointPlot) - pprPointD(pArea, newX, newY); - oldX = newX; - oldY = newY; - } - else { - sydPlot_Yarray(pArea, pSChan, i); - } - } - if (i == end) - i = -1; - else if (++i >= pSspec->dataDim) - i = 0; - first = 0; - } - } - pSlave->first = first; - pSlave->oldX = oldX; - pSlave->oldY = oldY; - pSlave->skip = skip; - pSlave = pSlave->pNext; - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_YStats - plot one or more snapshots for a Y plot -* -* DESCRIPTION -* -* RETURNS -* void -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -*-*/ -void -sydPlot_YStats(pMstr, begin, end) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -int begin; /* I number of begin snapshots to plot */ -int end; /* I number of end snapshots to plot */ -{ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - PPR_AREA *pArea; - int i; - SYD_SPEC *pSspec; - SYD_CHAN *pSChan; - double oldX, oldY, newX, newY, err; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - for (pSlave=pMstr->pHead; pSlave!=NULL; pSlave=pSlave->pNext) { - pArea = pSlave->pArea; pSChan = pSlave->pSChan; - for (i=begin; i<=end; i++) { - if (i == begin) { - oldX = i; oldY = pSChan->pStats[i].mean; - } - else { - newX = i; newY = pSChan->pStats[i].mean; - if (pMstr->linePlot) - pprLineSegD(pArea, oldX, oldY, newX, newY); - oldX = newX; oldY = newY; - } - if (pMstr->markPlot) - pprMarkD(pArea, oldX, oldY, pSlave->markNum); - else - pprPointD(pArea, oldX, oldY); - if (pMstr->errBar == SYD_PLATTR_STDDEV) { - err = pSChan->pStats[i].stdDev; - pprErrorBar(pArea, oldX, oldY-err, oldX, oldY+err); - } - } - } -} - -/*+/internal****************************************************************** -* NAME sydPlot_Yarray - plot array vs array -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -static void -sydPlot_Yarray(pArea, pSChan, sub) -PPR_AREA *pArea; -SYD_CHAN *pSChan; -int sub; -{ - int nEl, nElY, i; - char *pSrcY; - double newX, newY, oldX, oldY; - int nByteY; - - nEl = nElY = pSChan->elCount; - nByteY = dbr_value_size[pSChan->dbrType]; - pSrcY = (char *)pSChan->pData + sub * nByteY * nElY; - if (dbr_type_is_FLOAT(pSChan->dbrType)) - pprWaveF(pArea, 1., (float *)pSrcY, nEl); - else if (dbr_type_is_SHORT(pSChan->dbrType)) - pprWaveS(pArea, 1, (short *)pSrcY, nEl); - else if (dbr_type_is_DOUBLE(pSChan->dbrType)) - pprWaveD(pArea, 1., (double *)pSrcY, nEl); - else if (dbr_type_is_LONG(pSChan->dbrType)) - pprWaveL(pArea, 1, (long *)pSrcY, nEl); - else if (dbr_type_is_ENUM(pSChan->dbrType)) - pprWaveS(pArea, 1, (short *)pSrcY, nEl); - else if (dbr_type_is_CHAR(pSChan->dbrType)) { - for (i=0; i 0) - pprLineSegD(pArea, oldX, oldY, newX, newY); - oldX = newX; - oldY = newY; - pSrcY += nByteY; - } - } -} - -/*+/subr********************************************************************** -* NAME sydPlot_YYPlot - handle multiple Y plots -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_YYPlot(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - SYD_SPEC *pSspec; - - assert(pMstr != NULL); - pSspec = pMstr->pSspec; - assert(pSspec != NULL); - - sydPlot_YYGrid(pMstr); - if (pSspec->useStats == 0) { - sydPlot_YSamples(pMstr, - pSspec->restrictFirstData, pSspec->restrictLastData, 0); - } - else - sydPlot_YStats(pMstr, 0, pSspec->statCount-1); -} - -/*+/subr********************************************************************** -* NAME sydPlot_YYGrid - draw a grid for a multiple Y plot -* -* DESCRIPTION -* -* RETURNS -* void -* -* BUGS -* o text -* -* SEE ALSO -* -* NOTES -* 1. This routine isn't intended to be called directly. -* -* EXAMPLE -* -*-*/ -void -sydPlot_YYGrid(pMstr) -SYD_PL_MSTR *pMstr; /* I pointer to master plot structure */ -{ - PPR_WIN *pWin; /* pointer to plot window structure */ - SYD_PL_SLAVE *pSlave; /* pointer to individual slave struct */ - double xlo, ylo, xhi, yhi, yPart; - PPR_AREA *pArea; - double xmin, xmax, ymin, ymax; - int xNint; - double charHt, charHtX, charHtTY, charHtTX; - SYD_CHAN *pSChan; - int offsetAnnotY=0; - int drawAxis=0; - int thick=3; - int nGrids; - - pWin = pMstr->pWin; - - nGrids = 1; - sydPlot_setup(pMstr, nGrids, &xlo, &ylo, &xhi, &yhi, &yPart, - &charHt, &charHtX, &charHtTY, &charHtTX); - xlo += 6. * charHtX * (double)pMstr->nSlaves; - - xmin = xmax = 0.; - pSlave = pMstr->pHead; - while (pSlave != NULL) { - if (pSlave->pSChan->elCount > xmax) - xmax = pSlave->pSChan->elCount; - pSlave = pSlave->pNext; - } - xNint = 1; - if (xmax == 1.) - xmax = pMstr->pSspec->reqCount - 1; - - pSlave = pMstr->pHead; - while (pSlave != NULL) { -/*----------------------------------------------------------------------------- -* for the first channel: -* initialize a plot area; its fractional size depends on how many -* "sub-plots" there are -* plot a perimeter with grid lines -* for the other channels: -* initialize an overlapping plot area -* set a dashed line pattern (unless this is a mark or point plot) -* draw a "floating" Y axis -*----------------------------------------------------------------------------*/ - pSChan = pSlave->pSChan; - ymin = pSlave->originVal; - ymax = pSlave->extentVal; - if (pSlave->pArea != NULL) - pprAreaClose(pSlave->pArea); - pArea = pSlave->pArea = pprAreaOpen(pWin, xlo, ylo+2.*charHt, xhi, yhi, - xmin, ymin, xmax, ymax, xNint, pSlave->nInt, charHt); - assertAlways(pArea != NULL); - pSlave->xFracLeft = xlo; - pSlave->xFracRight = xhi; - pSlave->yFracBot = ylo; - pSlave->yFracTop = yhi; - if (pSlave->fg != 0 && pMstr->noColor == 0) - pprAreaSetAttr(pSlave->pArea, PPR_ATTR_FG, 0, &pSlave->fg); - else if (pMstr->linePlot) { - if (dbr_type_is_ENUM(pSChan->dbrType)) - pprAreaSetAttr(pArea, PPR_ATTR_LINE_THICK, thick, NULL); - if (pSlave->lineKey > 1 || pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_KEYNUM, pSlave->lineKey, NULL); - } - else if (pMstr->noColor == 0) - pprAreaSetAttr(pArea, PPR_ATTR_COLORNUM, pSlave->lineKey, NULL); - if (drawAxis == 0) { - pprGrid(pArea); - pArea->charHt = charHtTY * pWin->height; - pprAnnotX_wc(pArea, 0, xmin, xmax, xNint, 0, "bin number", NULL,0.); - pArea->charHt = charHt * pWin->height; - } - pprAnnotY(pArea, offsetAnnotY, pSlave->originVal, pSlave->extentVal, - pSlave->nInt, drawAxis, - pSlave->pSChan->label, pSlave->ppAnnot, 90.); - if (pMstr->markPlot) - pprAnnotYMark(pArea, offsetAnnotY, pSlave->markNum); - offsetAnnotY += 6; - drawAxis = 1; /* draw an "auxiliary" axis next time */ - pSlave->annotXFL = xlo - offsetAnnotY * charHtX; - pSlave->annotXFR = pSlave->annotXFL + 6. * charHtX; - pSlave->annotYFB = ylo; - pSlave->annotYFT = yhi; - pSlave = pSlave->pNext; - } -} diff --git a/src/vxWorks/db/devLib.c b/src/vxWorks/db/devLib.c deleted file mode 100644 index 9fae68376..000000000 --- a/src/vxWorks/db/devLib.c +++ /dev/null @@ -1,1336 +0,0 @@ -/* devLib.c - support for allocation of common device resources */ -/* @(#)$Id$*/ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - * - * 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 03-10-93 joh original - * .02 03-18-93 joh index address alloc array by fundamental type - * .03 03-23-93 joh changed input parameter to be a fund - * address type in favor of the argument - * that the BSP will be reconfigured - * to use an EPICS standard address - * mode - * .04 04-08-93 joh made unsolicitedHandlerEPICS() external - * .05 04-08-92 joh better diagnostic if we cant find - * a default interrupt handler - * .06 05-06-93 joh added new parameter to devDisconnectInterrupt(). - * See comment below. - * .07 05-28-93 joh Added block probe routines - * .08 05-28-93 joh Added an argument to devRegisterAddress() - * .09 05-28-93 joh Added devAddressMap() - * .10 06-14-93 joh Added devAllocAddress() - * .11 02-21-95 joh Fixed warning messages - * - * NOTES: - * .01 06-14-93 joh needs devAllocInterruptVector() routine - */ - -static char *sccsID = "@(#) $Id$"; - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "fast_lock.h" -#define devLibGlobal -#include "devLib.h" - - -LOCAL LIST addrAlloc[atLast]; -LOCAL LIST addrFree[atLast]; - -LOCAL void *addrLast[atLast] = { - (void *) 0xffff, - (void *) 0xffffff, - (void *) 0xffffffff, - (void *) 0xffffff - }; - -LOCAL long addrFail[atLast] = { - S_dev_badA16, - S_dev_badA24, - S_dev_badA32, - S_dev_badA24 - }; - -LOCAL FAST_LOCK addrListLock; -LOCAL char addrListInit; - -typedef struct{ - NODE node; - const char *pOwnerName; - char *pFirst; - char *pLast; -}rangeItem; - -/* - * A list of the names of the unexpected interrupt handlers - * ( some of these are provided by wrs ) - */ -LOCAL char *defaultHandlerNames[] = { - "_excStub", - "_excIntStub", - "_unsolicitedHandlerEPICS"}; -typedef void myISR (void *pParam); -LOCAL myISR *defaultHandlerAddr[NELEMENTS(defaultHandlerNames)]; - -/* - * These routines are not exported - */ -LOCAL void initHandlerAddrList(void); -LOCAL int vectorInUse(unsigned vectorNumber); -LOCAL long initAddrList(void); -LOCAL long addrVerify(epicsAddressType addrType, void *address); -LOCAL myISR *isrFetch(unsigned vectorNumber); -LOCAL long blockFind( - epicsAddressType addrType, - char *pBlockFirst, - char *pBlockLast, - /* size needed */ - unsigned long size, - /* n ls bits zero in base addr */ - unsigned alignment, - /* base address found */ - char **ppBase); -LOCAL long report_conflict( - epicsAddressType addrType, - char *pFirst, - char *pLast, - const char *pOwnerName); -LOCAL long devInsertAddress( - LIST *pRangeList, - rangeItem *pNewRange); -LOCAL long devListAddressMap( - LIST *pRangeList); -LOCAL long devCombineAdjacentBlocks( - LIST *pRangeList, - rangeItem *pRange); -LOCAL long devInstallAddr( - rangeItem *pRange, - const char *pOwnerName, - epicsAddressType addrType, - char *pFirst, - char *pLast, - void **pLocalAddress); -LOCAL long blockDivide( - epicsAddressType addrType, - char *pBlockFirst, - char *pBlockLast, - /* base address found */ - char **ppBase, - unsigned long requestSize -); -LOCAL long blockProbe( - epicsAddressType addrType, - char *pFirst, - char *pLast -); -long locationProbe( - epicsAddressType addrType, - char *pLocation -); - -/* - * this routine needs to be in the symbol table - * for this code to work correctly - */ -void unsolicitedHandlerEPICS(int vectorNumber); -/* - * this is in veclist.c - */ -int cISRTest(void (*)(), void (**)(), void **); - -#define SUCCESS 0 - - - -/* - * - * devConnectInterrupt - * - * coded to support other interrupting types in the future - * - * wrapper to minimize driver dependency on vxWorks - */ -long devConnectInterrupt( -epicsInterruptType intType, -unsigned vectorNumber, -void (*pFunction)(), -void *parameter) -{ - int status; - - switch(intType){ - case intCPU: - case intVME: - case intVXI: - if(vectorInUse(vectorNumber)){ - return S_dev_vectorInUse; - } - status = intConnect( - (void *)INUM_TO_IVEC(vectorNumber), - pFunction, - (int) parameter); - if(status<0){ - return S_dev_vxWorksVecInstlFail; - } - break; - default: - return S_dev_uknIntType; - } - - return SUCCESS; -} - - -/* - * - * devDisconnectInterrupt() - * - * wrapper to minimize driver dependency on vxWorks - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from removing - * an interrupt handler that was installed by another driver - * - */ -long devDisconnectInterrupt( -epicsInterruptType intType, -unsigned vectorNumber, -void (*pFunction)() -) -{ - void (*psub)(); - int status; - - /* - * If pFunction not connected to this vector - * then they are probably disconnecting from the wrong vector - */ - psub = isrFetch(vectorNumber); - if(psub != pFunction){ - return S_dev_vectorNotInUse; - } - - switch(intType){ - case intCPU: - case intVME: - case intVXI: - status = intConnect( - (void *)INUM_TO_IVEC(vectorNumber), - unsolicitedHandlerEPICS, - (int) vectorNumber); - if(status<0){ - return S_dev_vxWorksVecInstlFail; - } - break; - default: - return S_dev_uknIntType; - } - - return SUCCESS; -} - - -/* - * - * devEnableInterruptLevel() - * - * wrapper to minimize driver dependency on vxWorks - * - */ -long devEnableInterruptLevel( -epicsInterruptType intType, -unsigned level) -{ - int s; - - switch(intType){ - case intCPU: - case intVME: - case intVXI: - s = sysIntEnable(level); - if(s<0){ - return S_dev_vxWorksIntEnFail; - } - break; - default: - return S_dev_uknIntType; - } - - return SUCCESS; -} - - -/* - * - * devDisableInterruptLevel() - * - * wrapper to minimize driver dependency on vxWorks - * - */ -long devDisableInterruptLevel( -epicsInterruptType intType, -unsigned level) -{ - int s; - - switch(intType){ - case intCPU: - case intVME: - case intVXI: - s = sysIntDisable(level); - if(s<0){ - return S_dev_vxWorksIntDissFail; - } - break; - default: - return S_dev_uknIntType; - } - - return SUCCESS; -} - - -/* - * - * devRegisterAddress() - * - * - */ -long devRegisterAddress( -const char *pOwnerName, -epicsAddressType addrType, -void *baseAddress, -unsigned long size, -void **pLocalAddress) -{ - char *pFirst; - char *pLast; - rangeItem *pRange; - long s; - - if(!addrListInit){ - s = initAddrList(); - if(s){ - return s; - } - } - - s = addrVerify(addrType, (void *) size); - if(s){ - return s; - } - - if(size == 0){ - return S_dev_lowValue; - } - - pFirst = (char *) baseAddress; - pLast = pFirst + size - 1; - - FASTLOCK(&addrListLock); - pRange = (rangeItem *) addrFree[addrType].node.next; - while(pRange){ - - if(pRange->pFirst > pLast){ - pRange = NULL; - break; - } - - if(pRange->pFirst <= pFirst && pRange->pLast >= pLast){ - break; - } - - pRange = (rangeItem *) pRange->node.next; - } - FASTUNLOCK(&addrListLock); - - if(!pRange){ - s = report_conflict(addrType, pFirst, pLast, pOwnerName); - if(s){ - return s; - } - else{ - return S_dev_internal; - } - } - - s = devInstallAddr( - pRange, - pOwnerName, - addrType, - pFirst, - pLast, - pLocalAddress); - return s; -} - - -/* - * - * devInstallAddr() - * - */ -LOCAL long devInstallAddr( -rangeItem *pRange, /* item on the free list to be split */ -const char *pOwnerName, -epicsAddressType addrType, -char *pFirst, -char *pLast, -void **ppLocalAddress) -{ - rangeItem *pNewRange; - int s; - - if(ppLocalAddress){ - char *pAddr; - int s1; - int s2; - - if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert) - { - *ppLocalAddress = pFirst; - } - else - { - s1 = sysBusToLocalAdrs( - EPICStovxWorksAddrType[addrType], - pLast, - &pAddr); - s2 = sysBusToLocalAdrs( - EPICStovxWorksAddrType[addrType], - pFirst, - &pAddr); - if(s1 || s2){ - errPrintf( - S_dev_vxWorksAddrMapFail, - __FILE__, - __LINE__, - "%s base=0X %X size = 0X %X", - epicsAddressTypeName[addrType], - pFirst, - pLast-pFirst+1); - return S_dev_vxWorksAddrMapFail; - } - - *ppLocalAddress = (void *) pAddr; - } - } - - /* - * split the item on the free list - * (when required) - */ - if(pRange->pFirst == pFirst && pRange->pLast == pLast){ - FASTLOCK(&addrListLock); - lstDelete(&addrFree[addrType], &pRange->node); - FASTUNLOCK(&addrListLock); - free((void *)pRange); - } - else if(pRange->pFirst == pFirst){ - pRange->pFirst = pLast+1; - } - else if(pRange->pLast == pLast){ - pRange->pLast = pFirst-1; - } - else{ - - pNewRange = (rangeItem *) malloc(sizeof(*pRange)); - if(!pNewRange){ - return S_dev_noMemory; - } - pNewRange->pFirst = pLast+1; - pNewRange->pLast = pRange->pLast; - pNewRange->pOwnerName = ""; - pRange->pLast = pFirst-1; - /* - * add the node after the old item on the free list - * (blocks end up ordered by address) - */ - FASTLOCK(&addrListLock); - lstInsert(&addrFree[addrType], &pRange->node, &pNewRange->node); - FASTUNLOCK(&addrListLock); - } - - /* - * allocate a new address range entry and add it to - * the list - */ - pNewRange = (rangeItem *)calloc(1,sizeof(*pRange)); - if(!pNewRange){ - return S_dev_noMemory; - } - - pNewRange->pFirst = pFirst; - pNewRange->pLast = pLast; - pNewRange->pOwnerName = pOwnerName; - - s = devInsertAddress(&addrAlloc[addrType], pNewRange); - if(s){ - free((void *)pNewRange); - return s; - } - - return SUCCESS; -} - - -/* - * - * report_conflict() - * - * - */ -LOCAL long report_conflict( -epicsAddressType addrType, -char *pFirst, -char *pLast, -const char *pOwnerName -) -{ - rangeItem *pRange; - - pRange = (rangeItem *) addrAlloc[addrType].node.next; - while(pRange){ - - if(pRange->pFirst <= pFirst && pRange->pLast >= pFirst){ - break; - } - if(pRange->pFirst <= pLast && pRange->pLast >= pLast){ - break; - } - if(pRange->pFirst > pLast){ - pRange = NULL; - break; - } - - pRange = (rangeItem *) pRange->node.next; - } - - if(pRange){ - errPrintf( - S_dev_addressOverlap, - __FILE__, - __LINE__, - "%10s 0X %08X - %08X Requested by %s", - epicsAddressTypeName[addrType], - pFirst, - pLast, - pOwnerName); - - errPrintf( - S_dev_identifyOverlap, - __FILE__, - __LINE__, - "%10s 0X %08X - %08X Owned by %s", - epicsAddressTypeName[addrType], - pRange->pFirst, - pRange->pLast, - pRange->pOwnerName); - - return S_dev_addressOverlap; - } - - return S_dev_internal; -} - - -/* - * - * devUnregisterAddress() - * - */ -long devUnregisterAddress( -epicsAddressType addrType, -void *baseAddress, -const char *pOwnerName) -{ - char *charAddress = (char *) baseAddress; - rangeItem *pRange; - int s; - - if(!addrListInit){ - s = initAddrList(); - if(s){ - return s; - } - } - - s = addrVerify(addrType, charAddress); - if(s != SUCCESS){ - return s; - } - - FASTLOCK(&addrListLock); - pRange = (rangeItem *) addrAlloc[addrType].node.next; - while(pRange){ - if(pRange->pFirst == charAddress){ - break; - } - if(pRange->pFirst > charAddress){ - pRange = NULL; - break; - } - pRange = (rangeItem *) pRange->node.next; - } - FASTUNLOCK(&addrListLock); - - if(!pRange){ - return S_dev_addressNotFound; - } - - if(strcmp(pOwnerName,pRange->pOwnerName)){ - s = S_dev_addressOverlap; - errPrintf( - s, - __FILE__, - __LINE__, - "unregister address for %s at 0X %X failed because %s owns it", - pOwnerName, - charAddress, - pRange->pOwnerName); - return s; - } - - FASTLOCK(&addrListLock); - lstDelete( - &addrAlloc[addrType], - &pRange->node); - FASTUNLOCK(&addrListLock); - - pRange->pOwnerName = ""; - s = devInsertAddress(&addrFree[addrType], pRange); - if(s){ - free((void *)pRange); - errMessage(s, "Allocated Device Address Leak"); - return s; - } - s = devCombineAdjacentBlocks(&addrFree[addrType], pRange); - if(s){ - errMessage(s, NULL); - return s; - } - - return SUCCESS; -} - - -/* - * - * devCombineAdjacentBlocks() - * - * - */ -LOCAL long devCombineAdjacentBlocks( -LIST *pRangeList, -rangeItem *pRange) -{ - rangeItem *pBefore; - rangeItem *pAfter; - - pBefore = (rangeItem *) pRange->node.previous; - pAfter = (rangeItem *) pRange->node.next; - - /* - * combine adjacent blocks - */ - if(pBefore){ - if(pBefore->pLast == pRange->pFirst-1){ - FASTLOCK(&addrListLock); - pRange->pFirst = pBefore->pFirst; - lstDelete(pRangeList, &pBefore->node); - FASTUNLOCK(&addrListLock); - free((void *)pBefore); - } - } - - if(pAfter){ - if(pAfter->pFirst-1 == pRange->pLast){ - FASTLOCK(&addrListLock); - pRange->pLast = pAfter->pLast; - lstDelete(pRangeList, &pAfter->node); - FASTUNLOCK(&addrListLock); - free((void *)pAfter); - } - } - - return SUCCESS; -} - - -/* - * - * devInsertAddress() - * - * - */ -LOCAL long devInsertAddress( -LIST *pRangeList, -rangeItem *pNewRange) -{ - rangeItem *pBefore; - rangeItem *pAfter; - - FASTLOCK(&addrListLock); - pAfter = (rangeItem *) pRangeList->node.next; - while(pAfter){ - if(pNewRange->pLast < pAfter->pFirst){ - break; - } - pAfter = (rangeItem *) pAfter->node.next; - } - - if(pAfter){ - pBefore = (rangeItem *) pAfter->node.previous; - lstInsert(pRangeList, &pBefore->node, &pNewRange->node); - } - else{ - lstAdd(pRangeList, &pNewRange->node); - } - FASTUNLOCK(&addrListLock); - - return SUCCESS; -} - - - -/* - * - * devAllocAddress() - * - * - */ -long devAllocAddress( -const char *pOwnerName, -epicsAddressType addrType, -unsigned long size, -unsigned alignment, /* n ls bits zero in base addr*/ -void **pLocalAddress) -{ - int s; - rangeItem *pRange; - char *pBase; - - s = addrVerify(addrType, (void *)size); - if(s){ - return s; - } - - if(size == 0){ - return S_dev_lowValue; - } - - FASTLOCK(&addrListLock); - pRange = (rangeItem *) addrFree[addrType].node.next; - while(pRange){ - if(pRange->pLast-pRange->pFirst>=size-1){ - s = blockFind( - addrType, - pRange->pFirst, - pRange->pLast, - size, - alignment, - &pBase); - if(!s){ - break; - } - } - pRange = (rangeItem *) pRange->node.next; - } - FASTUNLOCK(&addrListLock); - - if(!pRange){ - s = S_dev_deviceDoesNotFit; - errMessage(s, epicsAddressTypeName[addrType]); - return s; - } - - - s = devInstallAddr( - pRange, - pOwnerName, - addrType, - pBase, - pBase + size - 1, - pLocalAddress); - return s; -} - - - -/* - * addrVerify() - */ -LOCAL long addrVerify( -epicsAddressType addrType, -void *address) -{ - if(addrType>=atLast){ - return S_dev_uknAddrType; - } - - if(address > addrLast[addrType]){ - return addrFail[addrType]; - } - - return SUCCESS; -} - - - -/* - * initAddrList() - */ -LOCAL long initAddrList(void) -{ - rangeItem *pRange; - - if(NELEMENTS(addrAlloc) != NELEMENTS(addrFree)){ - return S_dev_internal; - } - - if(!addrListInit){ - int i; - - FASTLOCKINIT(&addrListLock); - - FASTLOCK(&addrListLock); - for(i=0; ipOwnerName = ""; - pRange->pFirst = 0; - pRange->pLast = addrLast[i]; - lstAdd(&addrFree[i], &pRange->node); - } - FASTUNLOCK(&addrListLock); - } - - return SUCCESS; -} - - -/* - * devAddressMap() - */ -long devAddressMap(void) -{ - return devListAddressMap(addrAlloc); -} - - -/* - * devListAddressMap() - */ -LOCAL long devListAddressMap(LIST *pRangeList) -{ - rangeItem *pri; - int i; - long s; - - if(!addrListInit){ - s = initAddrList(); - if(s){ - return s; - } - } - - FASTLOCK(&addrListLock); - for(i=0; ipFirst) * 2U), - (unsigned long) pri->pFirst, - (int) (sizeof (pri->pFirst) * 2U), - (unsigned long) pri->pLast, - pri->pOwnerName); - pri = (rangeItem *) lstNext(&pri->node); - } - } - FASTUNLOCK(&addrListLock); - - return SUCCESS; -} - - -/* - * - * unsolicitedHandlerEPICS() - * what gets called if they disconnect from an - * interrupt and an interrupt arrives on the - * disconnected vector - * - */ -void unsolicitedHandlerEPICS(int vectorNumber) -{ - /* - * call logMsg() and not errMessage() - * so we are certain that printf() - * does not get called at interrupt level - */ - logMsg( - "%s: line=%d: Interrupt to EPICS disconnected vector = 0X %X", - (int)__FILE__, - __LINE__, - vectorNumber, - NULL, - NULL, - NULL); -} - - -/* - * - * initHandlerAddrList() - * init list of interrupt handlers to ignore - * - */ -LOCAL -void initHandlerAddrList(void) -{ - int i; - SYM_TYPE type; - int status; - - for(i=0; i> 1; - } - - while(bs > requestSize){ - pBlock = pBlockFirst; - while(pBlock <= pBlockLast-bs+1){ - pBlock += bs; - s = blockProbe(addrType, pBlock, pBlock+(requestSize-1)); - if(!s){ - *ppBase = pBlock; - return SUCCESS; - } - pBlock += bs; - } - bs = bs>>1; - } - return S_dev_deviceDoesNotFit; -} - - -/* - * blockProbe() - */ -LOCAL long blockProbe( -epicsAddressType addrType, -char *pFirst, -char *pLast -) -{ - char *pProbe; - int s; - - pProbe = pFirst; - while(pProbe <= pLast){ - s = locationProbe(addrType, pProbe); - if(s){ - return s; - } - pProbe++; - } - return SUCCESS; -} - - -/* - * locationProbe - */ -long locationProbe( -epicsAddressType addrType, -char *pLocation -) -{ - char *pPhysical; - int s; - - /* - * every byte in the block must - * map to a physical address - */ - if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert) - { - pPhysical = pLocation; - } - else - { - s = sysBusToLocalAdrs( - EPICStovxWorksAddrType[addrType], - pLocation, - &pPhysical); - if(s<0){ - return S_dev_vxWorksAddrMapFail; - } - } - - - { - int8_t *pChar; - int8_t byte; - - pChar = (int8_t *) pPhysical; - if(devPtrAlignTest(pChar)){ - s = vxMemProbe( - (char *) pChar, - READ, - sizeof(byte), - (char *) &byte); - if(s!=ERROR){ - return S_dev_addressOverlap; - } - } - } - { - int16_t *pWord; - int16_t word; - - pWord = (int16_t *)pPhysical; - if(devPtrAlignTest(pWord)){ - s = vxMemProbe( - (char *)pWord, - READ, - sizeof(word), - (char *) &word); - if(s!=ERROR){ - return S_dev_addressOverlap; - } - } - } - { - int32_t *pLongWord; - int32_t longWord; - - pLongWord = (int32_t *) pPhysical; - if(devPtrAlignTest(pLongWord)){ - s = vxMemProbe( - (char *)pLongWord, - READ, - sizeof(longWord), - (char *)&longWord); - if(s!=ERROR){ - return S_dev_addressOverlap; - } - } - } - - return SUCCESS; -} - -/****************************************************************************** - * - * The follwing may, or may not be present in the BSP for the CPU in use. - * - */ -void *sysA24Malloc(unsigned long size); -STATUS sysA24Free(void *pBlock); - -/****************************************************************************** - * - * Routines to use to allocate and free memory present in the A24 region. - * - ******************************************************************************/ - -static void * (*A24MallocFunc)(size_t) = NULL; -static void (*A24FreeFunc)(void *) = NULL; -int devLibA24Debug = 0; /* Debugging flag */ - -void *devLibA24Calloc(size_t size) -{ - void *ret; - - ret = devLibA24Malloc(size); - - if (ret == NULL) - return (NULL); - - memset(ret, 0x00, size); - return(ret); -} - -void *devLibA24Malloc(size_t size) -{ - SYM_TYPE stype; - static int UsingBSP = 0; - void *ret; - - if (devLibA24Debug) - logMsg("devLibA24Malloc(%d) entered\n", size, 0,0,0,0,0); - - if (A24MallocFunc == NULL) - { - /* See if the sysA24Malloc() function is present. */ - if(symFindByNameEPICS(sysSymTbl,"_sysA24Malloc", (char**)&A24MallocFunc,&stype)==ERROR) - { /* Could not find sysA24Malloc... use the malloc one and hope we are OK */ - if (devLibA24Debug) - logMsg("devLibA24Malloc() using regular malloc\n",0,0,0,0,0,0); - A24MallocFunc = malloc; - A24FreeFunc = free; - } - else - { - if(symFindByNameEPICS(sysSymTbl,"_sysA24Free", (char**)&A24FreeFunc, &stype) == ERROR) - { /* That's strange... we have malloc, but no free! */ - if (devLibA24Debug) - logMsg("devLibA24Malloc() using regular malloc\n",0,0,0,0,0,0); - A24MallocFunc = malloc; - A24FreeFunc = free; - } - else - UsingBSP = 1; - } - } - ret = A24MallocFunc(size); - - if ((ret == NULL) && (UsingBSP)) - errMessage(S_dev_noMemory, "devLibA24Malloc ran out of A24 memory, try sysA24MapRam(size)"); - - return(ret); -} - -void devLibA24Free(void *pBlock) -{ - if (devLibA24Debug) - logMsg("devLibA24Free(%p) entered\n", (unsigned long)pBlock,0,0,0,0,0); - - A24FreeFunc(pBlock); -} diff --git a/src/vxWorks/db/devLib.h b/src/vxWorks/db/devLib.h deleted file mode 100644 index d9967ca65..000000000 --- a/src/vxWorks/db/devLib.h +++ /dev/null @@ -1,234 +0,0 @@ -/* devLib.h */ -/* $Id$ */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - * - * 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 03-10-93 joh original - * .02 03-18-93 joh added fundamental address type mapping - * .03 03-23-93 joh changed input parameter to be a fund - * address type in favor of the argument - * that the BSP will be reconfigured - * to use an EPICS standard address - * mode - * .04 05-06-93 joh added new parameter to devDisconnectInterrupt(). - * See comment below. - * .05 05-28-93 joh Added an argument to devRegisterAddress() - * .06 05-28-93 joh Added devAddressMap() - * .07 06-14-93 joh Added devAllocAddress() - * - * Notes: - * ------ - * .01 03-23-93 joh We will only have problems with mod .03 - * above if the CPU maintains the different - * address modes in different address spaces - * and we have a card or a user that insists - * on not using the default address type - * .02 06-14-93 joh needs devAllocInterruptVector() routine - */ - - -#ifndef INCdevLibh -#define INCdevLibh 1 - -#if defined(devLibGlobal) && !defined(INCvmeh) -#include "vme.h" -#endif - -#include - -/* - * epdevAddressType & EPICStovxWorksAddrType - * devLib.c must change in unison - */ -typedef enum { - atVMEA16, - atVMEA24, - atVMEA32, - atISA, /* memory mapped ISA access (until now only on PC) */ - atLast /* atLast must be the last enum in this list */ - } epicsAddressType; - -#ifdef devLibGlobal -char *epicsAddressTypeName[] - = { - "VME A16", - "VME A24", - "VME A32", - "ISA" - }; -#endif - -/* - * we use a translation between an EPICS encoding - * and a vxWorks encoding here - * to reduce dependency of drivers on vxWorks - * - * we assume that the BSP are configured to use these - * address modes by default - */ -#define EPICSAddrTypeNoConvert -1 -#ifdef devLibGlobal -int EPICStovxWorksAddrType[] - = { - VME_AM_SUP_SHORT_IO, - VME_AM_STD_SUP_DATA, - VME_AM_EXT_SUP_DATA, - EPICSAddrTypeNoConvert - }; -#endif - -long devAddressMap(void); /* print an address map */ - -long devRegisterAddress( - const char *pOwnerName, - epicsAddressType addrType, - void *baseAddress, - unsigned long size, /* bytes */ - void **pLocalAddress); - -long devUnregisterAddress( - epicsAddressType addrType, - void *baseAddress, - const char *pOwnerName); - -/* - * allocate and register an unoccupied address block - */ -long devAllocAddress( - const char *pOwnerName, - epicsAddressType addrType, - unsigned long size, - unsigned alignment, /*n ls bits zero in addr*/ - void **pLocalAddress); - -/* - * some CPU`s will maintain these in independent spaces - */ -typedef enum {intCPU, intVME, intVXI} epicsInterruptType; -long devConnectInterrupt( - epicsInterruptType intType, - unsigned vectorNumber, - void (*pFunction)(), - void *parameter); - - -/* - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from inadvertently - * removing an interrupt handler that it didn't install - */ -long devDisconnectInterrupt( - epicsInterruptType intType, - unsigned vectorNumber, - void (*pFunction)()); - -long devEnableInterruptLevel( - epicsInterruptType intType, - unsigned level); - -long devDisableInterruptLevel( - epicsInterruptType intType, - unsigned level); - - -/* - * Routines to allocate and free memory in the A24 memory region. - * - */ -void *devLibA24Malloc(size_t); -void *devLibA24Calloc(size_t); -void devLibA24Free(void *pBlock); - -/* - * Normalize a digital value and convert it to type TYPE - * - * Ex: - * float f; - * int d; - * f = devNormalizeDigital(d,12) - * - */ -#define devCreateMask(NBITS) ((1<<(NBITS))-1) -#define devDigToNml(DIGITAL,NBITS) \ - (((double)(DIGITAL))/devCreateMask(NBITS)) -#define devNmlToDig(NORMAL,NBITS) \ - (((long)(NORMAL)) * devCreateMask(NBITS)) - -/* - * - * Alignment mask - * (for use when testing to see if the proper number of least - * significant bits are zero) - * - */ -#define devCreateAlignmentMask(CTYPE)\ -(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1) - -/* - * pointer aligned test - * (returns true if the pointer is on the worst case alignemnt - * boundary for its type) - */ -#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR))) - -/* - * error codes (and messages) associated with devLib.c - */ -#define S_dev_vectorInUse (M_devLib| 1) /*Interrupt vector in use*/ -#define S_dev_vxWorksVecInstlFail (M_devLib| 2) /*vxWorks interrupt vector install failed*/ -#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/ -#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/ -#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/ -#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/ -#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/ -#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/ -#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/ -#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/ -#define S_dev_vxWorksAddrMapFail (M_devLib| 11) /*vxWorks refused address map*/ -#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/ -#define S_dev_internal (M_devLib| 13) /*Internal failure*/ -#define S_dev_vxWorksIntEnFail (M_devLib| 14) /*vxWorks interrupt enable failure*/ -#define S_dev_vxWorksIntDissFail (M_devLib| 15) /*vxWorks interrupt disable failure*/ -#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/ -#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/ -#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/ -#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/ -#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/ -#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/ -#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/ -#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/ -#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/ -#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/ -#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/ -#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/ -#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/ -#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/ -#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/ -#endif /* devLib.h*/ diff --git a/src/vxWorks/db/devLibVxWorks.c b/src/vxWorks/db/devLibVxWorks.c deleted file mode 100644 index 983ae6aa1..000000000 --- a/src/vxWorks/db/devLibVxWorks.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * devLibVxWorks.c - * @(#)$Id$ - * - * Archictecture dependent support for common device driver resources - * - * Author: Jeff Hill - * Date: 10-30-98 - * - * 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 - * - */ - -static char *sccsID = "@(#) $Id$"; - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "devLib.h" -#include "epicsDynLink.h" - -/* - * A list of the names of the unexpected interrupt handlers - * ( some of these are provided by wrs ) - */ -LOCAL char *defaultHandlerNames[] = { - "_excStub", - "_excIntStub", - "_unsolicitedHandlerEPICS"}; - -typedef void myISR (void *pParam); -LOCAL myISR *defaultHandlerAddr[NELEMENTS(defaultHandlerNames)]; - -LOCAL myISR *isrFetch(unsigned vectorNumber); - -/* - * this routine needs to be in the symbol table - * for this code to work correctly - */ -void unsolicitedHandlerEPICS(int vectorNumber); - -/* - * this is in veclist.c - */ -int cISRTest(void (*)(), void (**)(), void **); - -/* - * we use a translation between an EPICS encoding - * and a vxWorks encoding here - * to reduce dependency of drivers on vxWorks - * - * we assume that the BSP are configured to use these - * address modes by default - */ -#define EPICSAddrTypeNoConvert -1 -int EPICStovxWorksAddrType[] - = { - VME_AM_SUP_SHORT_IO, - VME_AM_STD_SUP_DATA, - VME_AM_EXT_SUP_DATA, - EPICSAddrTypeNoConvert - }; - -LOCAL void initHandlerAddrList(void); - -/* - * maps logical address to physical address, but does not detect - * two device drivers that are using the same address range - */ -LOCAL long vxDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress); - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue); - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); - -/* - * used by dynamic bind in devLib.c - */ -const struct devLibVirtualOS devLibVirtualOS = - {vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe, - devConnectInterruptVME, devDisconnectInterruptVME}; - -#define SUCCESS 0 - -/* - * devConnectInterruptVME - * - * wrapper to minimize driver dependency on vxWorks - */ -long devConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter) -{ - int status; - - - if (devInterruptInUseVME(vectorNumber)) { - return S_dev_vectorInUse; - } - status = intConnect( - (void *)INUM_TO_IVEC(vectorNumber), - pFunction, - (int) parameter); - if (status<0) { - return S_dev_vecInstlFail; - } - - return SUCCESS; -} - -/* - * - * devDisconnectInterruptVME() - * - * wrapper to minimize driver dependency on vxWorks - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from removing - * an interrupt handler that was installed by another driver - * - */ -long devDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -) -{ - void (*psub)(); - int status; - - /* - * If pFunction not connected to this vector - * then they are probably disconnecting from the wrong vector - */ - psub = isrFetch(vectorNumber); - if(psub != pFunction){ - return S_dev_vectorNotInUse; - } - - status = intConnect( - (void *)INUM_TO_IVEC(vectorNumber), - unsolicitedHandlerEPICS, - (int) vectorNumber); - if(status<0){ - return S_dev_vecInstlFail; - } - - return SUCCESS; -} - -/* - * devEnableInterruptLevel() - * - * wrapper to minimize driver dependency on vxWorks - */ -long devEnableInterruptLevel( -epicsInterruptType intType, -unsigned level) -{ - int s; - - switch (intType) { - case intVME: - case intVXI: - s = sysIntEnable (level); - if(s!=OK){ - return S_dev_intEnFail; - } - break; - case intISA: -# if CPU == I80386 - s = sysIntEnablePIC (level); - if (s!=OK) { - return S_dev_intEnFail; - } -# endif - default: - return S_dev_uknIntType; - } - - return SUCCESS; -} - -/* - * devDisableInterruptLevel() - * - * wrapper to minimize driver dependency on vxWorks - */ -long devDisableInterruptLevel ( -epicsInterruptType intType, -unsigned level) -{ - int s; - - switch (intType) { - case intVME: - case intVXI: - s = sysIntDisable (level); - if(s!=OK){ - return S_dev_intDissFail; - } - break; - case intISA: -# if CPU == I80386 - s = sysIntDisablePIC (level); - if (s!=OK) { - return S_dev_intEnFail; - } -# endif - default: - return S_dev_uknIntType; - } - - return SUCCESS; -} - -/* - * vxDevMapAddr () - */ -LOCAL long vxDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress) -{ - long status; - - if (ppPhysicalAddress==NULL) { - return S_dev_badArgument; - } - - if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert) - { - *ppPhysicalAddress = (void *) logicalAddress; - } - else - { - status = sysBusToLocalAdrs (EPICStovxWorksAddrType[addrType], - (char *) logicalAddress, (char **)ppPhysicalAddress); - if (status) { - return S_dev_addrMapFail; - } - } - - return SUCCESS; -} - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) -{ - long status; - - /* - * this global variable exists in the nivxi library - */ - status = vxMemProbe ((char *)ptr, VX_READ, wordSize, (char *) pValue); - if (status!=OK) { - return S_dev_noDevice; - } - - return SUCCESS; -} - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) -{ - long status; - - /* - * this global variable exists in the nivxi library - */ - status = vxMemProbe ((char *)ptr, VX_READ, wordSize, (char *) pValue); - if (status!=OK) { - return S_dev_noDevice; - } - - return SUCCESS; -} - -/* - * isrFetch() - */ -LOCAL myISR *isrFetch(unsigned vectorNumber) -{ - myISR *psub; - myISR *pCISR; - void *pParam; - int s; - - /* - * fetch the handler or C stub attached at this vector - */ - psub = (myISR *) intVecGet((FUNCPTR *)INUM_TO_IVEC(vectorNumber)); - - /* - * from libvxWorks/veclist.c - * - * checks to see if it is a C ISR - * and if so finds the function pointer and - * the parameter passed - */ - s = cISRTest(psub, &pCISR, &pParam); - if(!s){ - psub = pCISR; - } - - return psub; -} - -/* - * determine if a VME interrupt vector is in use - */ -int devInterruptInUseVME (unsigned vectorNumber) -{ - static int init; - int i; - myISR *psub; - - if (!init) { - initHandlerAddrList(); - init = TRUE; - } - - psub = isrFetch (vectorNumber); - - /* - * its a C routine. Does it match a default handler? - */ - for (i=0; i LOCAL for debugging and many changes - * to the parser for resource.def so that we - * allow white space between tokens in env var - * - * Revision 1.7 1995/02/02 17:15:55 jbk - * Removed the stinking message "Cannot contact master timing IOC ". - * - * Revision 1.6 1995/02/01 15:29:54 winans - * Added a type field to the configure command to disable the use of the event - * system hardware if desired. - * - * Revision 1.5 1994/12/16 15:51:21 winans - * Changed error message in the event system error handler & added a conditional - * based on a debug flag to print it... defaults to off. (Per request from MRK.) - * - * Revision 1.4 1994/10/28 20:15:10 jbk - * increased the USP packet time-out to 250ms, added a parm to the configure() - * routine to let user specify it. - * - */ - -/************************************************************************** - * - * Author: Jim Kowalkowski - * - * Modification Log: - * ----------------- - * .01 01-06-94 jbk initial version - * .02 03-01-94 jbk magic # in packets, network byte order check - * .03 03-02-94 jbk current time always uses 1 tick watch dog update - * .04 17MAR98 mrk Make safe to year 2104 - * .05 17MAR98 mrk change nanosec conversion - * .06 04AUG98 mrk make TSsetClockFromUnix external - sync master - * - ***********************************************************************/ - -#define MAKE_DEBUG TSdriverDebug -#define TS_DRIVER 1 - -#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 "envDefs.h" -#include "envLib.h" -#include "dbDefs.h" -#include "epicsPrint.h" -#include "errMdef.h" -#include "drvSup.h" -#include "drvTS.h" -#include "bsdSocketResource.h" - -#define TSprintf epicsPrintf - -#define DEFAULT_TIME 0 -#define NO_EVENT_SYSTEM 1 - -/* functions used by this driver */ -static long TSgetUnixTime(struct timespec*); -static long TSgetMasterTime(struct timespec*); -static long TSgetBroadcastAddr(int soc, struct sockaddr*); -static int TSgetSocket(int port, struct sockaddr_in* sin); -static int TSgetBroadcastSocket(int port, struct sockaddr_in* sin); -static void TSsyncServer(); -static void TSsyncClient(); -static long TSasyncClient(); -static long TSsyncTheTime(struct timespec* cts, struct timespec* ts); -static long TSgetData(char* buf, int buf_size, int soc, - struct sockaddr* to_sin, struct sockaddr* from_sin, - struct timespec* round_trip); -static void TSaddStamp( struct timespec* result, - struct timespec* op1, struct timespec* op2); -static void TSwdIncTime(); -static void TSwdIncTimeSync(); -static void TSstampServer(); -static void TSeventHandler(int Card,int EventNum,unsigned long Ticks); -static void TSerrorHandler(int Card, int ErrorNum); -static long TSsetClockFromMaster(); -static void TSstartSoftClock(); -static long TScalcDiff(struct timespec* a, struct timespec* b, - struct timespec* diff); - -static long TSgetCurrentTime(struct timespec* ts); -static long TSforceSoftSync(int Card); -static long TSstartSyncServer(); -static long TSstartSyncClient(); -static long TSstartAsyncClient(); -static long TSstartStampServer(); -static long TSuserGetJunk(int event_number,struct timespec* sp); - -/* event system and time clock functions */ -static long (*TSregisterEventHandler)(int Card, void(*func)()); -static long (*TSregisterErrorHandler)(int Card, void(*func)()); -static long (*TSgetTicks)(int Card, unsigned long *Ticks); -static long (*TShaveReceiver)(int Card); -static long (*TSforceSync)(int Card); -static long (*TSgetTime)(struct timespec*); -static long (*TSsyncEvent)(); -static long (*TSdirectTime)(); -static long (*TSdriverInit)(); -static long (*TSuserGet)(int event_number,struct timespec* sp); - -/* global functions */ -#ifdef __cplusplus -extern "C" { -#endif -long TSinit(void); /* called by iocInit currently */ -long TSreport(); /* callable from vxWorks shell */ - -/* test functions */ -void TSprintRealTime(); -void TSprintUnixTime(); -void TSprintMasterTime(); -void TSprintTimeStamp(int event_number); -void TSprintCurrentTime(); -#ifdef __cplusplus -} -#endif - -/* data used by all */ -TSinfo TSdata = -{ TS_master_dead, TS_async_slave, TS_async_none, - 0,NULL, - TS_SYNC_RATE_SEC,TS_CLOCK_RATE_HZ,0,TS_TIME_OUT_MS,0, - TS_MASTER_PORT,TS_SLAVE_PORT,1,0,0,0,0, - NULL, {NULL}, {NULL} -}; - -extern char* sysBootLine; - -int TSdirectTimeVar = 0; /* aother way to indicate direct time */ -int TSgoodTimeStamps = 0; /* a way to force use of accurate time stamps */ - -static WDOG_ID wd; -static long correction_factor = 0; -static long correction_count = 0; - - -/* static long TSreturnError() { return -1; } */ -static long TSdirectTimeError() { return -1; } -static long TShaveReceiverError(int i) { return -1; } -static long TSgetTicksError(int i,unsigned long* t) { return -1; } - -static long TSregisterErrorHandlerError(int i, void(*f)()) - { if(TSdata.has_direct_time==1) return 0; else return -1; } -static long TSregisterEventHandlerError(int i, void(*f)()) - { if(TSdata.has_direct_time==1) return 0; else return -1; } - - -long TSdriverInitError() -{ - struct timespec ts; - time_t t; - - clock_gettime(CLOCK_REALTIME,&ts); - time(&t); - Debug(1,"vxWorks time = %s\n",ctime(&t)); - - return 0; -} - -unsigned long TSepochNtpToUnix(struct timespec* ts) -{ - unsigned long nfssecs = (unsigned long)ts->tv_sec; - unsigned long secs = 0; - - /*If high order bit is not set then nfssecs has overflowed */ - if(!(nfssecs & 0x80000000ul)) { - /*secs = nfssecs - TS_1900_TO_VXWORKS_EPOCH + 2**32 */ - /* in order to prevent overflows rearrange as */ - /* secs = (2**32 -1) - TS_1900_TO_VXWORKS_EPOCH + nfssecs +1 */ - secs = 0xffffffffUL - TS_1900_TO_VXWORKS_EPOCH + nfssecs +1; - } else { - secs = nfssecs - TS_1900_TO_VXWORKS_EPOCH; - } - return(secs); -} - -unsigned long TSfractionToNano(unsigned long fraction) -{ - double value; - - /*value = 1e9 * fraction / 2**32 */ - value = (1e9 * (double)fraction)/4294967296.0; - return((unsigned long)value); -} - -unsigned long TSepochNtpToEpics(struct timespec* ts) -{ - unsigned long nfssecs = (unsigned long)ts->tv_sec; - unsigned long secs = 0; - - /*If high order bit is not set then nfssecs has overflowed */ - if(!(nfssecs & 0x80000000ul)) { - /*secs = nfssecs - TS_1900_TO_EPICS_EPOCH + 2**32 */ - /* in order to prevent overflows rearrange as */ - /* secs = (2**32 -1) - TS_1900_TO_EPICS_EPOCH + nfssecs +1 */ - secs = 0xffffffffUL - TS_1900_TO_EPICS_EPOCH + nfssecs +1; - } else { - secs = nfssecs - TS_1900_TO_EPICS_EPOCH; - } - return(secs); -} - -unsigned long TSepochUnixToEpics(struct timespec* ts) -{ - unsigned long unixsecs = (unsigned long)ts->tv_sec; - unsigned long secs; - - secs = unixsecs - TS_VXWORKS_TO_EPICS_EPOCH; - return(secs); -} - -unsigned long TSepochEpicsToUnix(struct timespec* ts) -{ - unsigned long epicssecs = (unsigned long)ts->tv_sec; - unsigned long secs; - - secs = epicssecs + TS_VXWORKS_TO_EPICS_EPOCH; - return(secs); -} - -/*-----------------------------------------------------------------------*/ -/* - TSreport() - report information about the state of the time stamp - support software -*/ -long TSreport() -{ - char buf[64]; - - switch(TSdata.type) - { - case TS_direct_master: TSprintf("Direct timing master\n"); break; - case TS_sync_master: TSprintf("Event timing master\n"); break; - case TS_async_master: TSprintf("Soft timing master\n"); break; - case TS_direct_slave: TSprintf("Direct timing slave\n"); break; - case TS_sync_slave: TSprintf("Event timing slave\n"); break; - case TS_async_slave: TSprintf("Soft timing slave\n"); break; - default: break; - } - switch(TSdata.state) - { - case TS_master_alive: TSprintf("Master timing IOC alive\n"); break; - case TS_master_dead: TSprintf("Master timing IOC dead\n"); break; - default: break; - } - switch(TSdata.async_type) - { - case TS_async_none: TSprintf("No clock synchronization\n"); break; - case TS_async_private: TSprintf("Sync protocol with master\n"); break; - case TS_async_ntp: TSprintf("NTP sync with unix server\n"); break; - case TS_async_time: TSprintf("Time protocol sync with unix\n"); break; - default: break; - } - TSprintf("Clock Rate in Hertz = %lu\n",TSdata.clock_hz); - TSprintf("Sync Rate in Seconds = %lu\n",TSdata.sync_rate); - TSprintf("Master communications port = %d\n",TSdata.master_port); - TSprintf("Slave communications port = %d\n",TSdata.slave_port); - TSprintf("Total events supported = %d\n",TSdata.total_events); - TSprintf("Request Time Out = %lu milliseconds\n",TSdata.time_out); - - ipAddrToA ((struct sockaddr_in*)&TSdata.hunt, buf, sizeof(buf)); - TSprintf("Broadcast address: %s\n", buf); - ipAddrToA ((struct sockaddr_in*)&TSdata.master, buf, sizeof(buf)); - TSprintf("Master address: %s\n", buf); - - if(TSdata.UserRequestedType) - TSprintf("\nForced to not use the event system\n"); - - if(TSdata.has_direct_time) - TSprintf("Event system has time directly available\n"); - return 0; -} - -/*-----------------------------------------------------------------------*/ -/* - TSconfigure() - This is the configuration routine which is meant to - be called from the vxWorks startup.cmd script before iocInit. - It's job is to set operating parameters for the time stamp support code. - - JRW -- if type = 0, then try to config using event system - if type = 1, then permanantly inhibit use of the event system -*/ -void TSconfigure(int master, int sync_rate_sec, int clock_rate_hz, - int master_port, int slave_port, unsigned long time_out, int type) -{ - if(master) TSdata.master_timing_IOC=1; - else TSdata.master_timing_IOC=0; - - if(sync_rate_sec) TSdata.sync_rate=sync_rate_sec; - else TSdata.sync_rate=TS_SYNC_RATE_SEC; - - if(clock_rate_hz) TSdata.clock_hz=clock_rate_hz; - else TSdata.clock_hz=TS_CLOCK_RATE_HZ; - - TSdata.clock_conv= TS_BILLION / TSdata.clock_hz; - - if(master_port) TSdata.master_port=master_port; - else TSdata.master_port=TS_MASTER_PORT; - - if(slave_port) TSdata.slave_port=slave_port; - else TSdata.slave_port=TS_SLAVE_PORT; - - if(time_out) TSdata.time_out=time_out; - else TSdata.time_out=TS_TIME_OUT_MS; - - switch(type) - { - case DEFAULT_TIME: - case NO_EVENT_SYSTEM: - TSdata.UserRequestedType = type; - break; - default: - TSprintf("Invalid type parameter <%d> must be:\n",type); - TSprintf(" 0 = default time system\n"); - TSprintf(" 1 = force no event system\n"); - TSdata.UserRequestedType = 0; - break; - } - - return; -} - -/* - this sucks, but who cares, user should not be using event number if not - prepared to handle them by defining an ErUserGetTimeStamp() routine. -*/ -static long TSuserGetJunk(int event_number,struct timespec* sp) -{ - return TSgetTimeStamp(0,sp); -} - -/*-----------------------------------------------------------------------*/ -/* - TSgetTimeStamp() - This routine returns the time stamp which represents - the time when an event event_number occurred. Soft timing will always - return the current time. Event zero will always return the current time - also. -*/ -long TSgetTimeStamp(int event_number,struct timespec* sp) -{ - /* this is questionable, a sync slave with a dead master will have - an invalid time stamp, so use the vxworks clock. Also remember that - the IOC vxWorks clock may not be in sync with time stamps if - default TSgetTime() in use and master failure is detected */ - - switch(TSdata.type) - { - case TS_async_master: - case TS_async_slave: - if(event_number<=0) - *sp = TSdata.event_table[TSdata.sync_event]; - else - return TSuserGet(event_number,sp); - break; - case TS_direct_slave: - case TS_direct_master: - TSgetTime(sp); - break; - case TS_sync_slave: - case TS_sync_master: - switch(event_number) - { - case 0: - if(TSgoodTimeStamps==0) - { - /* one tick watch dog maintains */ - *sp = TSdata.event_table[0]; - break; - } - case -1: - { - struct timespec ts; - unsigned long ticks; - - TSgetTicks(0,&ticks); /* add in the board time */ - *sp = TSdata.event_table[TSdata.sync_event]; - - /* calculate a time stamp from the tick count */ - ts.tv_sec = ticks / TSdata.clock_hz; - ts.tv_nsec=(ticks-(ts.tv_sec*TSdata.clock_hz))* - TSdata.clock_conv; - - sp->tv_sec += ts.tv_sec; - sp->tv_nsec += ts.tv_nsec; - - /* adjust seconds if needed */ - if(sp->tv_nsec >= TS_BILLION) - { - sp->tv_sec++; - sp->tv_nsec -= TS_BILLION; - } - } - break; - default: - if(TSdata.state==TS_master_dead) - TSgetTime(sp); - else - *sp = TSdata.event_table[event_number]; - break; - } - break; - default: - if(event_number==0) - *sp = TSdata.event_table[TSdata.sync_event]; - else - *sp = TSdata.event_table[event_number]; - } - return 0; -} - -/*-----------------------------------------------------------------------*/ -/* - TSinit() - initialize the driver, determine mode. -*/ -long TSinit(void) -{ - SYM_TYPE stype; - char tz[100],min_west[20]; - - Debug0(5,"In TSinit()\n"); - - /* 0=default, 1=none, 2=direct */ - - if( TSdata.UserRequestedType==DEFAULT_TIME) - { - /* default configuration probe */ - /* ------------------------------------------------------------- */ - /* find the lower level event system functions */ - if(symFindByNameEPICS(sysSymTbl,"_ErHaveReceiver", - (char**)&TShaveReceiver,&stype)==ERROR) - TShaveReceiver = TShaveReceiverError; - if(symFindByNameEPICS(sysSymTbl,"_ErGetTicks", - (char**)&TSgetTicks,&stype)==ERROR) - TSgetTicks = TSgetTicksError; - - if(symFindByNameEPICS(sysSymTbl,"_ErRegisterEventHandler", - (char**)&TSregisterEventHandler,&stype)==ERROR) - TSregisterEventHandler = TSregisterEventHandlerError; - - if(symFindByNameEPICS(sysSymTbl,"_ErRegisterErrorHandler", - (char**)&TSregisterErrorHandler,&stype)==ERROR) - TSregisterErrorHandler = TSregisterErrorHandlerError; - - if(symFindByNameEPICS(sysSymTbl,"_ErForceSync", - (char**)&TSforceSync,&stype)==ERROR) - TSforceSync = TSforceSoftSync; - - if(symFindByNameEPICS(sysSymTbl,"_ErDirectTime", - (char**)&TSdirectTime,&stype)==ERROR) - TSdirectTime = TSdirectTimeError; - - if(symFindByNameEPICS(sysSymTbl,"_ErDriverInit", - (char**)&TSdriverInit,&stype)==ERROR) - TSdriverInit = TSdriverInitError; - - if(symFindByNameEPICS(sysSymTbl,"_ErGetTime", - (char**)&TSgetTime,&stype)==ERROR) - TSgetTime = TSgetCurrentTime; - - if(symFindByNameEPICS(sysSymTbl,"_ErUserGetTimeStamp", - (char**)&TSuserGet,&stype)==ERROR) - TSuserGet = TSuserGetJunk; - - if(symFindByNameEPICS(sysSymTbl,"_ErSyncEvent", - (char**)&TSsyncEvent,&stype)==ERROR) - TSdata.sync_event=ER_EVENT_RESET_TICK; - else - TSdata.sync_event=TSsyncEvent(); - - /* ------------------------------------------------------------- */ - } - else - { - /* inhibit probe and use of the event system */ - TSprintf("WARNING: drvTS event hardware probe inhibited by user\n"); - TShaveReceiver = TShaveReceiverError; - TSgetTicks = TSgetTicksError; - TSregisterEventHandler = TSregisterEventHandlerError; - TSregisterErrorHandler = TSregisterErrorHandlerError; - TSforceSync = TSforceSoftSync; - TSgetTime = TSgetCurrentTime; - TSdriverInit = TSdriverInitError; - TSdirectTime = TSdirectTimeError; - TSdata.sync_event=ER_EVENT_RESET_TICK; - } - - /* set all the known information about the system */ - TSdata.event_table=NULL; - TSdata.ts_sync_valid=0; /* the sync time stamp invalid */ - TSdata.state=TS_master_dead; - TSdata.sync_occurred = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY); - TSdata.has_event_system = 0; - TSdata.has_direct_time = 0; - TSdata.async_type=TS_async_none; - - if( (TSdata.total_events=TShaveReceiver(0))<=0) - { - Debug0(5,"TSinit() - no event receiver\n"); - TSdata.total_events=1; - TSdata.sync_event=0; - TSdata.clock_hz=sysClkRateGet(); - TSdata.clock_conv=TS_BILLION / TSdata.clock_hz; - TSdata.has_event_system = 0; - } - else - TSdata.has_event_system = 1; - - if(TSdirectTime()>0 || TSdirectTimeVar>0) TSdata.has_direct_time=1; - - /* allocate the event table */ - TSdata.event_table=(struct timespec*)malloc( - TSdata.total_events*sizeof(struct timespec)); - - if(TSdata.master_timing_IOC) - { - /* master */ - Debug0(5,"TSinit() - I am master\n"); - if(TSdata.has_direct_time) - { - TSdata.type=TS_direct_master; - } - else - { - if(TSdata.has_event_system) - TSdata.type=TS_sync_master; - else - TSdata.type=TS_async_master; - } - } - else - { - /* slave */ - Debug0(5,"TSinit() - I am slave\n"); - if(TSdata.has_direct_time) - { - TSdata.type=TS_direct_slave; - } - else - { - if(TSdata.has_event_system) - TSdata.type=TS_sync_slave; - else - TSdata.type=TS_async_slave; - } - } - - /* set up the event system hooks */ - if(TSdata.has_event_system) - { - /* register the event handler function */ - if(TSregisterEventHandler(0,TSeventHandler)!=0) - { - TSprintf("Failed to register event handler\n"); - return -1; - } - - /* register the error handler function */ - if(TSregisterErrorHandler(0,TSerrorHandler)!=0) - { - TSprintf("Failed to register error handler\n"); - return -1; - } - } - - /* always start the soft clock */ - if(TSdata.has_direct_time==0) TSstartSoftClock(); - - /* get time from boot server Unix system */ - if(TSdata.master_timing_IOC) - { - /* master */ - if(TSsetClockFromUnix()<0) - { - /* bad, cannot get time - accessing starts ticking */ - struct timespec tp; - clock_gettime(CLOCK_REALTIME,&tp); - TSprintf("Failed to set clock from Unix server\n"); - } - Debug0(5,"TSinit() - tried to get clock from unix\n"); - - /* start the time stamp info server */ - if(TSstartStampServer()==ERROR) - { - TSprintf("Failed to start stamp server\n"); - return -1; - } - Debug0(5,"TSinit() - stamp server started \n"); - - TSdata.state = TS_master_alive; - - /* a direct master may be capable of delivering sync time stamps? */ - if(TSdata.type==TS_sync_master) - { - /* start the sync udp server */ - if(TSstartSyncServer()==ERROR) - { - TSprintf("Failed to start sync server\n"); - return -1; - } - Debug0(5,"TSinit() - sync server started \n"); - } - } - else - { - /* slave */ - if(TSsetClockFromUnix()<0) - { - struct timespec tp; - clock_gettime(CLOCK_REALTIME,&tp); - /* this should work */ - TSprintf("Failed to set time from Unix server\n"); - } - - if( TSsetClockFromMaster()<0 ) - { - /* do nothing here */ - /* TSprintf("Could not contact a master timing IOC\n"); */ - } - else - TSdata.state = TS_master_alive; - - if(TSdata.type==TS_async_slave) - { - /* this task syncs with master or unix */ - if(TSstartAsyncClient()==ERROR) - { - TSprintf("Failed to start async client\n"); - return -1; - } - Debug0(5,"TSinit() - async client started \n"); - } - else - { - /* this task sync with master */ - if(TSstartSyncClient()==ERROR) - { - TSprintf("Failed to start sync client\n"); - return -1; - } - Debug0(5,"TSinit() - sync client started \n"); - } - } - - /* - This section sets up the vxWorks clock for use with the ansiLib - functions. The TIMEZONE environment variable for vxWorks is only - overwritten if it has not been set. It seems as though the day - light saving time does not work (at least following the directions - in ansiLib). - - The EPICS environment variable EPICS_TS_MIN_WEST holds the minutes - west of GMT (UTC) time. This variable should be preset by the EPICS - administrator for your site. - */ - - if(getenv("TIMEZONE")==(char*)NULL) - { - if(envGetConfigParam(&EPICS_TS_MIN_WEST,sizeof(min_west),min_west)==NULL - || strlen(min_west)==0) - { - TSprintf("TS initialization: No Time Zone Information\n"); - } - else - { - sprintf(tz,"TIMEZONE=UTC::%s:040102:100102",min_west); - if(putenv(tz)==ERROR) - { - TSprintf("TS initialization: TIMEZONE putenv failed\n"); - } - } - } - - TSdriverInit(); /* Call the user's driver initialization if supplied */ - return 0; -} - -/* following are watch dog routines for soft time support */ - -static void TSstartSoftClock() /*start the soft clock watch dog*/ -{ - /* simple watch dog to fire off syncs to slaves */ - Debug(5,"start watch dog at rate %ld\n", - (long) sysClkRateGet()*TSdata.sync_rate); - wd = wdCreate(); - if(TSdata.has_event_system) - { - Debug0(8,"Starting sync time watch dog\n"); - wdStart(wd,1,(FUNCPTR)TSwdIncTimeSync,NULL); - } - else - { - Debug0(8,"Starting async time watch dog\n"); - wdStart(wd,1,(FUNCPTR)TSwdIncTime,NULL); - } - return; -} - -/* NOTE: TSwdIncTime called at interrupt level! */ -static void TSwdIncTime() /*increment the time stamp at a 60 Hz rate*/ -{ - int key; - - wdStart(wd,1, (FUNCPTR)TSwdIncTime,NULL); - /* update the event table */ - key=intLock(); - - if(correction_count) - { - long nsec = TSdata.event_table[TSdata.sync_event].tv_nsec - + TSdata.clock_conv; - nsec += correction_factor; - if(nsec<0) { - nsec += TS_BILLION; - TSdata.event_table[TSdata.sync_event].tv_sec--; - } - TSdata.event_table[TSdata.sync_event].tv_nsec = nsec; - if(--correction_count == 0) correction_factor = 0; - } - else - TSdata.event_table[TSdata.sync_event].tv_nsec += - TSdata.clock_conv; - - /* adjust seconds if needed */ - if(TSdata.event_table[TSdata.sync_event].tv_nsec >= TS_BILLION) - { - TSdata.event_table[TSdata.sync_event].tv_sec++; - TSdata.event_table[TSdata.sync_event].tv_nsec -= TS_BILLION; - } - intUnlock(key); - return; -} - -static void TSwdIncTimeSync() -{ - wdStart(wd,1, (FUNCPTR)TSwdIncTimeSync,NULL); - TSaccurateTimeStamp(&TSdata.event_table[0]); -} - -/* following are all interrupt service routines */ - -/* - TSeventHandler() - receive events from event system; update the event table - - Note: called at interrupt level! -*/ -static void TSeventHandler(int Card,int EventNum,unsigned long Ticks) -{ - struct timespec ts; - struct timespec* st; - int key; - -#ifdef DIRECT_WITH_EVENTS - if(TSdata.has_direct_time==1) - { - TSgetTime(&ts); - key=intLock(); - TSdata.event_table[EventNum].tv_sec = ts.tv_sec; - TSdata.event_table[EventNum].tv_nsec = ts.tv_nsec; - intUnlock(key); - return; - } -#endif - - /* calculate a time stamp from the Tick count */ - ts.tv_sec = Ticks / TSdata.clock_hz; - ts.tv_nsec = (Ticks - (ts.tv_sec * TSdata.clock_hz)) * TSdata.clock_conv; - /* obtain a copy of the last sync time */ - st = &TSdata.event_table[TSdata.sync_event]; - /* update the event table */ - key=intLock(); - TSdata.event_table[EventNum].tv_sec = st->tv_sec + ts.tv_sec; - TSdata.event_table[EventNum].tv_nsec = st->tv_nsec + ts.tv_nsec; - /* adjust seconds if needed */ - if(TSdata.event_table[EventNum].tv_nsec >= TS_BILLION) - { - TSdata.event_table[EventNum].tv_sec++; - TSdata.event_table[EventNum].tv_nsec -= TS_BILLION; - } - intUnlock(key); - /* signal a time stamp sync if this is sync event */ - if(TSdata.type==TS_sync_master && EventNum==TSdata.sync_event) - { - /* validate the soft time for back off in case of event system - failure, this will not be done in first implementation */ - - /* tell broadcast server to send out sync */ - semGive(TSdata.sync_occurred); - } - return; -} - -/* TSerrorHandler() - receive errors from event system - Note: called at interrupt level! -*/ -static void TSerrorHandler(int Card, int ErrorNum) -{ - /* probably should do the following: - mark a "bad" state - timestamp is invalid, - send a request for sync to master, - if sync doesn't come when in bad state, then install - clock hook to increment time stamp until event system back up - keep a count of errors - Could put the slave on the vxworks timer until next sync - */ - - if(MAKE_DEBUG) - { - switch(ErrorNum) - { - case 1: - logMsg("***TSerrorHandler: event system error: TAXI violation", - 0,0,0,0,0,0); - break; - case 2: - logMsg("***TSerrorHandler: event system error: lost heartbeat", - 0,0,0,0,0,0); - break; - case 3: - logMsg("***TSerrorHandler: event system error: lost events", - 0,0,0,0,0,0); - break; - default: - logMsg("***TSerrorHandler: unknown error %d from event system", - ErrorNum,0,0,0,0,0); - } - } - return; -} - -/**************************************************************************/ -/* the following are utilities for initially getting and setting the time */ -/**************************************************************************/ -/* - TSgetUnixTime() - ask the boot server for the time using the - time protocol. This is only the time to the nearest second - A better way would be to use the NTP transactions to boot server -*/ - -static long TSgetUnixTime(struct timespec* ts) -{ - BOOT_PARAMS bootParms; - unsigned long buf_data,timeValue; - TS_NTP buf_ntp; - struct sockaddr_in sin; - int soc; - char host_addr[BOOT_ADDR_LEN]; - int status; - - Debug0(2,"in TSgetUnixTime()\n"); - if(envGetConfigParam(&EPICS_TS_NTP_INET,BOOT_ADDR_LEN,host_addr)==NULL || - strlen(host_addr)==0) - { - /* use boot host if the environment variable not set */ - bootStringToStruct(sysBootLine,&bootParms); - /* bootParms.had = host IP address */ - strncpy(host_addr,bootParms.had,BOOT_ADDR_LEN); - } - if( (soc=TSgetSocket(0,&sin)) <0) - { Debug0(1,"TSgetsocket failed\n"); return -1; } - - /* set up for ntp transaction to boot server */ - Debug(5,"host addr = %s\n",host_addr); - - /* well known registered NTP port - or whatever port they specify */ - status = aToIPAddr (host_addr, UDP_NTP_PORT, &sin); - if (status) { - Debug0(2,"bad host name or IP address\n"); - TSdata.async_type=TS_async_none; - close(soc); - return -1; - } - - TSdata.async_type=TS_async_ntp; - memset(&buf_ntp,0,sizeof(buf_ntp)); - buf_ntp.info[0]=0x0b; - if(TSgetData((char*)&buf_ntp,sizeof(buf_ntp),soc, - (struct sockaddr*)&sin,NULL,NULL)<0) - { - Debug0(2,"no reply from NTP server\n"); - /* well known registered time port */ - sin.sin_port = htons(UDP_TIME_PORT); - TSdata.async_type=TS_async_time; - buf_data=0; - if(TSgetData((char*)&buf_data,sizeof(buf_data),soc, - (struct sockaddr*)&sin,NULL,NULL)<0) - { - Debug0(2,"no reply from Time server\n"); - TSdata.async_type=TS_async_none; - close(soc); - return -1; - } - } - /* remember: time and NTP protocol return seconds since 1900, not 1970 */ - /* to convert sec = timeValue - TS_1900_TO_EPICS_EPOCH */ - if(TSdata.async_type==TS_async_time) - { - /* this is time protocol */ - timeValue=ntohl(buf_data); - ts->tv_sec = timeValue; - ts->tv_nsec = 0; - Debug(2,"got the Time protocol time %lu= \n",timeValue); - } - else - { - /* this is ntp - need to convert to ns */ - ts->tv_sec=ntohl(buf_ntp.transmit_ts.tv_sec); - timeValue=ntohl(buf_ntp.transmit_ts.tv_nsec); - ts->tv_nsec = TSfractionToNano(timeValue); - if(MAKE_DEBUG>=2) - TSprintf("got the NTP time %9.9lu.%9.9lu\n",ts->tv_sec,timeValue); - } - close(soc); - return 0; -} - -/* - TSgetMasterTime() - query the master timing IOC for it's current time - This routine will be converted to a task and block on a semaphore, - when it gets the semaphore, it will go to the master timing IOC - and get a time stamp, the time stamp will be used to adjust the - vxworks clock. To use it for software timing, just put a watchdog - out there that pokes the semaphore. Another way to manage soft - timing is to catch broadcasts from the master, round trip - calculations cannot be made when doing this. -*/ -static long TSgetMasterTime(struct timespec* tsp) -{ - TSstampTrans stran; - struct timespec curr_time,tran_time,send_time,recv_time; - struct sockaddr_in sin; - struct sockaddr fs; - int soc; - - Debug0(3,"TSgetMasterTime() called\n"); - - if( (soc=TSgetBroadcastSocket(0,&sin)) <0) - { Debug0(1,"TSgetBroadcastSocket failed\n"); return -1; } - sin.sin_port = htons(TSdata.master_port); - memcpy(&TSdata.hunt,&sin,sizeof(sin)); - stran.type=(TStype)htonl(TS_time_request); - stran.magic=htonl(TS_MAGIC); - - if(TSgetData((char*)&stran,sizeof(stran),soc, - (struct sockaddr*)&sin,&fs,&tran_time)<0) - { Debug0(2,"no reply from master server\n"); close(soc); return -1; } - - /* check the magic number */ - if(ntohl(stran.magic)!=(TS_MAGIC)) - { - - TSprintf("TSgetMasterTime: invalid packet received\n"); - close(soc); - return -1; - } - /* we now have several pieces of information: - the master's address, - the approximate round trip time, - and the master's processing time. */ - /* set the global data structure for information from master */ - Debug(8,"master port=%d\n",ntohs(((struct sockaddr_in*)&fs)->sin_port)); - TSdata.master = fs; - TSdata.state = TS_master_alive; - if(TSdata.type==TS_sync_slave) - { - TSdata.clock_hz = ntohl(stran.clock_hz); - TSdata.sync_rate = ntohl(stran.sync_rate); - TSdata.clock_conv = TS_BILLION / TSdata.clock_hz; - } - /* how long did it take to give transaction? */ - TScalcDiff(&send_time,&recv_time,&tran_time); - if(MAKE_DEBUG>=6) - { - TSprintf("round trip time: %9.9lu.%9.9lu\n", - tran_time.tv_sec,tran_time.tv_nsec); - TSprintf("master time: %9.9lu.%9.9lu\n", - stran.master_time.tv_sec,stran.master_time.tv_nsec); - } - tran_time.tv_nsec >>= 2; - tran_time.tv_sec >>= 2; - /* add half the round trip estimate to the time stamp from master */ - curr_time.tv_sec = ntohl(stran.current_time.tv_sec); - curr_time.tv_nsec = ntohl(stran.current_time.tv_nsec); - TSaddStamp(tsp,&curr_time,&tran_time); - close(soc); - return 0; -} - -/* - TSsetClockFromUnix() - query the time from boot server and set the - vxworks clock. -*/ -long TSsetClockFromUnix(void) -{ - struct timespec tp; - unsigned long ulongtemp; - - Debug0(3,"in TSsetClockFromUnix()\n"); - - if(TSgetUnixTime(&tp)!=0) return -1; - - ulongtemp = TSepochNtpToUnix(&tp); - tp.tv_sec = (long)ulongtemp; - - if(MAKE_DEBUG>=9) - TSprintf("set time: %9.9lu.%9.9lu\n", tp.tv_sec,tp.tv_nsec); - - /* set the vxWorks clock to the correct time */ - if(clock_settime(CLOCK_REALTIME,&tp)<0) - { Debug0(1,"clock_settime failed\n"); } - - /* adjust time to use the EPICS EPOCH of 1990 */ - /* this is wrong if leap seconds accounted for */ - ulongtemp = TSepochUnixToEpics(&tp); - tp.tv_sec = ulongtemp; - - /* set the EPICS event time table sync entry (current time) */ - TSdata.event_table[TSdata.sync_event]=tp; - - if(MAKE_DEBUG>=9) - TSprintf("epics time: %9.9lu.%9.9lu\n", - TSdata.event_table[TSdata.sync_event].tv_sec, - TSdata.event_table[TSdata.sync_event].tv_nsec); - - return 0; -} - -/* - TSsetClockFromMaster() - set the vxworks clock using the time from - the master timing IOC -*/ -static long TSsetClockFromMaster() -{ - struct timespec tp; - int key; - unsigned long secs; - - Debug0(3,"in TSsetClockFromMaster()\n"); - - if(TSgetMasterTime(&tp)<0) return -1; - - key=intLock(); - TSdata.event_table[TSdata.sync_event]=tp; - intUnlock(key); - - /* adjust time to use the Unix EPOCH of 1900 - not to good */ - /* making this adjustment is not so good */ - secs = TSepochEpicsToUnix(&tp); - tp.tv_sec = secs; - clock_settime(CLOCK_REALTIME,&tp); - - return 0; -} - -/**************************************************************************/ -/* broadcast socket creation utilites */ -/**************************************************************************/ - -/* - TSgetBroadcastSocket() - return a broadcast socket for a port, return - a sockaddr also. -*/ -static int TSgetBroadcastSocket(int port, struct sockaddr_in* sin) -{ - int on=1; - int soc; - - sin->sin_port=htons(port); - sin->sin_family=AF_INET; - sin->sin_addr.s_addr=htonl(INADDR_ANY); - if( (soc=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0 ) - { perror("socket create failed"); return -1; } - - setsockopt(soc,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on)); - - if( bind(soc,(struct sockaddr*)sin,sizeof(struct sockaddr_in)) < 0 ) - { perror("socket bind failed"); close(soc); return -1; } - - if( TSgetBroadcastAddr(soc,(struct sockaddr*)sin) < 0 ) return -1; - return soc; -} - -/* - TSgetBroadcastAddr() - Determine the broadcast address, this is - directly from the Sun Network Programmer's guide. -*/ -static long TSgetBroadcastAddr(int soc, struct sockaddr* sin) -{ - struct ifconf ifc; - struct ifreq* ifr; - struct ifreq* save; - char buf[BUFSIZ]; - int tot,i; - - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - if(ioctl(soc,SIOCGIFCONF,(int)&ifc) < 0) - { perror("ioctl SIOCGIFCONF failed"); return -1; } - - ifr = ifc.ifc_req; - tot = ifc.ifc_len/sizeof(struct ifreq); - save=(struct ifreq*)NULL; - i=0; - do - { - if(ifr[i].ifr_addr.sa_family==AF_INET) - { - if(ioctl(soc,SIOCGIFFLAGS,(int)&ifr[i])<0) - { perror("ioctl SIOCGIFFLAGS failed"); return -1; } - - if( (ifr[i].ifr_flags&IFF_UP) && - !(ifr[i].ifr_flags&IFF_LOOPBACK) && - (ifr[i].ifr_flags&IFF_BROADCAST)) - { save=&ifr[i]; } - } - } while( !save && ++iifr_broadaddr, - sizeof(save->ifr_broadaddr)); - } - else - { Debug0(1,"no broadcast address found\n"); return -1; } - return 0; -} - -/**************************************************************************/ -/* time stamp utility routines */ -/**************************************************************************/ - -/* - TSsyncTheTime - given the current time (cts), and a compare time - stamp (ts), correct the current time clock to match ts. -*/ -static long TSsyncTheTime(struct timespec* cts, struct timespec* ts) -{ - int key; - long diffSec; - long diffNsec; - long diffSecAbs; - - diffSec = (long)ts->tv_sec -(long) cts->tv_sec; - diffNsec = (long)ts->tv_nsec - (long)cts->tv_nsec; - diffSecAbs = (diffSec<0) ? -diffSec : diffSec; - /* see if clock can be corrected in sync window - up to 1 secs per tick */ - if(diffSecAbs <= TSdata.sync_rate) - { - long diff; - long count; - count=sysClkRateGet()*TSdata.sync_rate; - diff = (TS_BILLION/count)*diffSec + diffNsec/count; - if(diff) { - key=intLock(); - correction_count = count; - correction_factor = diff; - intUnlock(key); - } - Debug(5,"Correction Factor=.%9.9ld\n",correction_factor); - } - else - { - /* clock can not be corrected - jam it for now */ - TSdata.event_table[TSdata.sync_event]=*ts; - if(MAKE_DEBUG>=7) - { - TSprintf("Slave not in sync: mine=%9.9lu.%9.9lu!=%lu.%lu=other\n", - cts->tv_sec, cts->tv_nsec, ts->tv_sec, ts->tv_nsec); - TSprintf("slave diff time: %9.9ld.%9.9ld\n", - diffSec,diffNsec); - } - } - return 0; -} - -/**************************************************************************/ -/* varies server that can be running */ -/**************************************************************************/ - -long TSstartSyncServer() -{ - /* run at priority just above CA */ - return taskSpawn("ts_syncS",TS_SYNC_SERVER_PRI,VX_FP_TASK|VX_STDIO,5000, - (FUNCPTR)TSsyncServer,0,0,0,0,0,0,0,0,0,0); -} - -/* - TSsyncServer() - Server task that broadcasts the sync time stamp every - time a sync event is receive by the event system. -*/ -static void TSsyncServer() -{ - TSstampTrans stran; - struct sockaddr_in sin; - int soc; - - if( (soc=TSgetBroadcastSocket(0,&sin)) <0) - { Debug0(1,"TSgetBroadcastSocket failed\n"); return; } - sin.sin_port = htons(TSdata.slave_port); - stran.type=(TStype)htonl(TS_sync_msg); - stran.magic=htonl(TS_MAGIC); - stran.sync_rate=htonl(TSdata.sync_rate); - stran.clock_hz=htonl(TSdata.clock_hz); - while(1) - { - /* wait for a sync to occur */ - semTake(TSdata.sync_occurred,WAIT_FOREVER); - - if(!TSdata.ts_sync_valid) - { - int key; - struct timespec ts; - /* remember, the ts table has only an approximation to the - correct time before the event is actually up and running, - so validate the ts if this is the first sync - the vxWorks - clock has a good time in it - */ - if(TSgetTime(&ts)==0) TSdata.ts_sync_valid=1; - key=intLock(); - /* don't adjust time from getTime() to EPICS epoch */ - TSdata.event_table[TSdata.sync_event].tv_nsec=ts.tv_nsec; - TSdata.event_table[TSdata.sync_event].tv_sec=ts.tv_sec; - intUnlock(key); - } - stran.master_time.tv_sec= - htonl(TSdata.event_table[TSdata.sync_event].tv_sec); - stran.master_time.tv_nsec= - htonl(TSdata.event_table[TSdata.sync_event].tv_nsec); - if(sendto(soc,(char*)&stran,sizeof(stran),0, - (struct sockaddr*)&sin,sizeof(sin))<0) - { perror("sendto failed"); } - Debug(8,"time send secs = %lu\n",stran.master_time.tv_sec); - Debug(8,"time send nsecs = %lu\n",stran.master_time.tv_nsec); - } - close(soc); - return; -} - -/*-----------------------------------------------------------------------*/ -long TSstartAsyncClient() -{ - /* run at priority just above CA */ - return taskSpawn("ts_Casync",TS_ASYNC_CLIENT_PRI,VX_FP_TASK|VX_STDIO,5000, - (FUNCPTR)TSasyncClient,0,0,0,0,0,0,0,0,0,0); -} - -/* - TSasyncClient() - keep the async slave in sync with ntp server - while checking for master timing IOC to come up - - algorithm: - - sync with master if available - - sync with unix if no master, checking every so often for master - - sync with unix if master goes away until master comes back - - continually check for master if no unix sync available -*/ -static long TSasyncClient() -{ - BOOT_PARAMS bootParms; - TSstampTrans stran; - TS_NTP buf_ntp; - struct sockaddr_in sin_unix,sin_bc,sin_master; - int count,soc_unix,soc_master,soc_bc,buf_size; - struct timespec ts,diff_time,cts,curr_time; - unsigned long nsecs; - char host_addr[BOOT_ADDR_LEN]; - int status; - - Debug0(2,"in TSasyncClient()\n"); - - /* could open two sockets here, one to contact unix, one to find master */ - - /*------socket for unix server----------*/ - if(envGetConfigParam(&EPICS_TS_NTP_INET,BOOT_ADDR_LEN,host_addr)==NULL - || strlen(host_addr)==0) - { - /* use boot host if the environment variable not set */ - bootStringToStruct(sysBootLine,&bootParms); - /* bootParms.had = host IP address */ - strncpy(host_addr,bootParms.had,BOOT_ADDR_LEN); - } - - if( (soc_unix=TSgetSocket(0,&sin_unix)) <0) - { Debug0(1,"TSgetSocket failed\n"); return -1; } - - status = aToIPAddr (host_addr, UDP_NTP_PORT, &sin_unix); - if (status) { - Debug0(2,"bad host name or IP address\n"); - close (soc_unix); - return -1; - } - - /*------socket for finding master----------*/ - if( (soc_bc=TSgetBroadcastSocket(0,&sin_bc)) <0) - { Debug0(1,"TSgetBroadcastSocket failed\n"); close(soc_unix); return -1; } - - sin_bc.sin_port = htons(TSdata.master_port); - /*-----------------------------------------*/ - - while(1) - { - /* stop the clock from correcting here - probably better to use - a watch dog to stop the clock correction */ - - if(TSdata.state==TS_master_alive) - { - /* get socket to master */ - Debug0(5,"async_client(): master_alive\n"); - if( (soc_master=TSgetSocket(0,&sin_master)) <0) - { Debug0(1,"TSgetSocket failed\n"); } - - while(TSdata.state==TS_master_alive) - { - /* sync with the master as long as it is up */ - Debug0(5,"async_client(): syncing with master\n"); - stran.type=(TStype)htonl(TS_time_request); - stran.magic=htonl(TS_MAGIC); - - if(TSgetData((char*)&stran,sizeof(stran),soc_master, - &TSdata.master,NULL,&diff_time)<0) - { - Debug0(2,"no reply from master server\n"); - TSdata.state=TS_master_dead; - close(soc_master); - } - else - { - if(ntohl(stran.magic)==TS_MAGIC) - { - /* sync the time with master's here - 2 ticks */ - cts=TSdata.event_table[TSdata.sync_event]; - curr_time.tv_sec=ntohl(stran.current_time.tv_sec); - curr_time.tv_nsec=ntohl(stran.current_time.tv_nsec); - TSsyncTheTime(&cts,&curr_time); - Debug(8,"master sec = %lu\n",curr_time.tv_sec); - Debug(8,"my sec = %lu\n", cts.tv_sec); - } - else - { - TSprintf("TSasyncClient: invalid packet recved\n"); - } - taskDelay(sysClkRateGet()*TSdata.sync_rate); - } - } - } - else if(TSdata.async_type==TS_async_ntp) - { - /* sync with unix server using NTP - master check now and then */ - Debug0(5,"async_client(): using NTP sync\n"); - count=0; - while(TSdata.state==TS_master_dead) - { - Debug0(5,"async_client(): syncing with unix\n"); - memset(&buf_ntp,0,sizeof(buf_ntp)); - buf_ntp.info[0]=0x0b; - buf_size=sizeof(buf_ntp); - - if(TSgetData((char*)&buf_ntp,sizeof(buf_ntp),soc_unix, - (struct sockaddr*)&sin_unix,NULL,&diff_time)<0) - { - Debug0(2,"no reply from NTP server\n"); - } - else - { - unsigned long ulongtemp; - /* get the current time */ - cts=TSdata.event_table[TSdata.sync_event]; - /* adjust the ntp time */ - ts.tv_sec = ntohl(buf_ntp.transmit_ts.tv_sec); - ulongtemp = TSepochNtpToEpics(&ts); - ts.tv_sec = (long)ulongtemp; - nsecs=ntohl(buf_ntp.transmit_ts.tv_nsec); - ts.tv_nsec = TSfractionToNano(nsecs); - TSsyncTheTime(&cts,&ts); - } - if(count==0) - { - stran.type=(TStype)htonl(TS_time_request); - stran.magic=htonl(TS_MAGIC); - - if(TSgetData((char*)&stran,sizeof(stran),soc_bc, - (struct sockaddr*)&sin_bc,&TSdata.master,&diff_time)<0) - { Debug0(2,"no reply from master server\n"); } - else - { - TSdata.state=TS_master_alive; - Debug(8,"master port = %d\n", - ntohs( ((struct sockaddr_in*) - &TSdata.master)->sin_port)); - } - - count=(TSdata.sync_rate>TS_SECS_ASYNC_TRY_MASTER)? - TS_SECS_ASYNC_TRY_MASTER: - TS_SECS_ASYNC_TRY_MASTER/TSdata.sync_rate; - } - else count--; - taskDelay(sysClkRateGet()*TSdata.sync_rate); - } - } - else - { - /* try to find a master */ - while(TSdata.state==TS_master_dead) - { - stran.type=(TStype)htonl(TS_time_request); - stran.magic=htonl(TS_MAGIC); - - if(TSgetData((char*)&stran,sizeof(stran),soc_bc, - (struct sockaddr*)&sin_bc,&TSdata.master,&diff_time)<0) - { Debug0(2,"no reply from master server\n"); } - else - TSdata.state=TS_master_alive; - taskDelay(sysClkRateGet()*TS_SECS_SYNC_TRY_MASTER); - } - } - } -} - -static long TSstartSyncClient() -{ - return taskSpawn("ts_syncC",TS_SYNC_CLIENT_PRI,VX_FP_TASK|VX_STDIO,5000, - (FUNCPTR)TSsyncClient,0,0,0,0,0,0,0,0,0,0); -} - -/* - TSsyncClient() - Client task that listens for sync time stamp on a port - and verifies with this IOC sync time stamp. This is only to be used - with event system timing. -*/ -static void TSsyncClient() -{ - TSstampTrans stran; - struct sockaddr_in sin; - struct sockaddr fs; - int num,mlen,soc,fl; - struct timespec mast_time; - fd_set readfds; - int key; - - /* if no master then use unix and ntp to sync time - all aync slaves will operate in polled mode */ - - if(TSdata.type!=TS_sync_slave) return; - - /* check for master to be there every so many minutes */ - if(TSdata.state != TS_master_alive) - while( TSsetClockFromMaster()<0 ) - taskDelay(sysClkRateGet()*TS_SECS_SYNC_TRY_MASTER); - if( (soc=TSgetSocket(TSdata.slave_port,&sin)) <0) - { Debug0(1,"TSgetSocket failed\n"); return; } - while(1) - { - FD_ZERO(&readfds); - FD_SET(soc,&readfds); - - /* could set up timeout for (sync_rate + epsilon) - to see if one is missed */ - - num=select(FD_SETSIZE,&readfds,(fd_set*)NULL,(fd_set*)NULL,NULL); - if(num==ERROR) { perror("select failed"); continue; } - - if((mlen=recvfrom(soc,(char*)&stran,sizeof(stran),0,&fs,&fl))<0) - { perror("recvfrom failed"); continue; } - - if(ntohl(stran.magic)!=TS_MAGIC) - { - TSprintf("TSsyncClient: invalid packet received\n"); - continue; - } - - /* get the master time out of packet */ - mast_time.tv_sec=ntohl(stran.master_time.tv_sec); - mast_time.tv_nsec=ntohl(stran.master_time.tv_nsec); - - Debug0(6,"Received sync request from master\n"); - if(MAKE_DEBUG>=8) - { - TSprintf("time received=%9.9lu.%9.9lu\n", - mast_time.tv_sec,mast_time.tv_nsec); - } - - /* verify the sync event with this one */ - if( TSdata.event_table[TSdata.sync_event].tv_sec!=mast_time.tv_sec - || TSdata.event_table[TSdata.sync_event].tv_nsec!=mast_time.tv_nsec) - { - TSprintf("sync Slave not in sync: %lu,%lu != %lu,%lu\n", - TSdata.event_table[TSdata.sync_event].tv_sec, - TSdata.event_table[TSdata.sync_event].tv_nsec, - mast_time.tv_sec, mast_time.tv_nsec); - key=intLock(); - TSdata.event_table[TSdata.sync_event].tv_sec=mast_time.tv_sec; - TSdata.event_table[TSdata.sync_event].tv_nsec=mast_time.tv_nsec; - intUnlock(key); - } - } - close(soc); - return; -} - -static long TSstartStampServer() -{ - return taskSpawn("ts_stamp",TS_STAMP_SERVER_PRI,VX_FP_TASK|VX_STDIO,5000, - (FUNCPTR)TSstampServer,0,0,0,0,0,0,0,0,0,0); -} - -/* - TSstampServer() - Server task on master timing IOC that listens for - time stamp requests and sync request from slaves. -*/ -static void TSstampServer() -{ - TSstampTrans stran; - struct sockaddr_in sin; - struct sockaddr fs; - struct timespec ts; - int mlen,soc,fl; - TStype type; - - if( (soc=TSgetSocket(TSdata.master_port,&sin)) <0) - { Debug0(1,"TSgetSocket failed\n"); return; } - - stran.type=(TStype)htonl(TS_time_request); - stran.magic=htonl(TS_MAGIC); - - while(1) - { - fl=sizeof(fs); - if((mlen=recvfrom(soc,(char*)&stran,sizeof(stran),0,&fs,&fl))<0) - { perror("recvfrom failed"); continue; } - - if(ntohl(stran.magic)!=TS_MAGIC) - { - TSprintf("TSstampServer(): invalid packet received\n"); - continue; - } - - type=(TStype)ntohl(stran.type); - switch(type) - { - case TS_time_request: - TSgetTimeStamp(TSdata.sync_event,&ts); - stran.master_time.tv_sec=htonl(ts.tv_sec); - stran.master_time.tv_nsec=htonl(ts.tv_nsec); - - if(TSdata.has_event_system) - TSaccurateTimeStamp(&ts); - else - TScurrentTimeStamp(&ts); - stran.current_time.tv_sec=htonl(ts.tv_sec); - stran.current_time.tv_nsec=htonl(ts.tv_nsec); - stran.sync_rate = htonl(TSdata.sync_rate); - stran.clock_hz = htonl(TSdata.clock_hz); - Debug0(4,"Slave requesting time\n"); - if(sendto(soc,(char*)&stran,sizeof(stran),0,&fs,fl)<0) - { perror("sendto to slave failed"); } - break; - case TS_sync_request: TSforceSync(0); break; - default: - Debug0(1,"Unknown transaction type from slave\n"); - } - } - close(soc); - return; -} - -/*************************************************************************/ - /* utility routines for managing time retrieval */ -/*************************************************************************/ - -/* get the current time from time stamp support software */ -long TScurrentTimeStamp(struct timespec* sp) -{ - TSgetTimeStamp(0,sp); - return 0; -} - -/* get the current time from time stamp support software */ -long TSaccurateTimeStamp(struct timespec* sp) -{ - struct timespec ts; - unsigned long ticks; - - if(TSdata.has_direct_time==1) - { - TSgetTime(sp); - return 0; - } - - TSgetTicks(0,&ticks); /* add in the board time */ - *sp = TSdata.event_table[TSdata.sync_event]; - - /* calculate a time stamp from the tick count */ - ts.tv_sec = ticks / TSdata.clock_hz; - ts.tv_nsec=(ticks-(ts.tv_sec*TSdata.clock_hz))*TSdata.clock_conv; - - sp->tv_sec += ts.tv_sec; - sp->tv_nsec += ts.tv_nsec; - - /* adjust seconds if needed */ - if(sp->tv_nsec >= TS_BILLION) - { - sp->tv_sec++; - sp->tv_nsec -= TS_BILLION; - } - return 0; -} - -/* get the current time from vxWorks time clock */ -static long TSgetCurrentTime(struct timespec* ts) -{ - long rc; - rc=clock_gettime(CLOCK_REALTIME,ts); - ts->tv_sec = TSepochUnixToEpics(ts); - return rc; -} - -/* routine for causing sync to occur (not a hardware one) */ -static long TSforceSoftSync(int Card) -{ - semGive(TSdata.sync_occurred); - TSforceSync(0); - return 0; -} - -/* - TSaddStamp - Add time stamp op1 to time stamp op2 giving time stamp - result -*/ -static void TSaddStamp( struct timespec* result, - struct timespec* op1, struct timespec* op2) -{ - result->tv_sec = op1->tv_sec + op2->tv_sec; - result->tv_nsec = op1->tv_nsec + op2->tv_nsec; - - /* adjust seconds if needed */ - if(result->tv_nsec >= TS_BILLION) - { - result->tv_sec++; - result->tv_nsec -= TS_BILLION; - } - return; -} - -/* - TScalcDiff() - Calculate the difference between to time stamps. The - difference between arguments 'a' and 'b' is returned in 'diff'. The - return value from this routine is the direction: (1)=a>b, (-1)=atv_sec < b->tv_sec) { dir=-1; big_time=b; small_time=a; } - else if(a->tv_sec > b->tv_sec) { dir=1; small_time=b; big_time=a; } - else if(a->tv_nsec == b->tv_nsec){ dir=0; small_time=b; big_time=a;} - else if(a->tv_nsec < b->tv_nsec) { dir=-1; big_time=b; small_time=a; } - else { dir=1; small_time=b; big_time=a; } - - diff->tv_sec=big_time->tv_sec-small_time->tv_sec; - - if(big_time->tv_nsec>=small_time->tv_nsec) - diff->tv_nsec=big_time->tv_nsec-small_time->tv_nsec; - else - { - diff->tv_nsec = TS_BILLION + big_time->tv_nsec-small_time->tv_nsec; - diff->tv_sec--; - } - /* ---------------------this block sucks--------------------*/ - return dir; -} - -/**************************************************************************/ -/* more routines for managing sockets */ -/**************************************************************************/ - -/* get a UDP socket for a port, return a sockaddr for it. */ -static int TSgetSocket(int port, struct sockaddr_in* sin) -{ - int soc; - - sin->sin_port=htons(port); - sin->sin_family=AF_INET; - sin->sin_addr.s_addr=htonl(INADDR_ANY); - if( (soc=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0 ) - { perror("socket create failed"); return -1; } - Debug(5,"sizeof sin = %d\n", (int) sizeof(struct sockaddr_in)); - if( bind(soc,(struct sockaddr*)sin,sizeof(struct sockaddr_in)) < 0 ) - { perror("socket bind failed"); close(soc); return -1; } - - return soc; -} - -/* attempt to get data from a socket after sending a request to it. - 0ptionally return round trip time and the sockaddr of the responsedent. -*/ -static long TSgetData(char* buf, int buf_size, int soc, - struct sockaddr* to_sin, struct sockaddr* from_sin, - struct timespec* round_trip) -{ - int retry_count=0; - int num,mlen,flen; - fd_set readfds; - volatile unsigned long s,us; - struct timeval timeOut; - struct timespec send_time,recv_time; - - /* convert millisecond time out to seconds/microseconds */ - s=TSdata.time_out/1000; us=(TSdata.time_out-(s*1000))*1000; - Debug(6,"time_out Second=%lu\n",s); - Debug(6,"time_out Microsecond=%lu\n",us); - do - { - Debug(8,"sednto port %d\n", - ntohs(((struct sockaddr_in*)to_sin)->sin_port)); - if(round_trip) clock_gettime(CLOCK_REALTIME,&send_time); - if( sendto(soc,buf,buf_size,0,to_sin,sizeof(struct sockaddr)) < 0 ) - { perror("sendto failed"); return -1; } - FD_ZERO(&readfds); FD_SET(soc,&readfds); - timeOut.tv_sec=s; timeOut.tv_usec=us; - num=select(FD_SETSIZE,&readfds,(fd_set*)NULL,(fd_set*)NULL,&timeOut); - if(round_trip) clock_gettime(CLOCK_REALTIME,&recv_time); - if(num==ERROR) { perror("select failed"); return -1; } - } - while(num==0 && ++retry_count= TS_RETRY_COUNT) - { Debug0(5,"TSgetData - retry count exceeded\n"); return -1; } - else - { - /* data available */ - flen=from_sin?sizeof(struct sockaddr):0; - if((mlen=recvfrom(soc,buf,buf_size,0,from_sin,&flen))<0) - { perror("recvfrom failed"); return -1; } - if(from_sin) - { - Debug(8,"recvfrom port %d\n", - ntohs(((struct sockaddr_in*)from_sin)->sin_port)); - Debug(8,"flen = %d\n",flen); - Debug(8,"mlen = %d\n",mlen); - } - if(round_trip) TScalcDiff(&send_time,&recv_time,round_trip); - } - return mlen; -} - -/*************************************************************************/ - /* all the functions that follow are test functions */ -/*************************************************************************/ - -/* test function to print the IOC real time clock value. */ -void TSprintRealTime() -{ - struct timespec tp; - - TSgetTime(&tp); - TSprintf("real time clock = %lu,%lu\n",tp.tv_sec,tp.tv_nsec); - TSprintf("EPICS clock = %lu,%lu\n", - TSdata.event_table[TSdata.sync_event].tv_sec, - TSdata.event_table[TSdata.sync_event].tv_nsec); - return; -} - -/* test function to print an event time stamp */ -void TSprintTimeStamp(int num) -{ - struct timespec tp; - - TSgetTimeStamp(num,&tp); - TSprintf("event %d occurred: %lu.%lu\n",num,tp.tv_sec,tp.tv_nsec); - return; -} - -/* test function to print the current time using event system */ -void TSprintCurrentTime() -{ - struct timespec tp; - - TScurrentTimeStamp(&tp); - TSprintf("Current Event System time: %lu.%lu\n",tp.tv_sec,tp.tv_nsec); - TSaccurateTimeStamp(&tp); - TSprintf("Accurate Event System time: %lu.%lu\n",tp.tv_sec,tp.tv_nsec); - return; -} - -/* test function to query the boot server for the current time. */ -void TSprintUnixTime() -{ - struct timespec ts; - - if(TSgetUnixTime(&ts)!=0) - { - TSprintf("Could not get Unix time\n"); - return; - } - TSprintf("boot server time clock = %lu, %lu\n",ts.tv_sec,ts.tv_nsec); - return; -} - -/* test function to print the master timing IOC time stamp. */ -void TSprintMasterTime() -{ - struct timespec ts; - - if(TSgetMasterTime(&ts)!=0) - { - TSprintf("Could not get Unix time\n"); - return; - } - TSprintf("master time clock = %lu, %lu\n",ts.tv_sec,ts.tv_nsec); - return; -} - -/* gross and horrid example */ -long TSgetFirstOfYearVx(struct timespec* ts) -{ - time_t tloc; - struct tm t; - - time(&tloc); /* retrieve the current time */ - localtime_r(&tloc,&t); - t.tm_sec=0; - t.tm_min=0; - t.tm_hour=t.tm_isdst?1:0; - t.tm_mday=1; - t.tm_mon=0; - tloc=mktime(&t); - ts->tv_sec=tloc; - ts->tv_nsec=0; - return 0; -} diff --git a/src/vxWorks/db/drvTS.h b/src/vxWorks/db/drvTS.h deleted file mode 100644 index 9a5d854af..000000000 --- a/src/vxWorks/db/drvTS.h +++ /dev/null @@ -1,252 +0,0 @@ -#ifndef __DRVTS_h__ -#define __DRVTS_h__ - -/* - * $Log$ - * Revision 1.2 1998/03/19 20:41:16 mrk - * Checked for Y2K complience. It turns out it was even ok when NTP time overflows - * in 2036. However it was modified so that no overflows should occur while convert - * ing between NTP, UNIX, and EPICS epochs. - * In addition the conversion of fractions of a second to nanaoseconds was changed - * Formatting was changed so that interesting code does not run off right side of page. - * Hopefully EPICS base is now fine for Y2K. - * In fact it should be fine (as far as time is converned) until the Unix epoch - * overflows a 32 unsigned integer in the year 2106. - * - * Revision 1.1 1996/01/25 21:11:56 mrk - * moved includes; .ascii=> .db; path changes - * - * Revision 1.12 1995/08/30 15:39:07 jbk - * Added global variables for force accurate time stamps and direct time. - * - * Revision 1.11 1995/08/18 13:18:13 mrk - * Added function prototypes for ansi c - * - * Revision 1.10 1995/08/17 20:35:52 jbk - * fixed the debug macro to work with -pendantic option (yuck) - * - * Revision 1.9 1995/08/17 19:44:08 jbk - * Added a new utility function to get the first of the year time stamp. - * - * Revision 1.8 1995/08/16 19:04:20 jbk - * corrected vxworks time troubles - * - * Revision 1.7 1995/05/22 15:22:24 jbk - * changes TS_EXTERN thing - * - * Revision 1.6 1995/02/01 15:30:17 winans - * Added a type field to the configure command to disable the use of the event - * system hardware if desired. - * - * Revision 1.5 1994/10/31 20:36:17 jbk - * added new stuff - * - */ - -/************************************************************************** - * - * Author: Jim Kowalkowski - * - * Modification Log: - * ----------------- - * .01 01-06-94 jbk initial version - * - ***********************************************************************/ - -/***************************************************************** - COPYRIGHT NOTIFICATION -***************************************************************** - -(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO - -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**********************************************************************/ - -#include -#include -#include -#include -#include - -#include - -#ifdef TS_DRIVER -#define TS_EXTERN -#else -#define TS_EXTERN extern -#endif - -#define ER_EVENT_RESET_TICK 0x7d /* Reset the tick counter */ - -#define TS_MAGIC ('T'<<24|'S'<<16|'d'<<8|'r') -#define TS_SLAVE_PORT 18322 -#define TS_MASTER_PORT 18323 -#define TS_RETRY_COUNT 4 -#define TS_TIME_OUT_MS 250 -#define TS_SECS_ASYNC_TRY_MASTER (60*5) /* every five minutes */ -#define TS_SECS_SYNC_TRY_MASTER (60*1) /* every one minute */ - -#define UDP_TIME_PORT 37 -#define UDP_NTP_PORT 123 - -#define TS_BILLION 1000000000 -#define TS_SYNC_RATE_SEC 10 -#define TS_CLOCK_RATE_HZ 1000 -#define TS_TOTAL_EVENTS 128 -/*Following is (SEC_IN_YEAR*90)+(22*SEC_IN_DAY) */ -/*22 is leap years from 1900 to 1990*/ -#define TS_1900_TO_EPICS_EPOCH 2840140800UL -/*Following is (SEC_IN_YEAR*70)+(17*SEC_IN_DAY) */ -/*17 is leap years from 1900 to 1970*/ -#define TS_1900_TO_VXWORKS_EPOCH 2208988800UL -/*Following is (SEC_IN_YEAR*20)+(5*SEC_IN_DAY) */ -/*5 is leap years from 1970 to 1990*/ -#define TS_VXWORKS_TO_EPICS_EPOCH 631152000UL - -#define TS_STAMP_SERVER_PRI 70 -#define TS_SYNC_SERVER_PRI 70 -#define TS_SYNC_CLIENT_PRI 70 -#define TS_ASYNC_CLIENT_PRI 70 - -typedef enum { TS_time_request, TS_sync_request, TS_sync_msg } TStype; -typedef enum { TS_master_alive, TS_master_dead } TSstate; -typedef enum { TS_async_none, TS_async_private, - TS_async_ntp, TS_async_time } TStime_protocol; -typedef enum { TS_sync_master, TS_async_master, - TS_sync_slave, TS_async_slave, - TS_direct_master, TS_direct_slave} TStime_type; - -struct TSstampTransStruct { - unsigned long magic; /* identifier */ - TStype type; /* transaction type */ - struct timespec master_time; /* master time stamp - last sync time */ - struct timespec current_time; /* master current time stamp 1990 epoch */ - struct timespec unix_time; /* time using 1900 epoch */ - unsigned long sync_rate; /* master sends sync at this rate */ - unsigned long clock_hz; /* master clock this frequency (tick rate) */ -}; -typedef struct TSstampTransStruct TSstampTrans; - -struct TSinfoStruct { - TSstate state; - TStime_type type; - TStime_protocol async_type; - int ts_sync_valid; - - struct timespec *event_table; /* timestamp table */ - - unsigned long sync_rate; /* master send sync at this rate */ - unsigned long clock_hz; /* master clock is this frequency */ - unsigned long clock_conv;/* conversion factor for tick_rate->ns */ - unsigned long time_out; /* udp packet time-out in milliseconds */ - int master_timing_IOC; /* 1=master, 0=slave */ - int master_port; /* port that master listens on */ - int slave_port; /* port that slave listens on */ - int total_events; /* this is the total event in the event system*/ - int sync_event; /* this is the sync event number */ - int has_event_system; /* 1=has event system, 0=no event system */ - int has_direct_time; /* 1=has direct time, 0=no direct time */ - int UserRequestedType; /* let user force the setting of type */ - - SEM_ID sync_occurred; - - struct sockaddr hunt; /* broadcast address info */ - struct sockaddr master; /* socket info for contacting master */ -}; -typedef struct TSinfoStruct TSinfo; - -/* global functions */ -#ifdef __cplusplus -extern "C" { -#endif -TS_EXTERN long TSinit(void); -TS_EXTERN long TSgetTimeStamp(int event_number,struct timespec* ts); -TS_EXTERN unsigned long TSepochNtpToUnix(struct timespec* ts); -TS_EXTERN unsigned long TSfractionToNano(unsigned long fraction); -TS_EXTERN unsigned long TSepochNtpToEpics(struct timespec* ts); -TS_EXTERN unsigned long TSepochUnixToEpics(struct timespec* ts); -TS_EXTERN unsigned long TSepochEpicsToUnix(struct timespec* ts); -TS_EXTERN long TScurrentTimeStamp(struct timespec* ts); -TS_EXTERN long TSaccurateTimeStamp(struct timespec* ts); -TS_EXTERN long TSgetFirstOfYearVx(struct timespec* ts); -TS_EXTERN void TSconfigure(int master, int sync_rate_sec, int clock_rate_hz, - int master_port, int slave_port, - unsigned long millisecond_request_time_out, int type); -TS_EXTERN long TSsetClockFromUnix(void); - -#ifndef TS_DRIVER -TS_EXTERN TSinfo TSdata; -TS_EXTERN TSdirectTimeVar; /* set to !=0 to indicate direct time available*/ -TS_EXTERN TSgoodTimeStamps; /* force best time stamps by setting != 0 */ -#endif - -#ifdef __cplusplus -}; -#endif - -/* NTP information - all this is backwards and documentation only */ -#define VN_SHIFT 2 /* Version - 3 bits */ -#define VN_version 3< -#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 deleted file mode 100644 index 790a2b011..000000000 --- a/src/vxWorks/dev/apsDev/devApsEr.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ***************************************************************** - * 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 deleted file mode 100644 index 63c172d56..000000000 --- a/src/vxWorks/dev/atDev/devAt5Vxi.c +++ /dev/null @@ -1,584 +0,0 @@ -/* 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 deleted file mode 100644 index 624afaef6..000000000 --- a/src/vxWorks/dev/atDev/devAt8Fp.c +++ /dev/null @@ -1,251 +0,0 @@ -/* 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 deleted file mode 100644 index 153ec1175..000000000 --- a/src/vxWorks/dev/compumotorDev/devSmCompumotor1830.c +++ /dev/null @@ -1,82 +0,0 @@ -/* 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 deleted file mode 100644 index b47096cb2..000000000 --- a/src/vxWorks/dev/gpibDev/devCommonGpib.c +++ /dev/null @@ -1,2638 +0,0 @@ -/* 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 deleted file mode 100644 index 77cb9de68..000000000 --- a/src/vxWorks/dev/gpibDev/devCommonGpib.h +++ /dev/null @@ -1,348 +0,0 @@ -/* 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 deleted file mode 100644 index c21bb4352..000000000 --- a/src/vxWorks/dev/joergerDev/devWfJoergerVtr1.c +++ /dev/null @@ -1,167 +0,0 @@ -/* 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); -} diff --git a/src/vxWorks/devOpt/devAnalytekGpib.c b/src/vxWorks/devOpt/devAnalytekGpib.c deleted file mode 100644 index 9afcbbc7a..000000000 --- a/src/vxWorks/devOpt/devAnalytekGpib.c +++ /dev/null @@ -1,818 +0,0 @@ - -#define DSET_AI devAiAnalytekGpib -#define DSET_AO devAoAnalytekGpib -#define DSET_LI devLiAnalytekGpib -#define DSET_LO devLoAnalytekGpib -#define DSET_BI devBiAnalytekGpib -#define DSET_BO devBoAnalytekGpib -#define DSET_MBBO devMbboAnalytekGpib -#define DSET_MBBI devMbbiAnalytekGpib -#define DSET_SI devSiAnalytekGpib -#define DSET_SO devSoAnalytekGpib -#define DSET_WF devWfAnalytekGpib - -#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 - -#define STATIC static - -long devGpibLib_initWf(); -long devGpibLib_readWf(); -int devGpibLib_wfGpibWork(); - -STATIC long init_dev_sup(), report(); -STATIC struct devGpibParmBlock devSupParms; - -STATIC int getamprange(); /* used to get signal amplitude range */ -STATIC int getrange(); /* used to get signal range */ -STATIC int getoffset(); /* used to get signal offset */ - -STATIC int convertWave(); /* parses waveform data from analytek digitizer */ - -/****************************************************************************** - * - * Define all the dset's. - * - * Note that the dset names are provided via the #define lines at the top of - * this file. - * - * Other than for the debugging flag(s), these DSETs are the only items that - * will appear in the global name space within the IOC. - * - * The last 3 items in the DSET structure are used to point to the parm - * structure, the work functions used for each record type, and the srq - * handler for each record type. - * - ******************************************************************************/ -gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, - devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; - -gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, - devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; - -gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, - devGpibLib_readBi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; - -gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, - devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; - -gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, - devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; - -gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, - devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; - -gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, - devGpibLib_readSi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)&devGpibLib_stringinGpibWork, - (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; - -gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, - devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; - -gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, - devGpibLib_readLi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; - -gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, - devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; - -gDset DSET_WF = {5, {NULL, NULL, devGpibLib_initWf, NULL, - devGpibLib_readWf, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_wfGpibWork, NULL}}; - -int AnalytekDebug = 0; /* debugging flags */ -extern int ibSrqDebug; - - -static char *onoffList[] = { "Off","On" }; -static unsigned long onoffVal[] = { 0,1 }; -static struct devGpibNames onoff = { 2, onoffList, onoffVal, 4 }; - -/* - * Use the TIME_WINDOW defn to indicate how long commands should be ignored - * for a given device after it times out. The ignored commands will be - * returned as errors to device support. - * - * Use the DMA_TIME to define how long you wish to wait for an I/O operation - * to complete once started. - */ -#define TIME_WINDOW 600 /* 10 seconds on a getTick call */ -#define DMA_TIME 6000 /* 1 second on a watchdog time */ - -static struct gpibCmd gpibCmds[] = -{ - /* Param 0, (model) */ - FILL, - -/* Function Commands */ - - - /* Param 1, Clear status command */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*CLS\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 2, Return Power-on-Status Clear state */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "*PSC?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 3, Set Power-on-Status Clear state */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*PSC %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 4, Recall device state */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*RCL %u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 5, Reset */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*RST\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 6, Save device state */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*SAV %u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 7, Perform self-test */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "*TST?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 8, Signal info, at end of parameter list */ - FILL, - /* Param 9, Request base average sample count */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "BASAVG?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 10, Set base average sample count */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BASAVG %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 11, Request state of base correction switch */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "BASCOR?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 12, Set state of base correction switch */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "BASCOR %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 13 Request current channel on board 1 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "BDSEL?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 14, Set current channel on board 1 */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*BDSEL 1,%u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 15, Request sampling board types */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "BRDTYPE?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 16, Request state of calibration trigger */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "CALTRIG?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 17, Set state of calibration trigger, */ - {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 18, Request frequency of base clock in Mhz */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "CLKFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 19, Set frequency of base clock in Mhz */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "CLKFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 20, Return state of display*/ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "DISPlay?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 21, Set state of display */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "DISPlay %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 22, Return state of local switch*/ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "LOCAL?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 23, Set local switch on/off */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LOCAL %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 24, Return state of lockout switch */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "LOCKOUT?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 25, Set lockout switch on/off */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LOCKOUT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 26, Request state of low pass filter */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "LPFILT?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 27, Set low pass filter */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFILT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 28, Request length of FIR for low pass filter */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "LPFIR?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 29, Set FIR for low pass filter */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFIR %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 30, Request frequency of low pass filter */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "LPFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 31, Set frequency of low pass filter */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 32, Request filter mode, */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "LPMODE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 33, Set filter mode, */ - {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 34, Select single or multiple events */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "MEVENT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 35, Request number of samples stored in cache memory */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "MIREP?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 36, Set number of samples stored 8in cache memory */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "MIREP %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 37, Restart program, similar to external reset button */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "PGMRST\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 38, Request instrument to acquire a data sample */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "SAMPLE\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 39, Request state of signal averaging switch */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "SIGAVG?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 40, Set state of signal averaging switch */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGAVG %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1}, - - /* Param 41, Request current average count */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGCNT?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 42, Request count of cycles to average before display modulo */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGDSP?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 43, Set count of cycles to average before display modulo */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGDSP %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 44, Request maximum count of cycles to be averaged */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGLMT?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 45, Set maximum count of cycles to be averaged */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGLMT %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 46, Signal info, */ - FILL, - - /* Param 47, Request sampling frequency */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "SMPFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 48, Set sampling frequency */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SMPFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 49, Request sample offset for a channel, */ - FILL, - - /* Param 50, Set sample offset for a channel, */ - FILL, - - /* Param 51, Request sample size, */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "SMPSIZE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 52, Set sample size, */ - {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 53, Halt current sampling operation */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "STOP\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 54, Returns trigger coupling, */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGCOUPLE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 55, Set trigger coupling, */ - {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 56, Request trigger delay */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "TRGDELAY?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 57, Set trigger delay */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TRGDELAY %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 58, Requests trigger mode, */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGMODE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 59, Set trigger mode, */ - {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 60, Request trigger offset */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "TRGOFF?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 61, Set trigger offset */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TRGOFF %f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 62, Request trigger slope setting, */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGSLOPE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 63, Set trigger slope, */ - {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 64, Request trigger type, */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGTYPE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1}, - - /* Param 65, Set trigger type, */ - {&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1}, - -/* Channel 1 */ - /* Param 66, Request amplitude range for signal on board 1 channel 1 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 67, Request range for signal on board 1 channel 1 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 68, Request offset for signal on board 1 channel 1 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 69, on board 1 channel 1 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,1", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, -/* Channel 2 */ - /* Param 70, Request amplitude range for signal on board 1 channel 2 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 71, Request range for signal on board 1 channel 2 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 72, Request offset for signal on board 1 channel 2 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 73, on board 1 channel 2 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,2", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, -/* Channel 3 */ - - /* Param 74, Request amplitude range for signal on board 1 channel 3 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 67, Request range for signal on board 1 channel 3 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 68, Request offset for signal on board 1 channel 3 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - /* Param 71, on board 1 channel 3 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,3", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, -/* Channel 4 */ - - /* Param 72, Request amplitude range for signal on board 1 channel 2 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 73, Request range for signal on board 1 channel 2 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 74, Request offset for signal on board 1 channel 2 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 75, on board 1 channel 4 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,4", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - -/* Channel 5 */ - /* Param 76, Request amplitude range for signal on board 1 channel 5 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 77, Request range for signal on board 1 channel 5 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 78, Request offset for signal on board 1 channel 5 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 79, on board 1 channel 5 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,5", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - -/* Channel 6 */ - /* Param 80, Request amplitude range for signal on board 1 channel 6 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 81, Request range for signal on board 1 channel 6 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 82, Request offset for signal on board 1 channel 6 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 83, on board 1 channel 6 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,6", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - - -/* Channel 7 */ - /* Param 84, Request amplitude range for signal on board 1 channel 7 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 85, Request range for signal on board 1 channel 7 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 86, Request offset for signal on board 1 channel 7 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 87, on board 1 channel 7 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,7", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - -/* Channel 8 */ - /* Param 88, Request amplitude range for signal on board 1 channel 8 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 89, Request range for signal on board 1 channel 8 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 90, Request offset for signal on board 1 channel 8 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 91, on board 1 channel 8 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,8", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - - -/* Channel 9 */ - /* Param 92, Request amplitude range for signal on board 1 channel 9 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 93, Request range for signal on board 1 channel 9 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 94, Request offset for signal on board 1 channel 9 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 95, on board 1 channel 9 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,9", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - -/* Channel 10 */ - /* Param 96, Request amplitude range for signal on board 1 channel 10 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 97, Request range for signal on board 1 channel 10 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 98, Request offset for signal on board 1 channel 10 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 99, on board 1 channel 10 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,10", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - -/* Channel 11 */ - /* Param 100, Request amplitude range for signal on board 1 channel 11 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 101, Request range for signal on board 1 channel 11 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 102, Request offset for signal on board 1 channel 11 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 103, on board 1 channel 11 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,11", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - - -/* Channel 12 */ - /* Param 104, Request amplitude range for signal on board 1 channel 12 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 105, Request range for signal on board 1 channel 12 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 106, Request offset for signal on board 1 channel 12 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 107, on board 1 channel 12 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,12", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - -/* Channel 13 */ - /* Param 108, Request amplitude range for signal on board 1 channel 13 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 109, Request range for signal on board 1 channel 13 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 110, Request offset for signal on board 1 channel 13 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 111, on board 1 channel 13 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,13", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - -/* Channel 14 */ - /* Param 112, Request amplitude range for signal on board 1 channel 14 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 113, Request range for signal on board 1 channel 14 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 114, Request offset for signal on board 1 channel 14 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 115, on board 1 channel 14 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,14", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - -/* Channel 15 */ - /* Param 116, Request amplitude range for signal on board 1 channel 15 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 117, Request range for signal on board 1 channel 15 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 118, Request offset for signal on board 1 channel 15 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 119, on board 1 channel 15 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,15", "%u", 0, 1100, convertWave , 0, 0, NULL, NULL, -1}, -/* Channel 16 */ - - /* Param 120, Request amplitude range for signal on board 1 channel 16 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1}, - - /* Param 121, Request range for signal on board 1 channel 16 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1}, - - /* Param 122, Request offset for signal on board 1 channel 16 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1}, - - /* Param 123, on board 1 channel 16 */ - {&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,16", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1}, - - -}; -/* The following is the number of elements in the command array above. */ -#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) - -/****************************************************************************** - * - * Structure containing the user's functions and operating parameters needed - * by the gpib library functions. - * - * The magic SRQ parm is the parm number that, if specified on a passive - * record, will cause the record to be processed automatically when an - * unsolicited SRQ interrupt is detected from the device. - * - * If the parm is specified on a non-passive record, it will NOT be processed - * when an unsolicited SRQ is detected. - * - ******************************************************************************/ -static struct devGpibParmBlock devSupParms = { - &AnalytekDebug, /* debugging flag pointer */ - -1, /* set to -1 if the device does NOT respond to writes */ - TIME_WINDOW, /* # of clock ticks to skip after a device times out */ - NULL, /* hwpvt list head */ - gpibCmds, /* GPIB command array */ - NUMPARAMS, /* number of supported parameters */ - -1, /* magic SRQ param number (-1 if none) */ - "devXxAnalytekGpib", /* device support module type name */ - DMA_TIME, /* # of clock ticks to wait for DMA completions */ - - NULL, /* pointer to SRQ handler function (NULL if none) */ - NULL /* pointer to secondary conversion routine */ -}; - -/****************************************************************************** - * - * 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. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -STATIC long -init_dev_sup(int parm) -{ - return(devGpibLib_initDevSup(parm, &DSET_AI)); -} - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -STATIC long -report(void) -{ - return(devGpibLib_report(&DSET_AI)); -} - -STATIC int getamprange(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) -{ - int amprange; - int i; - int status; - - struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord); - - if(AnalytekDebug) - printf("getamprange AINFO? returned msg:%s\n",pdpvt->msg); - - /* Change all commas in returned string to blank spaces to seperate fields */ - i=0; - while(pdpvt->msg[i] != '\0') - { - if (pdpvt->msg[i] == ',') - pdpvt->msg[i] = 0x20; /* blank space */ - i++; - } - - if(AnalytekDebug) - printf("getamprange AINFO? new msg:%s\n",pdpvt->msg); - - /* Scan response string for signal amplitude range */ - status = sscanf(pdpvt->msg, "%*c%d", &range); /* This sscanf command is command specific */ - /* In this case the leading quote is skipped */ - /* and the next number is assigned to amprange */ - /* and the rest of the string is skipped */ - if(AnalytekDebug) - printf("getamprange AINFO? :sscan status = %d\n",status); - printf("amprange = %d\n",amprange); - - /* if value was assigned, put value in data base */ - if (status == 1) /* make sure message was received ok */ - { /* sscanf returns an integer which tells */ - pai->val = amprange; /* how many assignments were made */ - } - else - { - if (pai->nsev < INVALID_ALARM) - { - pai->nsev = INVALID_ALARM; - pai->nsta = READ_ALARM; - } - } - - return(OK); -} - - -/* conversion routine */ - -STATIC int getrange(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) -{ - int range; - int i; - int status; - - struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord); - - if(AnalytekDebug) - printf("getrange AINFO? returned msg:%s\n",pdpvt->msg); - - /* Change all commas in returned string to blank spaces to seperate fields */ - i=0; - while(pdpvt->msg[i] != '\0') - { - if (pdpvt->msg[i] == ',') - pdpvt->msg[i] = 0x20; - i++; - } - - if(AnalytekDebug) - printf("getrange AINFO? new msg:%s\n",pdpvt->msg); - - /* Scan response string for signal amplitude range (paiar), range (pair), and offset (paio) */ - status = sscanf(pdpvt->msg, "%*c%*d%d", &range); - if(AnalytekDebug) - printf("getrange AINFO? :sscan status = %d\n",status); - - if (status == 1) /* make sure message was received ok */ - { - /*assign new value */ - pai->val = range; - } - else - { - if (pai->nsev < INVALID_ALARM) - { - pai->nsev = INVALID_ALARM; - pai->nsta = READ_ALARM; - } - } - - return(OK); -} - -/* conversion routine */ - -STATIC int getoffset(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) -{ - float offset; - int i; - int status; - - struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord); - - if(AnalytekDebug) - printf("getoffset AINFO? returned msg:%s\n",pdpvt->msg); - - /* Change all commas in returned string to blank spaces to seperate fields */ - i=0; - while(pdpvt->msg[i] != '\0') - { - if (pdpvt->msg[i] == ',') - pdpvt->msg[i] = 0x20; - i++; - } - - if(AnalytekDebug) - printf("getoffset AINFO? new msg:%s\n",pdpvt->msg); - - /* Scan response string for signal amplitude range (paiar), range (pair), and offset (paio) */ - status = sscanf(pdpvt->msg, "%*c%*d%*d%f", &offset); - if(AnalytekDebug) - printf("getoffset AINFO? :sscan status = %d\n",status); - - if (status == 1) /* make sure message was received ok */ - { - /*assign new value */ - pai->val = offset; - } - else - { - if (pai->nsev < INVALID_ALARM) - { - pai->nsev = INVALID_ALARM; - pai->nsta = READ_ALARM; - } - } - - return(OK); -} - -STATIC int convertWave(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) -{ - struct waveformRecord *pwf = (struct waveformRecord *) (pdpvt->precord); - short *raw; - char *craw; - short *clean; - unsigned long numElem; - char asciiLen[10]; - int ix; - -#define ANALTEK_BIAS 2048 - - if (AnalytekDebug) - printf("Analytek waveform conversion routine entered\n"); - - clean = (short *) pwf->bptr; - craw = pdpvt->msg; - if (*craw != '#') - { /* don't have a valid analytek waveform */ - devGpibLib_setPvSevr(pwf,READ_ALARM,INVALID_ALARM); - - printf("Got an invalid waveform back!\n"); - return(ERROR); - } - while (*craw == '#') - craw++; - - - ix = *craw - '0'; - craw ++; - raw = (short *) (craw + ix); - asciiLen[ix] = '\0'; - - while(ix--) - asciiLen[ix] = craw[ix]; - - if (sscanf (asciiLen, "%d", &numElem) != 1) - { - devGpibLib_setPvSevr(pwf,READ_ALARM,INVALID_ALARM); - - printf("Got an invalid waveform back!!\n"); - return(ERROR); - } - numElem = numElem/2; /* 2 bytes per sample */ - - /* Fill in the pwf->nord field with number of elements read from analytek */ - if (numElem > pwf->nelm) - numElem = pwf->nelm; - - pwf->nord = numElem; - - /* convert the raw data in pdpvt->msg to a usable data-stream in pwf->bptr */ - while (numElem) - { - *clean = (short) (*raw - ANALTEK_BIAS); - clean++; - raw++; - numElem--; - } - return(OK); -} diff --git a/src/vxWorks/devOpt/devGpibInteract.c b/src/vxWorks/devOpt/devGpibInteract.c deleted file mode 100644 index d28127fc1..000000000 --- a/src/vxWorks/devOpt/devGpibInteract.c +++ /dev/null @@ -1,775 +0,0 @@ -/* devGpibInteract.c */ -/* share/src/devOpt/ $Id$ */ -/* - * Author: John Winans - * Origional Author: Ned D. Arnold - * Date: 9/23/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 06-19-91 nda initial coding & debugging - * .02 09-23-91 jrw added proper multi-link support - * - */ - -/* gpibInteract.c - allows interactive GPIB message transmissions */ - -/* - * gpibInteract allows the user to interactively set up gpib messages, - * submit them to the gpibOwn Queue, and display the result. Five - * gpib messages can be defined at a time. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define GPIBREAD 1 -#define GPIBWRITE 2 -#define GPIBCMD 3 - -#define MAX_MSG_LENGTH 80 - -int GITime = 60; /* shell-setable DMA timeout value */ - -extern struct drvGpibSet drvGpib; /* entry points to driver functions */ -static int gpibWork(); - -struct gpibIntCmd { - struct dpvtGpibHead head; - - char type; /* R, W, C for read, write, command */ - char cmd[MAX_MSG_LENGTH]; /* string to send to instrument */ - char resp[MAX_MSG_LENGTH+32];/* place for response if a GPIB read */ - long count; /* used for counting */ - char busy; /* used by timing routine */ - - int linkId; /* link number */ - int linkType; /* GPIB_IO or BBGPIB_IO */ - int bug; /* bug# if BBGPIB_IO linkType */ -}; - -#define LIST_SIZE 10 -static struct gpibIntCmd gpibIntCmds[LIST_SIZE]; - -/* declare other required variables used by more than one routine */ - -BOOL replyIsBack; /* reset by sender, set by replyReceived() */ - -extern int ibDebug; -int GIDebug = 0; - -static int sendMsg(); -static int gpibWork(); -static int configMsg(); -static int getInt(); -static int getChar(); -static int getString(); -static int showGpibMsg(); -static int timingStudy(); - -static void hexDump(unsigned char *string, int indent); - -static int firstTime = 1; -static int hexmode = 1; -static SEM_ID msgReply; - -int GI(void) -{ - unsigned char ans; - int cnt; - - if(firstTime) - { - firstTime = 0; - msgReply = semBCreate(SEM_Q_FIFO, SEM_EMPTY); - - for (cnt=0; cnt < LIST_SIZE; cnt++) - { /* init the elements of the command table */ - -#if 0 - gpibIntCmds[cnt].head.header.list.list1 = NULL; - gpibIntCmds[cnt].head.header.list.list2 = NULL; -#endif - gpibIntCmds[cnt].head.workStart = gpibWork; - gpibIntCmds[cnt].head.link = 0; - gpibIntCmds[cnt].head.device = 0; - gpibIntCmds[cnt].head.bitBusDpvt= NULL; - - gpibIntCmds[cnt].type = 'R'; - gpibIntCmds[cnt].cmd[0] = '\0'; - gpibIntCmds[cnt].resp[0] = '\0'; - gpibIntCmds[cnt].count = 0; - gpibIntCmds[cnt].busy = 0; - } - } - - ans = 0; /* set loop not to exit */ - logMsg("\n\n"); - - while ((ans != 'q') && (ans != 'Q')) - { - printf("\n\nInteractive GPIB Program\n"); - printf("Select a function:\n"); /* main menu */ - printf(" 'C' to configure send message content\n"); - printf(" 'D' to display transmit & receive messages\n"); - printf(" 'H' enable hex dump listings of message responses\n"); - printf(" 'h' disable hex dump listings of message responses\n"); - printf(" 'S' to send & receive a message one time\n"); - printf(" 'T' to do timing on messages\n"); - printf(" 'R' to turn on the GPIB debugging flag\n"); - printf(" 'r' to turn off the GPIB debugging flag\n"); - printf(" 'Q' to quit program\n"); - printf(">"); - ans = 0; /* clear previous selection */ - getChar(&ans); - - switch (ans) { - case 'c': /* configure message contents */ - case 'C': - configMsg(); - break; - - case 'h': /* disable hex dumping */ - hexmode = 0; - break; - - case 'H': /* enable hex dumping */ - hexmode = 1; - break; - - case 's': - case 'S': /* one shot: send one message */ - sendMsg(); - break; - - case 't': - case 'T': /* Timing analysis */ - timingStudy(); - break; - - case 'd': - case 'D': /* Display message contents */ - for (cnt = 1; cnt < LIST_SIZE; cnt++) /* for each message */ - showGpibMsg(cnt); - printf("\nHit CR to return to Main Menu ..."); - getChar(&ans); /* dummy input */ - break; - - case 'q': - case 'Q': /* quit */ - break; - - case 'r': /* turn off ibDebug */ - ibDebug = 0; - break; - case 'R': /* turn on ibDebug */ - ibDebug = 1; - break; - } /* end case */ - } /* end of while ans== q or Q */ - return(0); -} /* end of main */ - -static int timingStudy(void) -{ - struct gpibIntCmd *pCmd[LIST_SIZE]; - int inInt; /* input integer from operator */ - int reps; /* number of times to send a message */ - ULONG startTime; - ULONG endTime; - ULONG delta; - int Reps; - int i; - int j; - - for (i=0; i to terminate list) > "); - if (getInt(&inInt)) - { - if (inInt>0 && inIntbusy = 0; /* mark message 'not in queue' */ - pCmd[i]->count = 0; - -#ifdef USE_162_STUFF - if (pCmd[i]->linkId < MVME162_LINK_NUM_BASE) - { -#endif - (*(drvGpib.ioctl))(pCmd[i]->linkType, pCmd[i]->linkId, pCmd[i]->bug, IBGENLINK, 0, NULL); - (*(drvGpib.ioctl))(pCmd[i]->linkType, pCmd[i]->linkId, pCmd[i]->bug, IBGETLINK, 0, &(pCmd[i]->head.pibLink)); -#ifdef USE_162_STUFF - } - else - { - drv162IB_InitLink(pCmd[i]->linkId); - drv162IB_GetLink(pCmd[i]->linkId, &(pCmd[i]->head.pibLink)); - } -#endif - } - else - { - pCmd[i] = NULL; /* terminate the list */ - i = LIST_SIZE; - } - } - else - { - pCmd[i] = NULL; /* terminate the list */ - i = LIST_SIZE; - } - } - - printf("Enter the number of messages to send > "); - if (!getInt(&inInt)) - return(0); /* if no entry, return to main menu */ - if(inInt < 0) - return(0); - reps = inInt; - Reps = reps; - - startTime = tickGet(); /* time the looping started */ - - while(reps) - { - for(i=0; ibusy)) - { - pCmd[i]->count++; - pCmd[i]->busy = 1; /* mark the xact as busy */ - -#ifdef USE_162_STUFF - if (pCmd[i]->linkId < MVME162_LINK_NUM_BASE) -#endif - (*(drvGpib.qGpibReq))(pCmd[i], IB_Q_LOW); -#ifdef USE_162_STUFF - else - drv162IB_QueueReq(pCmd[i], IB_Q_LOW); -#endif - reps--; - if (reps%10000 == 0) - { - printf("Timing study in progress with %d messages left, current status:\n", reps); - for (j=0; jcount); - } - else - j = LIST_SIZE; - } - - } - } - } - else - i = LIST_SIZE; /* force an exit from the loop */ - } - semTake(msgReply, WAIT_FOREVER); - } - - endTime = tickGet(); - delta = (endTime - startTime); /* measured time in ticks */ - if (delta == 0) - delta = 1; - printf("Total transmit and receiving time = %ld/60 Sec\n", delta); - printf("Messages/second = %.2f\n", (float) (60*Reps)/(float)delta); - - for (i=0; icount); - } - else - i = LIST_SIZE; - } - return(0); -} - -/* sendMsg() *************************************************** - */ - -static int sendMsg(void) -{ - struct gpibIntCmd *pCmd; - int inInt; /* input integer from operator */ - int msgNum; /* index to array of messages */ - int ticks; /* # of ticks since message was sent */ - int maxTicks = 480; /* # of ticks to wait for reply (8 seconds) */ - - printf("\nEnter Message # to Send (1 thru 5) > "); - if (!getInt(&inInt)) - return(-1); /* if no entry, return to main menu */ - if((inInt >= LIST_SIZE) || (inInt < 0)) - return(-1); - - msgNum = inInt; - pCmd = &gpibIntCmds[msgNum]; /* assign pointer to desired entry */ - - replyIsBack = FALSE; - ticks = 0; - -#ifdef USE_162_STUFF - if (pCmd->linkId < MVME162_LINK_NUM_BASE) - { -#endif - - (*(drvGpib.ioctl))(pCmd->linkType, pCmd->linkId, pCmd->bug, IBGENLINK, 0, NULL); - (*(drvGpib.ioctl))(pCmd->linkType, pCmd->linkId, pCmd->bug, IBGETLINK, 0, &(pCmd->head.pibLink)); - (*(drvGpib.qGpibReq))(pCmd, IB_Q_LOW); /* queue the msg */ - -#ifdef USE_162_STUFF - } - else - { - drv162IB_InitLink(pCmd->linkId); - drv162IB_GetLink(pCmd->linkId, &(pCmd->head.pibLink)); - drv162IB_QueueReq(pCmd, IB_Q_LOW); - } -#endif - - while (!replyIsBack && (ticks < maxTicks)) /* wait for reply msg */ - { - taskDelay(1); - ticks++; - } - - if (replyIsBack) - { - if (ibDebug) - taskDelay(60); /* Allow debug printing to complete */ - showGpibMsg(msgNum); - } - else - printf("No Reply Received ...\n"); - - return(0); -} - -static int gpibWork(struct gpibIntCmd *pCmd) -{ - int status; - - if (GIDebug || ibDebug) - logMsg("GI's gpibWork() was called for command >%s<\n", pCmd->cmd); - - switch (pCmd->type) { - case 'w': - case 'W': /* write the message to the GPIB listen adrs */ -#ifdef USE_162_STUFF - if (pCmd->linkId < MVME162_LINK_NUM_BASE) -#endif - status =(*(drvGpib.writeIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime); - -#ifdef USE_162_STUFF - else - status = drv162IB_write(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime); -#endif - - if (status == ERROR) - strcpy(pCmd->resp, "GPIB TIMEOUT (while talking)"); - else - pCmd->resp[0] = '\0'; - break; - case 'r': - case 'R': /* write the command string */ -#ifdef USE_162_STUFF - if (pCmd->linkId < MVME162_LINK_NUM_BASE) -#endif - status = (*(drvGpib.writeIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime); -#ifdef USE_162_STUFF - else - status = drv162IB_write(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime); -#endif - - if (status == ERROR) - { - strcpy(pCmd->resp, "GPIB TIMEOUT (while talking)"); - break; - } - /* fall thru into the reading protion below */ - case 'I': - case 'i': - /* read the instrument */ - pCmd->resp[0] = 0; /* clear response string */ -#ifdef USE_162_STUFF - if (pCmd->linkId < MVME162_LINK_NUM_BASE) -#endif - status = (*(drvGpib.readIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->resp, MAX_MSG_LENGTH, GITime); -#ifdef USE_162_STUFF - else - status = drv162IB_read(pCmd->head.pibLink, pCmd->head.device, pCmd->resp, MAX_MSG_LENGTH, GITime); -#endif - - if (status == ERROR) - { - strcat(pCmd->resp, "GPIB ERROR (while listening)"); - break; - } - else if (status > (MAX_MSG_LENGTH - 1)) /* check length of resp */ - { - logMsg("GPIB Response length equaled allocated space !!!\n"); - pCmd->resp[(MAX_MSG_LENGTH)] = '\0'; /* place \0 at end */ - } - else - { - pCmd->resp[status] = '\0'; /* terminate response with \0 */ - } - break; - } - pCmd->busy = 0; - replyIsBack = TRUE; - semGive(msgReply); - return(IDLE); -} - -/*-------------------------------------------------------------------- - * configMsg() - * - * - Purpose - * Prompts the operator for the contents of a GPIB message - * Displays current value of the field as the default entry - * - */ - -static int -configMsg() -{ - struct gpibIntCmd *pCmd; - int msgNum; /* index to array of messages */ - int inInt; /* input integer from operator */ - unsigned char inChar; /* input char from operator */ - char inString[MAX_MSG_LENGTH]; /* input string from operator */ - - printf("\nEnter Message # to Configure (1 thru 5) > "); - if (!getInt(&inInt)) - return(0); /* if no entry, return to main menu */ - if((inInt >= LIST_SIZE) || (inInt < 0)) - return(0); - - msgNum = inInt; - pCmd = &gpibIntCmds[msgNum]; /* assign pointer to desired entry */ - - printf("\n\n Configuring Send Message # %1.1d .... \n", msgNum); - -/* Prompt the Operator with the current value of each parameter If - * only a is typed, keep current value, else replace value with - * entered value - */ - - printf("Enter the Link Type (5 = GPIB, 13 = BBGPIB) [%d]: ", pCmd->linkType); - if (getInt(&inInt) == 1) - { - if(inInt == 5) - pCmd->linkType = GPIB_IO; - else if (inInt == 13) - pCmd->linkType = BBGPIB_IO; - else - { - printf("Invalid link Type %d specified\n", pCmd->linkType); - return(ERROR); - } - } - - - printf("\nenter Enter Link # [%2.2d] > ", (int) pCmd->linkId); - if (getInt(&inInt) == 1) - pCmd->linkId = inInt; - - if (pCmd->linkType == BBGPIB_IO) - { - printf("Enter the bug number [%d]: ", pCmd->bug); - if (getInt(&inInt) == 1) - pCmd->bug = inInt; - } - - printf("\nenter GPIB Node # [%2.2d] > ", pCmd->head.device); - if (getInt(&inInt) == 1) - { - pCmd->head.device = inInt; - } - - printf("\nenter command type R, W, C, I [%c] > ", pCmd->type); - if (getChar(&inChar) == 1) - pCmd->type = inChar; - - if ((pCmd->type != 'I') && (pCmd->type != 'i')) - { - if (hexmode) - { - printf("\nEnter string to send (no quotes)\n"); - hexDump(pCmd->cmd, 0); - } - else - printf("\nenter string to send (no quotes) [%.80s] > ", pCmd->cmd); - - if (getString(inString) == 1) - strcpy(pCmd->cmd, inString); - } - else - pCmd->cmd[0] = 0; - - pCmd->resp[0]= 0; /* clear response string */ - - showGpibMsg(msgNum); - return(ERROR); -} - -/* - * getInt(pInt) **************************************************** - * - * gets a line of input from STDIN (10 characters MAX !!!!) scans the line - * for an integer. - * - * Parm1 : pointer to an integer - * - * Returns (0) if a was hit, *pInt left unchanged. Returns (1) if a new - * value was written to *pvalue. Returns (2) if a entry was not a valid - * integer entry - * - */ - -static int -getInt(pInt) -int *pInt; -{ - char input[10]; - int inval; - - gets(input); - - if (input[0] == 0) /* if only a */ - return (0); - else - { - if (sscanf(input, "%d", &inval) == 1) - { /* if a valid entry ... */ - *pInt = inval; - return (1); - } - else /* if not a valid entry, return 2 */ - return (2); - } -} - -/* - * int getChar(pChar) ************************************************** - * - * gets a line of input from STDIN (10 characters MAX !!!!) scans the line - * for a character entry - * - * Parm1 : pointer to an unsigned character variable - * - * Returns(0) if a was hit, *pChar left unchanged. Returns(1) if a new - * value was written to *pChar - * - */ - -static int -getChar(pChar) -unsigned char *pChar; -{ - char input[10]; - unsigned char inval; - - gets(input); - - if (input[0] == 0) - return (0); - else - { - sscanf(input, "%c", &inval); - *pChar = inval; - return (1); - } -} - -/* - * int getString(pString) **************************************************** - * - * gets a line of input from STDIN (100 characters MAX !!!!) . - * If length is greater than 0, copies string into pString - * - * Parm1 : pointer to an character string - * - * Returns : 0 if a was hit, *pvalue left unchanged Returns : 1 if a - * new value was written to *pvalue - * - */ - -static int -getString(pString) -char *pString; -{ - char input[100]; - char *in; - - gets(input); - - if (input[0] == 0) - return (0); - else - { - in = input; - while(*in != '\0') - { - switch (*in) { - case '\\': /* meta-character parser */ - ++in; - switch (*in) { - case 'n': /* \n = linefeed */ - case 'l': /* \l = lenefeed too */ - *pString = '\n'; - break; - case 'r': /* \r = cariage return */ - *pString = '\r'; - break; - case 't': /* \t = tab character */ - *pString = '\t'; - break; - default: /* anything else is just the character after the \ */ - *pString = *in; - } - break; - default: - *pString = *in; - } - ++in; - ++pString; - } - *pString = '\0'; - return (1); - } -} - -/* utility fuinction to print a hex dump */ -static void hexDump(unsigned char *string, int indent) -{ - char ascBuf[17]; /* for the ascii xlation part of the dump */ - int strLength; - unsigned int j, x; - - if (!(strLength = strlen(string))) - { - printf("(null)\n"); - return; - } - j = 0; - - while (j < strLength) - { - if (j) - { - x = indent; - while(x--) - printf(" "); - } - printf("%2.2X: ", j); /* print relative address */ - x = 0; - while ((x < 16) && (j < strLength)) - { - printf("%2.2X ", string[j]); - ascBuf[x] = string[j]; - if (!((ascBuf[x] >= 0x20) && (ascBuf[x] <= 0x7e))) - ascBuf[x] = '.'; - ++x; - ++j; - } - ascBuf[x] = '\0'; - while (x++ <= 16) - printf(" "); - - printf(" *%s*\n", ascBuf); - } - return; -} - -/* - * showGpibMsg(msgNum) *********************************************** - * - * - * Print the gpib message contents onto the screen. - * msgNum selects the message to be displayed - * - */ - -static int -showGpibMsg(msgNum) -int msgNum; - -{ - struct gpibIntCmd *pCmd = &gpibIntCmds[msgNum]; - - printf("\nMessage #%1.1d : ", msgNum); - printf("LinkType=%d bug=%d Link=%d Adrs=%d Type=%c\n", - pCmd->linkType, pCmd->bug, pCmd->linkId, pCmd->head.device, pCmd->type); - - if (hexmode) - { - printf("Cmd: "); - hexDump(pCmd->cmd, 5); - printf("Res: "); - hexDump(pCmd->resp, 5); - } - else - { - printf(" Command String : %.40s\n", pCmd->cmd); - printf(" Response String : %.40s\n", pCmd->resp); - } - return(0); -} - diff --git a/src/vxWorks/devOpt/devK486Gpib.c b/src/vxWorks/devOpt/devK486Gpib.c deleted file mode 100644 index ca1a84f2c..000000000 --- a/src/vxWorks/devOpt/devK486Gpib.c +++ /dev/null @@ -1,326 +0,0 @@ -/* devK486Gpib.c */ -/* @(#)devK486Gpib.c 1.2 3/18/92 */ - -/* - * Author: Bill Brown - * Date: 03-18-93 - * - * 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 - * - * The Control Systems Group - * Systems Engineering Department - * Lawrence Berkeley 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 03-18-93 wlb Initial Release - */ - -#define DSET_AI devAiK486Gpib -#define DSET_AO devAoK486Gpib -#define DSET_LI devLiK486Gpib -#define DSET_LO devLoK486Gpib -#define DSET_BI devBiK486Gpib -#define DSET_BO devBoK486Gpib -#define DSET_MBBO devMbboK486Gpib -#define DSET_MBBI devMbbiK486Gpib -#define DSET_SI devSiK486Gpib -#define DSET_SO devSoK486Gpib - -#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 - -static long init_dev_sup(), report(); -static struct devGpibParmBlock devSupParms; - -/****************************************************************************** - * - * Define all the dset's. - * - * Note that the dset names are provided via the #define lines at the top of - * this file. - * - * Other than for the debugging flag(s), these DSETs are the only items that - * will appear in the global name space within the IOC. - * - * The last 3 items in the DSET structure are used to point to the parm - * structure, the work functions used for each record type, and the srq - * handler for each record type. - * - ******************************************************************************/ -gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, - devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; - -gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, - devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; - -gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, - devGpibLib_readBi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; - -gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, - devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; - -gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, - devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; - -gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, - devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; - -gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, - devGpibLib_readSi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; - -gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, - devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; - -gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, - devGpibLib_readLi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; - -gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, - devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; - -int K486Debug = 0; /* debugging flags */ - -/* - * Use the TIME_WINDOW defn to indicate how long commands should be ignored - * for a given device after it times out. The ignored commands will be - * returned as errors to device support. - * - * Use the DMA_TIME to define how long you wish to wait for an I/O operation - * to complete once started. - */ -#define TIME_WINDOW 300 /* 10 seconds on a getTick call */ -#define DMA_TIME 60 /* 1/2 second on a watchdog time */ - -/* - * Strings used by the init routines to fill in the znam, onam, ... - * fields in BI, BO, MBBI, and MBBO record types. - */ - -static char *offOnList[] = { "Off", "On" }; -static struct devGpibNames offOn = { 2, offOnList, NULL, 1 }; - -static char *disableEnableList[] = { "Disable", "Enable" }; -static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 }; - -static char *resetList[] = { "Reset", "Reset" }; -static struct devGpibNames reset = { 2, resetList, NULL, 1 }; - -static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" }; -static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1}; - -static char *invertNormList[] = { "INVERT", "NORM" }; -static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 }; - -static char *fallingRisingList[] = { "FALLING", "RISING" }; -static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 }; - -static char *singleShotList[] = { "SINGLE", "SHOT" }; -static struct devGpibNames singleShot = { 2, singleShotList, NULL, 1 }; - -static char *clearList[] = { "CLEAR", "CLEAR" }; -static struct devGpibNames clear = { 2, clearList, NULL, 1 }; - -static char *tABCDList[] = { "T", "A", "B", "C", "D" }; -static unsigned long tABCDVal[] = { 1, 2, 3, 5, 6 }; -static struct devGpibNames tABCD = { 5, tABCDList, tABCDVal, 3 }; - -static char *ttlNimEclVarList[] = { "TTL", "NIM", "ECL", "VAR" }; -static unsigned long ttlNimEclVarVal[] = { 0, 1, 2, 3 }; -static struct devGpibNames ttlNimEclVar = { 4, ttlNimEclVarList, - ttlNimEclVarVal, 2 }; - -static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL", - "SINGLE SHOT", "BURST MODE", "STOP" }; -static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 }; -static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList, - intExtSsBmStopVal, 2 }; -static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList, - intExtSsBmStopVal, 3 }; - - -/****************************************************************************** - * - * String arrays for EFAST operations. Note that the last entry must be - * NULL. - * - * On input operations, only as many bytes as are found in the string array - * elements are compared. If there are more bytes than that in the input - * message, they are ignored. The first matching string found (starting - * from the 0'th element) will be used as a match. - * - * NOTE: For the input operations, the strings are compared literally! This - * can cause problems if the instrument is returning things like \r and \n - * characters. You must take care when defining input strings so you include - * them as well. - * - ******************************************************************************/ - -static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL}; - -/****************************************************************************** - * - * Array of structures that define all GPIB messages - * supported for this type of instrument. - * - ******************************************************************************/ - -/* forward declarations of some custom convert routines */ -int setDelay(); -int rdDelay(); - -static struct gpibCmd gpibCmds[] = - { - /* Param 0, (model) */ - FILL, - - /* Param 1 initialization string */ - { - &DSET_BO, GPIBCMD, IB_Q_HIGH, "L0 X B0 G1 R0 S1 C2 X C0 T5 X", - NULL, 0, 32, NULL, 0, 0, NULL, NULL, -1 - }, - - /* Param 2 read current value */ - { - &DSET_AI, /* record type {analog in} */ - GPIBREAD, /* GPIB I/O operation type {read} */ - IB_Q_HIGH, /* processing priority */ - "X", /* command sent to device */ - "%*4c%lf", /* string descriptor for sscanf() */ - 0, /* buffer pointer */ - 32, /* buffer length */ - NULL, /* special I/O operation */ - 0, /* passed to func specified by */ - 0, /* ditto */ - NULL, /* ditto */ - NULL, /* name table pointer */ - -1 /* reserved */ - } - - }; - - -/* The following is the number of elements in the command array above. */ -#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) - -/****************************************************************************** - * - * Structure containing the user's functions and operating parameters needed - * by the gpib library functions. - * - * The magic SRQ parm is the parm number that, if specified on a passive - * record, will cause the record to be processed automatically when an - * unsolicited SRQ interrupt is detected from the device. - * - * If the parm is specified on a non-passive record, it will NOT be processed - * when an unsolicited SRQ is detected. - * - ******************************************************************************/ -static struct devGpibParmBlock devSupParms = - { - &K486Debug, /* debugging flag pointer */ - -1, /* set to -1 if the device does NOT respond to writes */ - TIME_WINDOW, /* # of clock ticks to skip after a device times out */ - NULL, /* hwpvt list head */ - gpibCmds, /* GPIB command array */ - NUMPARAMS, /* number of supported parameters */ - -1, /* magic SRQ param number (-1 if none) */ - "devXxK486Gpib", /* device support module type name */ - DMA_TIME, /* # of clock ticks to wait for DMA completions */ - - NULL, /* pointer to SRQ handler function (NULL if none) */ - NULL /* pointer to secondary conversion routine */ - }; - -/****************************************************************************** - * - * 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. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -static long -init_dev_sup(parm) -int parm; -{ - return(devGpibLib_initDevSup(parm, &DSET_AI)); -} - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -static long -report() -{ - return(devGpibLib_report(&DSET_AI)); -} diff --git a/src/vxWorks/devOpt/devXxBugRac.c b/src/vxWorks/devOpt/devXxBugRac.c deleted file mode 100644 index e070747ec..000000000 --- a/src/vxWorks/devOpt/devXxBugRac.c +++ /dev/null @@ -1,536 +0,0 @@ -/* devXxBugRac.c */ - -/* Device Support Routines for BUF RAC commands */ -/* - * Original Author: Ned Arnold (based on work by Jim Kowalkowski) - * Date: 02/01/93 - * - * 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 02-01093 nda initialized - * .02 06-03-94 nda removed automatic retry on a TIMEOUT - * .03 06-03-94 nda removed drvBitBus.qReq at init time - * ... - */ - - - -#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 - -/* types */ -#define AI 0x01 -#define AO 0x02 -#define BI 0x03 -#define BO 0x04 -#define LI 0x05 -#define LO 0x06 -#define MBBI 0x07 -#define MBBO 0x08 - - -/* Define forward references */ -long report(); -long init(); -static long init_ai(); -static long init_ao(); -static long init_bo(); -static long init_bi(); -static long init_li(); -long init_lo(); -static long init_mbbi(); -static long init_mbbo(); -long get_ioint_info(); -static long bug_rac(); - -/* Create the dsets for devXxBugRac */ -typedef struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_write; - DEVSUPFUN special_linconv; -} IODSET; - -/* DEFINE SUPPORTED RAC COMMANDS -#define RESET_STATION 0x00 /* BO record */ -#define GET_FUNCTION_ID 0x03 /* LI record */ - -/* xxDSET devXxxx={ 5,report,init,init_rec,get_ioint_info,bug_rac}; */ - -IODSET devBoBugRac = { 5, NULL, NULL, init_bo, NULL, bug_rac }; -IODSET devLiBugRac = { 5, NULL, NULL, init_li, NULL, bug_rac }; - -/* forward references */ - -static void get_data(); -static void send_cntl_trans(); -extern struct drvBitBusEt drvBitBus; - -volatile int bugRacDebug=0; - -#define OFF 0 -#define ON 1 - -#ifdef NODEBUG -#define Debug(FMT,V) ; -#else -#define Debug(FMT,V) { if(bugRacDebug) \ - {\ - printf("%s(%d):",__FILE__,__LINE__); \ - printf(FMT,V); \ - } \ - } -#endif - - - -struct dprivate { - struct dpvtBitBusHead bitbus; - char type; - unsigned char cmd; - struct dbCommon *precord; /* at end for callback to get it */ -}; - -static int io_callback(struct dprivate *pcallback) -{ - struct dbCommon *precord; - struct rset *prset; - - precord=pcallback->precord; - prset=(struct rset *)(precord->rset); - - dbScanLock(precord); - (*prset->process)(precord); - dbScanUnlock(precord); -} - -static struct dprivate * set_bitbus(int prio,unsigned char cmd,struct bitbusio *pbitbusio) -{ - struct dprivate *my_dpvt; - - my_dpvt=(struct dprivate *)(malloc(sizeof(struct dprivate))); - - my_dpvt->bitbus.finishProc=io_callback; - my_dpvt->bitbus.psyncSem=(SEM_ID *)NULL; - my_dpvt->bitbus.priority=prio; - my_dpvt->bitbus.link=pbitbusio->link; - my_dpvt->bitbus.rxMaxLen=9; - my_dpvt->bitbus.ageLimit=240; - - my_dpvt->bitbus.txMsg.length=9; - my_dpvt->bitbus.txMsg.route=0x40; - my_dpvt->bitbus.txMsg.node=pbitbusio->node; - my_dpvt->bitbus.txMsg.tasks=0; - my_dpvt->bitbus.txMsg.cmd=cmd; - my_dpvt->bitbus.txMsg.data=(unsigned char *)malloc(2); - my_dpvt->bitbus.rxMsg.data=(unsigned char *)malloc(BB_MAX_DAT_LEN); - - my_dpvt->bitbus.txMsg.data[0]='\0'; - my_dpvt->bitbus.txMsg.data[1]='\0'; - - Debug("command sent:(%02.2x)\n", my_dpvt->bitbus.txMsg.cmd); - - return(my_dpvt); -} - - -static long init_ai(struct aiRecord *ai) -{ - struct bitbusio *pbitbusio = (struct bitbusio *)(&ai->inp.value); - struct dprivate *my_dpvt; - int ret; - - Debug("init ai invoked\n",0); - - /* type must be an BITBUS_IO */ - if(ai->inp.type!=BITBUS_IO) - { - recGblRecordError(S_dev_badBus,(void *)ai, - "devXxBugRac (init_record) Illegal IN Bus Type"); - return(S_dev_badBus); - } - - - my_dpvt=set_bitbus(ai->prio,pbitbusio->signal,pbitbusio); - my_dpvt->precord = (struct dbCommon *)ai; - my_dpvt->type = AI; - - ai->dpvt=(void *)my_dpvt; - return(0); -} - - -static long init_ao(struct aoRecord *ao) -{ - struct bitbusio *pbitbusio = (struct bitbusio *)(&ao->out.value); - struct dprivate *my_dpvt; - - Debug("init ao invoked\n",0); - - /* out must be an BITBUS_IO */ - if(ao->out.type!=BITBUS_IO) - { - recGblRecordError(S_dev_badBus,(void *)ao, - "devXxBugRac (init_record) Illegal OUT Bus Type"); - return(S_dev_badBus); - } - - my_dpvt=set_bitbus(ao->prio,pbitbusio->signal,pbitbusio); - my_dpvt->precord = (struct dbCommon *)ao; - my_dpvt->type = AO; - - ao->dpvt=(void *)my_dpvt; - - return(0); -} - - -static long init_bi(struct biRecord *bi) -{ - struct bitbusio *pbitbusio = (struct bitbusio *)(&bi->inp.value); - struct dprivate *my_dpvt; - unsigned char cmd = 0; - - Debug("init bi invoked\n",0); - - /* out must be an BITBUS_IO */ - if(bi->inp.type!=BITBUS_IO) - { - recGblRecordError(S_dev_badBus,(void *)bi, - "devXxBugRac (init_record) Illegal IN Bus Type"); - return(S_dev_badBus); - } - - - my_dpvt=set_bitbus(bi->prio,pbitbusio->signal,pbitbusio); - my_dpvt->precord = (struct dbCommon *)bi; - my_dpvt->type = BI; - my_dpvt->cmd = cmd; - bi->dpvt=(void *)my_dpvt; - - return(0); -} - - -static long init_bo(struct boRecord *bo) -{ - struct bitbusio *pbitbusio = (struct bitbusio *)(&bo->out.value); - struct dprivate *my_dpvt; - - Debug("init bo invoked\n",0); - - /* out must be an BITBUS_IO */ - if(bo->out.type!=BITBUS_IO) - { - recGblRecordError(S_dev_badBus,(void *)bo, - "devXxBugRac (init_record) Illegal IN Bus Type"); - return(S_dev_badBus); - } - - switch(pbitbusio->signal) - { - default: - recGblRecordError(S_dev_badBus,(void *)bo, - "devXxBugRac (init_record) Illegal IN signal number"); - return(S_dev_badBus); - case 0: /* signal 0 is a bo record */ - break; - } - - my_dpvt=set_bitbus(bo->prio,pbitbusio->signal,pbitbusio); - my_dpvt->precord = (struct dbCommon *)bo; - my_dpvt->type = BO; - my_dpvt->cmd = pbitbusio->signal; - - bo->dpvt=(void *)my_dpvt; - - return(0); -} - - -static long init_li(struct longinRecord *li) -{ - struct bitbusio *pbitbusio = (struct bitbusio *)(&li->inp.value); - struct dprivate *my_dpvt; - unsigned char cmd = 0; - - Debug("init li invoked\n",0); - - /* out must be an BITBUS_IO */ - if(li->inp.type!=BITBUS_IO) - { - recGblRecordError(S_dev_badBus,(void *)li, - "devXxBugRac (init_record) Illegal IN Bus Type"); - return(S_dev_badBus); - } - - switch(pbitbusio->signal) - { - default: - recGblRecordError(S_dev_badBus,(void *)li, - "devXxBugRac (init_record) Illegal IN signal number"); - return(S_dev_badBus); - case 3: /* signal 3 is a li record */ - break; - } - - my_dpvt=set_bitbus(li->prio,pbitbusio->signal,pbitbusio); - my_dpvt->precord = (struct dbCommon *)li; - my_dpvt->type = LI; - my_dpvt->cmd = pbitbusio->signal; - li->dpvt=(void *)my_dpvt; - - return(0); -} - - -static long init_mbbi(struct mbbiRecord *mbbi) -{ - struct bitbusio *pbitbusio = (struct bitbusio *)(&mbbi->inp.value); - struct dprivate *my_dpvt; - unsigned char cmd = 0; - - Debug("init mbbi invoked\n",0); - - /* out must be an BITBUS_IO */ - if(mbbi->inp.type!=BITBUS_IO) - { - recGblRecordError(S_dev_badBus,(void *)mbbi, - "devXxBugRac (init_record) Illegal IN Bus Type"); - return(S_dev_badBus); - } - - my_dpvt=set_bitbus(mbbi->prio,pbitbusio->signal,pbitbusio); - my_dpvt->precord = (struct dbCommon *)mbbi; - my_dpvt->type = MBBI; - my_dpvt->cmd = cmd; - mbbi->dpvt=(void *)my_dpvt; - - return(0); -} - - -static long init_mbbo(struct mbboRecord *mbbo) -{ - struct bitbusio *pbitbusio = (struct bitbusio *)(&mbbo->out.value); - struct dprivate *my_dpvt; - unsigned char cmd = 0; - - Debug("init mbbo invoked\n",0); - - /* out must be an BITBUS_IO */ - if(mbbo->out.type!=BITBUS_IO) - { - recGblRecordError(S_dev_badBus,(void *)mbbo, - "devXxBugRac (init_record) Illegal OUT Bus Type"); - return(S_dev_badBus); - } - - if(pbitbusio->signal >= 8 ) - { - recGblRecordError(S_dev_badBus,(void *)mbbo, - "devXxBugRac (init_record) Illegal OUT signal number"); - return(S_dev_badBus); - } - - my_dpvt=set_bitbus(mbbo->prio,pbitbusio->signal,pbitbusio); - my_dpvt->precord = (struct dbCommon *)mbbo; - my_dpvt->type = MBBO; - my_dpvt->cmd = cmd; - - mbbo->dpvt=(void *)my_dpvt; - - return(0); -} - - -static long bug_rac(struct dbCommon *io) -{ - struct dprivate *my_dpvt=(struct dprivate *)io->dpvt; - struct dpvtBitBusHead *pbitbus; - - if(!io->dpvt) return(S_dev_NoInit); - - pbitbus=&(my_dpvt->bitbus); - - if(io->pact==TRUE) - { - Debug("Bitbus message completed \n",0); - - /* a transaction to bitbus has completed */ - switch(pbitbus->status) - { - case BB_OK: - Debug("Getting data \n",0); - get_data(io); - return(0); - default: - recGblSetSevr(io,WRITE_ALARM,MAJOR_ALARM); - recGblRecordError(S_dev_badBus,(void *)io, - "devXxBugRac (iobug_rdwr) BitBus Error!"); - return(S_dev_badBus); - } - } - else - { - /* data needs to be sent to bitbus */ - Debug("Sending transaction \n",0); - send_cntl_trans(io); - } - - io->pact=TRUE; - - /* queue the command */ - if((*drvBitBus.qReq)(pbitbus,BB_Q_LOW)<0) - { - recGblSetSevr(io,WRITE_ALARM,MAJOR_ALARM); - recGblRecordError(S_dev_badBus,(void *)io, - "devXxBugRac (init_record) Initial BitBus message failed"); - return(S_dev_badBus); - } - Debug("Queued transaction \n",0); - - return(0); -} - -static void get_data(struct dbCommon *io) -{ - struct dprivate *my_dpvt=(struct dprivate *)io->dpvt; - struct dpvtBitBusHead *pbitbus; - struct boRecord *bo; - struct biRecord *bi; - struct aoRecord *ao; - struct aiRecord *ai; - struct longoutRecord *lo; - struct longinRecord *li; - struct mbboRecord *mbbo; - struct mbbiRecord *mbbi; - long value; - unsigned long uvalue; - - pbitbus=&(my_dpvt->bitbus); - - Debug("Command return: 0x%04.4X\n",pbitbus->rxMsg.cmd); - Debug("byte 1 of return: 0x%04.4X\n",pbitbus->rxMsg.data[0]); - Debug("byte 2 of return: 0x%04.4X\n",pbitbus->rxMsg.data[1]); - - switch(my_dpvt->type) - { - case LI: - li=(struct longinRecord *)io; - switch(my_dpvt->bitbus.txMsg.cmd) - { - case GET_FUNCTION_ID: - /* extract the second ID code (task 1) */ - li->val = pbitbus->rxMsg.data[1]; - li->udf = 0; - if ((pbitbus->rxMsg.cmd) != 0) - { - recGblSetSevr(li, READ_ALARM, INVALID_ALARM); - } - break; - default: - break; - } - default: - break; - } - - return; -} - -static void send_cntl_trans(struct dbCommon *io) -{ - struct dprivate *my_dpvt=(struct dprivate *)io->dpvt; - struct dpvtBitBusHead *pbitbus; - struct boRecord *bo; - struct aoRecord *ao; - struct mbboRecord *mbbo; - short lsb,msb; - - pbitbus=&(my_dpvt->bitbus); - - pbitbus->finishProc=io_callback; - pbitbus->psyncSem=(SEM_ID *)NULL; - pbitbus->priority=io->prio; - pbitbus->txMsg.cmd=my_dpvt->cmd; - - switch(my_dpvt->type) - { - case BO: - bo=(struct boRecord *)io; - break; - case MBBO: - mbbo=(struct mbboRecord *)io; - break; - case AO: - ao=(struct aoRecord *)io; - pbitbus->txMsg.data[0]=0; - pbitbus->txMsg.data[1]=0; - break; - default: - break; - } - - my_dpvt->precord=(struct dbCommon *)io; - - Debug("Command send: 0x%02.2X\n",pbitbus->txMsg.cmd); - Debug("byte 1 sent: 0x%02.2X\n",(unsigned char)pbitbus->txMsg.data[0]); - Debug("byte 2 sent: 0x%02.2X\n",(unsigned char)pbitbus->txMsg.data[1]); - - return; -} diff --git a/src/vxWorks/devOpt/devXxDc5009Gpib.c b/src/vxWorks/devOpt/devXxDc5009Gpib.c deleted file mode 100644 index 56e93054a..000000000 --- a/src/vxWorks/devOpt/devXxDc5009Gpib.c +++ /dev/null @@ -1,406 +0,0 @@ -/* devXxDc5009Gpib.c */ -/* share/src/devOpt $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 05-30-91 jrw Initial Release - */ - -/****************************************************************************** - * - * The following define statements are used to declare the names to be used - * for the dset tables. - * - * NOTE: The dsets are referenced by the entries in the command table. - * - ******************************************************************************/ -#define DSET_AI devAiDc5009Gpib -#define DSET_AO devAoDc5009Gpib -#define DSET_LI devLiDc5009Gpib -#define DSET_LO devLoDc5009Gpib -#define DSET_BI devBiDc5009Gpib -#define DSET_BO devBoDc5009Gpib -#define DSET_MBBO devMbboDc5009Gpib -#define DSET_MBBI devMbbiDc5009Gpib -#define DSET_SI devSiDc5009Gpib -#define DSET_SO devSoDc5009Gpib - -#define STATIC static - -#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 - -STATIC long init_dev_sup(), report(); -STATIC int srqHandler(); -STATIC struct devGpibParmBlock devSupParms; - -/****************************************************************************** - * - * Define all the dset's. - * - * Note that the dset names are provided via the #define lines at the top of - * this file. - * - * Other than for the debugging flag(s), these DSETs are the only items that - * will appear in the global name space within the IOC. - * - * The last 3 items in the DSET structure are used to point to the parm - * structure, the work functions used for each record type, and the srq - * handler for each record type. - * - ******************************************************************************/ -gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, - devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; - -gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, - devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; - -gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, - devGpibLib_readBi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; - -gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, - devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; - -gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, - devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; - -gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, - devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; - -gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, - devGpibLib_readSi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; - -gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, - devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; - -gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, - devGpibLib_readLi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; - -gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, - devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; - -/****************************************************************************** - * - * Debugging flags that can be accessed from the shell. - * - ******************************************************************************/ -int Dc5009Debug = 0; -extern int ibSrqDebug; /* declared in the GPIB driver */ - -/****************************************************************************** - * - * Use the TIME_WINDOW defn to indicate how long commands should be ignored - * for a given device after it times out. The ignored commands will be - * returned as errors to device support. - * - * Use the DMA_TIME to define how long you wish to wait for an I/O operation - * to complete once started. - * - * These are to be declared in 60ths of a second. - * - ******************************************************************************/ -#define TIME_WINDOW 600 /* 10 seconds on a getTick call */ -#define DMA_TIME 60 /* 1 second on a watchdog time */ - -/****************************************************************************** - * - * Strings used by the init routines to fill in the znam, onam, ... - * fields in BI, BO, MBBI, and MBBO record types. - ******************************************************************************/ - -static char *offOnList[] = { "Off", "On" }; -static struct devGpibNames offOn = { 2, offOnList, NULL, 1 }; - -static char *offOffList[] = { "Off", "Off" }; -static struct devGpibNames offOff = { 2, offOffList, NULL, 1 }; - -static char *onOnList[] = { "On", "On" }; -static struct devGpibNames onOn = { 2, onOnList, NULL, 1 }; - -static char *initNamesList[] = { "Init", "Init" }; -static struct devGpibNames initNames = { 2, initNamesList, NULL, 1 }; - -static char *disableEnableList[] = { "Disable", "Enable" }; -static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 }; - -static char *resetList[] = { "Reset", "Reset" }; -static struct devGpibNames reset = { 2, resetList, NULL, 1 }; - -static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" }; -static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1}; - -static char *invertNormList[] = { "INVERT", "NORM" }; -static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 }; - -static char *fallingRisingList[] = { "FALLING", "RISING" }; -static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 }; - -static char *clearList[] = { "CLEAR", "CLEAR" }; -static struct devGpibNames clear = { 2, clearList, NULL, 1 }; - -/****************************************************************************** - * - * String arrays for EFAST operations. Note that the last entry must be - * NULL. - * - * On input operations, only as many bytes as are found in the string array - * elements are compared. If there are more bytes than that in the input - * message, they are ignored. The first matching string found (starting - * from the 0'th element) will be used as a match. - * - * NOTE: For the input operations, the strings are compared literally! This - * can cause problems if the instrument is returning things like \r and \n - * characters. You must take care when defining input strings so you include - * them as well. - * - ******************************************************************************/ - -static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL}; - -/****************************************************************************** - * - * Array of structures that define all GPIB messages - * supported for this type of instrument. - * - ******************************************************************************/ - -static struct gpibCmd gpibCmds[] = -{ - /* Param 0, init the device */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "init", NULL, 0, 32, - NULL, 0, 0, NULL, &initNames, -1}, - - /* Param 1, set ability to generate SRQs by pressing the ID button */ - {&DSET_BO, GPIBEFASTO, IB_Q_HIGH, NULL, NULL, 0, 32, - NULL, 0, 0, userOffOn, &offOn, -1}, - - /* Param 2, dissallow user-gen'd SRQs */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "user off", NULL, 0, 32, - NULL, 0, 0, NULL, &offOff, -1}, - - /* Param3, create an error */ - {&DSET_BO, GPIBCMD, IB_Q_LOW, "XyZzY", NULL, 0, 32, - NULL, 0, 0, NULL, &onOn, -1}, - - /* Param4, read the error status */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "err?", "ERR %lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 5 read the user button status */ - {&DSET_BI, GPIBEFASTI, IB_Q_HIGH, "user?", NULL, 0, 32, - NULL, 0, 0, userOffOn, &offOn, -1}, - - /* Param 6 send a reading from the display */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "DISP?", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1} -}; - -/* The following is the number of elements in the command array above. */ -#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) - -/****************************************************************************** - * - * Structure containing the user's functions and operating parameters needed - * by the gpib library functions. - * - * The magic SRQ parm is the parm number that, if specified on a passive - * record, will cause the record to be processed automatically when an - * unsolicited SRQ interrupt is detected from the device. - * - * If the parm is specified on a non-passive record, it will NOT be processed - * when an unsolicited SRQ is detected. - * - * In the future, the magic SRQ parm records will be processed as "I/O event - * scanned"... not passive. - * - ******************************************************************************/ -STATIC struct devGpibParmBlock devSupParms = { - &Dc5009Debug, /* debugging flag pointer */ - -1, /* device does not respond to writes */ - TIME_WINDOW, /* # of clock ticks to skip after a device times out */ - NULL, /* hwpvt list head */ - gpibCmds, /* GPIB command array */ - NUMPARAMS, /* number of supported parameters */ - 4, /* magic SRQ param number (-1 if none) */ - "devXxDc5009Gpib", /* device support module type name */ - DMA_TIME, /* # of clock ticks to wait for DMA completions */ - - srqHandler, /* SRQ handler function (NULL if none) */ - - NULL /* secondary conversion routine (NULL if none) */ -}; - -/****************************************************************************** - * - * 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. - * - ******************************************************************************/ -STATIC long -init_dev_sup(int parm) -{ - return(devGpibLib_initDevSup(parm,&DSET_AI)); -} - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - ******************************************************************************/ -STATIC long -report(void) -{ - return(devGpibLib_report(&DSET_AI)); -} - -/****************************************************************************** - * - * This is invoked by the linkTask when an SRQ is detected from a device - * operated by this module. - * - * It calls the work routine associated with the type of record expecting - * the SRQ response. - * - * No semaphore locks are needed around the references to anything in the - * hwpvt structure, because it is static unless modified by the linkTask and - * the linkTask is what will execute this function. - * - * THIS ROUTINE WILL GENERATE UNPREDICTABLE RESULTS IF... - * - the MAGIC_SRQ_PARM command is a GPIBREADW command. - * - the device generates unsolicited SRQs while processing GPIBREADW commands. - * - * In general, this function will have to be modified for each device - * type that SRQs are to be supported. This is because the serial poll byte - * format varies from device to device. - * - ******************************************************************************/ - -#define DC5009_GOODBITS 0xef /* I only care about these bits */ - -#define DC5009_PON 65 /* power just turned on */ -#define DC5009_OPC 66 /* operation just completed */ -#define DC5009_USER 67 /* user requested SRQ */ - -STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus) -{ - int status = IDLE; /* assume device will be idle when finished */ - - if (Dc5009Debug || ibSrqDebug) - printf("dc5009 srqHandler(%p, 0x%2.2X): called\n", phwpvt, srqStatus); - - switch (srqStatus & DC5009_GOODBITS) { - case DC5009_OPC: - - /* Invoke the command-type specific SRQ handler */ - if (phwpvt->srqCallback != NULL) - status = ((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus)); - else - printf("dc5009 srqHandler: Unsolicited operation complete from DC5009 device support!\n"); - break; -/* BUG - I have to clear out the error status by doing an err? read operation */ - - case DC5009_USER: - - /* user requested srq event is specific to the Dc5009 */ - printf("dc5009 srqHandler: Dc5009 User requested srq event link %d, device %d\n", phwpvt->link, phwpvt->device); - break; -/* BUG - I have to clear out the error status by doing an err? read operation */ - - case DC5009_PON: - - printf("dc5009 srqHandler: Power cycled on DC5009\n"); - break; -/* BUG - I have to clear out the error status by doing an err? read operation */ - - default: - - - if (phwpvt->unsolicitedDpvt != NULL) - { - if(Dc5009Debug || ibSrqDebug) - printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%2.2X\n", - phwpvt->link, phwpvt->device, srqStatus); - - ((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process; - ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri; - callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt); - } - else - { - printf("dc5009 srqHandler: Unsolicited SRQ ignored from link %d, device %d, status = 0x%2.2X\n", - phwpvt->link, phwpvt->device, srqStatus); - } - } - return(status); -} diff --git a/src/vxWorks/devOpt/devXxDg535Gpib.c b/src/vxWorks/devOpt/devXxDg535Gpib.c deleted file mode 100644 index dce336776..000000000 --- a/src/vxWorks/devOpt/devXxDg535Gpib.c +++ /dev/null @@ -1,898 +0,0 @@ -/* devXxDg535Gpib.c */ -/* share/src/devOpt $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 05-30-91 jrw Initial Release - * .02 01-06-92 nda dg535 support under EPICS 3.3 - */ - -#define DSET_AI devAiDg535Gpib -#define DSET_AO devAoDg535Gpib -#define DSET_LI devLiDg535Gpib -#define DSET_LO devLoDg535Gpib -#define DSET_BI devBiDg535Gpib -#define DSET_BO devBoDg535Gpib -#define DSET_MBBO devMbboDg535Gpib -#define DSET_MBBI devMbbiDg535Gpib -#define DSET_SI devSiDg535Gpib -#define DSET_SO devSoDg535Gpib - -#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 - -#define STATIC static - -STATIC long init_dev_sup(), report(); -STATIC struct devGpibParmBlock devSupParms; - -/* forward declarations of some custom convert routines */ -STATIC int setDelay(); -STATIC int rdDelay(); - - -/****************************************************************************** - * - * Define all the dset's. - * - * Note that the dset names are provided via the #define lines at the top of - * this file. - * - * Other than for the debugging flag(s), these DSETs are the only items that - * will appear in the global name space within the IOC. - * - * The last 3 items in the DSET structure are used to point to the parm - * structure, the work functions used for each record type, and the srq - * handler for each record type. - * - ******************************************************************************/ -gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, - devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; - -gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, - devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; - -gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, - devGpibLib_readBi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; - -gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, - devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; - -gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, - devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; - -gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, - devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; - -gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, - devGpibLib_readSi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; - -gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, - devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; - -gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, - devGpibLib_readLi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; - -gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, - devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; - -int Dg535Debug = 0; /* debugging flags */ -extern int ibSrqDebug; - -/* - * Use the TIME_WINDOW defn to indicate how long commands should be ignored - * for a given device after it times out. The ignored commands will be - * returned as errors to device support. - * - * Use the DMA_TIME to define how long you wish to wait for an I/O operation - * to complete once started. - */ -#define TIME_WINDOW 600 /* 10 seconds on a getTick call */ -#define DMA_TIME 20 /* 1/3 second on a watchdog time */ - -/* - * Strings used by the init routines to fill in the znam, onam, ... - * fields in BI, BO, MBBI, and MBBO record types. - */ - -static char *offOnList[] = { "Off", "On" }; -static struct devGpibNames offOn = { 2, offOnList, NULL, 1 }; - -static char *disableEnableList[] = { "Disable", "Enable" }; -static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 }; - -static char *resetList[] = { "Reset", "Reset" }; -static struct devGpibNames reset = { 2, resetList, NULL, 1 }; - -static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" }; -static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1}; - -static char *invertNormList[] = { "INVERT", "NORM" }; -static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 }; - -static char *fallingRisingList[] = { "FALLING", "RISING" }; -static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 }; - -static char *singleShotList[] = { "SINGLE", "SHOT" }; -static struct devGpibNames singleShot = { 2, singleShotList, NULL, 1 }; - -static char *clearList[] = { "CLEAR", "CLEAR" }; -static struct devGpibNames clear = { 2, clearList, NULL, 1 }; - -static char *tABCDList[] = { "T", "A", "B", "C", "D" }; -static unsigned long tABCDVal[] = { 1, 2, 3, 5, 6 }; -static struct devGpibNames tABCD = { 5, tABCDList, tABCDVal, 3 }; - -static char *ttlNimEclVarList[] = { "TTL", "NIM", "ECL", "VAR" }; -static unsigned long ttlNimEclVarVal[] = { 0, 1, 2, 3 }; -static struct devGpibNames ttlNimEclVar = { 4, ttlNimEclVarList, - ttlNimEclVarVal, 2 }; - -static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL", - "SINGLE SHOT", "BURST MODE", "STOP" }; -static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 }; -static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList, - intExtSsBmStopVal, 2 }; -static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList, - intExtSsBmStopVal, 3 }; - -/* Channel Names, used to derive string representation of programmed delay */ - -char *pchanName[8] = {" ", "T + ", "A + ", "B + ", " ", "C + ", "D + ", " "}; - -/****************************************************************************** - * - * String arrays for EFAST operations. Note that the last entry must be - * NULL. - * - * On input operations, only as many bytes as are found in the string array - * elements are compared. If there are more bytes than that in the input - * message, they are ignored. The first matching string found (starting - * from the 0'th element) will be used as a match. - * - * NOTE: For the input operations, the strings are compared literally! This - * can cause problems if the instrument is returning things like \r and \n - * characters. You must take care when defining input strings so you include - * them as well. - * - ******************************************************************************/ - -static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL}; - -/****************************************************************************** - * - * Array of structures that define all GPIB messages - * supported for this type of instrument. - * - ******************************************************************************/ - - -static struct gpibCmd gpibCmds[] = -{ - /* Param 0, (model) */ - FILL, - - /* Channel A Delay and Output */ - /* Param 1, write A delay */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 2\n", "DT 2,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL, -1}, - - /* Param 2, currently undefined */ - FILL, - - /* Param 3, read A Delay */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL, -1 }, - - /* Param 4, read A delay reference channel and delay as string */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL, -1 }, - - /* Param 5, set A delay reference channel */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 2\n", "DT 2,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD, -1}, - - /* Param 6, read A delay reference */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, &tABCD, -1}, - - /* Param 7, set A output mode */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 8, read A output mode */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 9, set A output amplitude */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 2,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 10, read A output amplitude */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 2\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 11, set A output offset */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 2,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 12, read A output offset */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 2\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 13, set A output Termination */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 14, read A output Termination */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 15, set A output Polarity */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 2,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm, -1}, - - /* Param 16, read A output Polarity */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 2\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - -/* Channel B Delay and Output */ - /* Param 17, write B delay */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 3\n", "DT 3,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL, -1}, - - /* Param 18, currently undefined */ - FILL, - - /* Param 19, read B Delay */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL, -1}, - - /* Param 20, read B delay reference channel and delay as string */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL, -1 }, - - /* Param 21, set B delay reference channel */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 3\n", "DT 3,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD, -1}, - - /* Param 22, read B delay reference */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32, - rdDelay, 0 ,0, NULL, &tABCD, -1}, - - /* Param 23, set B output mode */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 24, read B output mode */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 3\n", "%lu", 0 ,32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 25, set B output amplitude */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 3,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 26, read B output amplitude */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 3\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 27, set B output offset */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 3,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 28, read B output offset */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 3\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 29, set B output Termination */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 30, read B output Termination */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 3\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 31, set B output Polarity */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 3,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm, -1}, - - /* Param 32, read B output Polarity */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 3\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - -/* Channel AB Outputs */ - /* Param 33, set AB output mode */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 34, read AB output mode */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 35, set AB output amplitude */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 4,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 36, read AB output amplitude */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 4\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 37, set AB output offset */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 4,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 38, read AB output offset */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 4\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 39, set AB output Termination */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 40, read AB output Termination */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 41, set AB output Polarity */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 4,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm, -1}, - - /* Param 42, read AB output Polarity */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 4\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - -/* Channel C Delay and Output */ - /* Param 43, write C delay */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 5\n", "DT 5,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL, -1}, - - /* Param 44, currently undefined */ - FILL, - - /* Param 45, read C Delay */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL, -1}, - - /* Param 46, read C delay reference channel and delay as string */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL, -1 }, - - /* Param 47, set C delay reference channel */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 5\n", "DT 5,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD, -1}, - - /* Param 48, read C delay reference */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, &tABCD, -1}, - - /* Param 49, set C output mode */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 50, read C output mode */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 51, set C output amplitude */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 5,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 52, read C output amplitude */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 5\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 53, set C output offset */ - {&DSET_AI, GPIBWRITE, IB_Q_HIGH, NULL, "OO 5,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 54, read C output offset */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 5\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 55, set C output Termination */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 56, read C utput Termination */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 57, set C output Polarity */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 5,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm, -1}, - - /* Param 58, read C output Polarity */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 5\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - -/* Channel D Delay and Output */ - /* Param 59, write D delay */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 6\n", "DT 6,?,%.12lf\n", 0, 32, - setDelay, 0, 0, NULL, NULL, -1}, - - /* Param 60, currently undefined */ - FILL, - - /* Param 61, read D Delay */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL, -1}, - - /* Param 62, read D delay reference channel and delay as string */ - {&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, - rdDelay, 0, 0, NULL, NULL, -1 }, - - /* Param 63, set D delay reference channel */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 6\n", "DT 6,%u,", 0, 32, - setDelay, 0, 0, NULL, &tABCD, -1}, - - /* Param 64, read D delay reference */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32, - rdDelay, 0 ,0, NULL, &tABCD, -1}, - - /* Param 65, set D output mode */ - {&DSET_MBBI, GPIBWRITE, IB_Q_HIGH, NULL, "OM 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 66, read D output mode */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 67, set D output amplitude */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 6,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 68, read D output amplitude */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 6\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 69, set D output offset */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 6,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 70, read D output offset */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 6\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 71, set D output Termination */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 72, read D output Termination */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 73, set D output Polarity */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 6,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm, -1}, - - /* Param 74, read D output Polarity */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 6\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - -/* Channel CD Outputs */ - /* Param 75, set CD output mode */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 76, read CD output mode */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &ttlNimEclVar, -1}, - - /* Param 77, set CD output amplitude */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 7,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 78, read CD output amplitude */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 7\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 79, set CD output offset */ - {&DSET_AI, GPIBWRITE, IB_Q_HIGH, NULL, "OO 7,%.1f\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 80, read CD output offset */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 7\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 81, set CD output Termination */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 82, read CD output Termination */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 83, set CD output Polarity */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 7,%u\n", 0, 32, - NULL, 0, 0, NULL, &invertNorm, -1}, - - /* Param 84, read CD output Polarity */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 7\n", "%lu", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - -/* Trigger Settings */ - /* Param 85, set Trig Mode */ - {&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "TM %u\n", 0, 32, - NULL, 0, 0, NULL, &intExtSsBmStop, -1}, - - /* Param 86, read Trig Mode */ - {&DSET_MBBI, GPIBREAD, IB_Q_LOW, "TM \n", "%lu", 0, 32, - NULL, 0, 0, NULL, &intExtSsBm, -1}, - - /* Param 87, set Trig Rate */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TR 0,%.3lf\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 88, read Trig Rate */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "TR 0\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 89, set Burst Rate */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TR 1,%.3lf\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 90, read Burst Rate */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "TR 1\n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 91, set Burst Count */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BC %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 92, read Burst Count */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "BC \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 93, set Burst Period */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BP %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 94, read Burst Period */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "BP \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 95, set Trig Input Z */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 0,%u\n", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 96, read Trig Input Z */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 0\n", "%lu", 0, 32, - NULL, 0, 0, NULL, &lozHiz, -1}, - - /* Param 97, set Trig Input slope */ - {&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TS %u\n", 0, 32, - NULL, 0, 0, NULL, &fallingRising, -1}, - - /* Param 98, read Trig Input slope */ - {&DSET_BI, GPIBREAD, IB_Q_LOW, "TS \n", "%lu", 0, 32, - NULL, 0, 0, NULL, &fallingRising, -1}, - - /* Param 99, set Trig Input level */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TL %.2lf\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 100, read Trig Input Level */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "TL \n", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 101, generate Single Trig */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "SS \n", NULL, 0, 32, - NULL, 0, 0, NULL, &singleShot, -1}, - - /* Param 102, Store Setting # */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "ST %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 103, Recall Setting # */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "RC %01.0lf\n", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 104, Recall Setting # */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "CL \n", NULL, 0, 32, - NULL, 0, 0, NULL, &clear, -1} -}; - - -/* The following is the number of elements in the command array above. */ -#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) - -/****************************************************************************** - * - * Structure containing the user's functions and operating parameters needed - * by the gpib library functions. - * - * The magic SRQ parm is the parm number that, if specified on a passive - * record, will cause the record to be processed automatically when an - * unsolicited SRQ interrupt is detected from the device. - * - * If the parm is specified on a non-passive record, it will NOT be processed - * when an unsolicited SRQ is detected. - * - ******************************************************************************/ -static struct devGpibParmBlock devSupParms = { - &Dg535Debug, /* debugging flag pointer */ - -1, /* set to -1 if the device does NOT respond to writes */ - TIME_WINDOW, /* # of clock ticks to skip after a device times out */ - NULL, /* hwpvt list head */ - gpibCmds, /* GPIB command array */ - NUMPARAMS, /* number of supported parameters */ - -1, /* magic SRQ param number (-1 if none) */ - "devXxDg535Gpib", /* device support module type name */ - DMA_TIME, /* # of clock ticks to wait for DMA completions */ - - NULL, /* pointer to SRQ handler function (NULL if none) */ - NULL /* pointer to secondary conversion routine */ -}; - -/****************************************************************************** - * - * 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. - * - ******************************************************************************/ -STATIC long -init_dev_sup(int parm) -{ - return(devGpibLib_initDevSup(parm, &DSET_AI)); -} - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - ******************************************************************************/ -STATIC long -report(void) -{ - return(devGpibLib_report(&DSET_AI)); -} - - -/**************************************************************************** - * - * - * Custom convert routines for DG535 - * - * - ***************************************************************************/ - -/****************************************************************************** - * - * Unique message interpretaion for reading Channel Delays : - * The command to read the delay setting returns a string with two arguments, - * (eg 1, 4.300000000000) - * This routine extracts both arguments and assigns them appropriately. If the - * parameter corresponds to a "READ DELAY INTO STRING RECORD", - * a string is generated with the format CHAN + xxx.xxxxxxxxxxxx and stored - * in the val field of the SI record. (ex: T + .000000500000) - *****************************************************************************/ - -STATIC int rdDelay(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) -{ - int status; - double delay; - unsigned long chan; - - union delayRec { - struct aiRecord ai; - struct mbbiRecord mbbi; - struct stringinRecord si; - } *prec = (union delayRec *) (pdpvt->precord); - - if(Dg535Debug) - printf("rdDelay : returned msg :%s\n",pdpvt->msg); - - /* Change the "," in returned string to a " " to separate fields */ - pdpvt->msg[1] = 0x20; - - /* scan response string for chan reference & delay value */ - status = sscanf(pdpvt->msg, "%ld%lf", &chan, &delay); - - if(Dg535Debug) - { - printf("Dg535 rdDelay(): pdpvt=%p prec=%p status=%ld msg=%s\n", - pdpvt, prec, status, pdpvt->msg); - } - switch (pdpvt->parm) - { - case 4: /* A Delay monitor, must be an si record */ - case 20: /* B Delay monitor, must be an si record */ - case 46: /* C Delay monitor, must be an si record */ - case 62: /* D Delay monitor, must be an si record */ - if (status == 2) /* make sure both parameters were assigned */ - { - /* create a string in the value field*/ - strcpy(prec->si.val, pchanName[chan]); - strcat(prec->si.val, &((pdpvt->msg)[3])); - } - else - { - if (prec->si.nsev < INVALID_ALARM) - { - prec->si.nsev = INVALID_ALARM; - prec->si.nsta = READ_ALARM; - } - } - break; - - case 3: /* A Delay monitor, must be an ai record */ - case 19: /* B Delay monitor, must be an ai record */ - case 45: /* C Delay monitor, must be an ai record */ - case 61: /* D Delay monitor, must be an ai record */ - if (status == 2) /* make sure both parameters were assigned */ - { - /* assign new delay to value field*/ - prec->ai.val = delay; - } - else - { - if (prec->ai.nsev < INVALID_ALARM) - { - prec->ai.nsev = INVALID_ALARM; - prec->ai.nsta = READ_ALARM; - } - } - break; - - case 6: /* A Delay Reference monitor, must be an mbbi record */ - case 22: /* B Delay Reference monitor, must be an mbbi record */ - case 48: /* C Delay Reference monitor, must be an mbbi record */ - case 64: /* D Delay Reference monitor, must be an mbbi record */ - if (status == 2) /* make sure both parameters were assigned */ - { - prec->mbbi.rval = chan; - } - else - { - if (prec->mbbi.nsev < INVALID_ALARM) - { - prec->mbbi.nsev = INVALID_ALARM; - prec->mbbi.nsta = READ_ALARM; - } - } - break; - } - return(OK); -} - -/****************************************************************************** - * - * Unique message generation for writing channel Delays : - * The command to set the channel delay requires two parameters: The channel - * # to reference from and the time delay. Since changing either of these - * parameters requires the entire command to be sent, the current state of - * other parameter must be determined. This is done by reading the delay (which - * returns both parameters), changing one of the paramaters, and sending - * the command back. - * - *************************************************************************/ - -STATIC int setDelay(struct gpibDpvt *pdpvt, int p1, int p2, char **p3) -{ - char curChan; - char tempMsg[32]; - - union delayRec { - struct aoRecord ao; - struct mbboRecord mbbo; - } *prec = (union delayRec *) (pdpvt->precord); - - - /* go read the current delay & channel reference setting */ - /* this is done by specifying a GPIBREAD even though the gpibCmd is - defined as a GPIBWRITE. The cmd string in the gpibCmd is initialized - to make this work */ - - if(devGpibLib_xxGpibWork(pdpvt, GPIBREAD, -1) == ERROR) - { /* abort operation if read failed */ - return(ERROR); /* return, signalling an error */ - } - - /* Due to a fluke in the DG535, read again to insure accurate data */ - - if(devGpibLib_xxGpibWork(pdpvt, GPIBREAD, -1) == ERROR) - { /* abort operation if read failed */ - return(ERROR); /* return, signalling an error */ - } - - /* change one of the two parameters ... */ - - switch(pdpvt->parm) - { - case 1: /* changing time delay */ - case 17: - case 43: - case 59: - curChan = pdpvt->msg[0]; /* save current chan reference */ - /* generate new delay string (correct rounding error) */ - sprintf(pdpvt->msg,gpibCmds[pdpvt->parm].format, (prec->ao.val + 1.0e-13)); - pdpvt->msg[5] = curChan; /* replace "?" with current chan */ - break; - - case 5: /* changing reference channel */ - case 21: - case 47: - case 63: - strcpy(tempMsg, &((pdpvt->msg)[3])); /* save current delay setting */ - /* generate new channel reference */ - sprintf(pdpvt->msg, gpibCmds[pdpvt->parm].format, (unsigned int)prec->mbbo.rval); - strcat(pdpvt->msg, tempMsg); /* append current delay setting */ - break; - } - - if(Dg535Debug) - printf("setDelay : returned msg :%s\n",pdpvt->msg); - - return(OK); /* aoGpibWork or mbboGpibWork will call xxGpibWork */ -} diff --git a/src/vxWorks/devOpt/devXxHvpsGpib.c b/src/vxWorks/devOpt/devXxHvpsGpib.c deleted file mode 100644 index 70742776a..000000000 --- a/src/vxWorks/devOpt/devXxHvpsGpib.c +++ /dev/null @@ -1,1606 +0,0 @@ -/* devXxHvpsGpib.c */ -/* share/src/devOpt $Id$ */ -/* - * Author: Bob Daly - * Date: 10-21-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 10-27-91 winans converted to conform to *NEW* gpib driver - * .02 02-04-92 jba Changed process paramater from precord->pdba to precord - * - * BUGS: - * GPIBSOFT type commands should NOT be processed by the link task. They - * should be handled by a callback task! - */ - -/* Includes support for the following device types : - * "devAiHvpsGpib" - * "devAoHvpsGpib" - * "devBiHvpsGpib" - * "devBoHvpsGpib" - * "devMbbiHvpsGpib" - * "devMbbiHvpsGpib" - * "devStrinHvpsGpib" - * "devStroutHvpsGpib" - */ - -#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 INVALID_ALARM -#define INVALID_ALARM VALID_ALARM -#endif - -extern struct drvGpibSet drvGpib; /* entry points to driver functions */ - -long init_dev_sup(); -long init_rec_ai(); -long read_ai(); -long init_rec_ao(); -long write_ao(); -long init_rec_bi(); -long read_bi(); -long init_rec_bo(); -long write_bo(); -long init_rec_xx(); -long init_rec_stringin(); -long read_stringin(); -long init_rec_stringout(); -long write_stringout(); - -void aiGpibWork(); -void aoGpibWork(); -void biGpibWork(); -void boGpibWork(); -void soGpibWork(); -void siGpibWork(); -void processCallback(); - -int xxGpibWork(); - -/****************************************************************************** - * - * Define all the dset's. - * - ******************************************************************************/ -/* Generic dset structure */ -typedef struct { - long number; - DEVSUPFUN f1; - DEVSUPFUN f2; - DEVSUPFUN f3; - DEVSUPFUN f4; - DEVSUPFUN f5; - DEVSUPFUN f6; -} gDset; - -gDset devAiHvps = {6, NULL, init_dev_sup, init_rec_ai, NULL, read_ai, NULL}; -gDset devSiHvps = {5, NULL, NULL, init_rec_stringin, NULL, read_stringin}; -gDset devAoHvps = {6, NULL, NULL, init_rec_ao, NULL, write_ao, NULL }; -gDset devSoHvps = {5, NULL, NULL, init_rec_stringout, NULL, write_stringout}; -gDset devBiHvps = {5, NULL, NULL, init_rec_bi, NULL, read_bi}; -gDset devBoHvps = {5, NULL, NULL, init_rec_bo, NULL, write_bo}; - -/*#define _SRQSUPPORT_ */ /*NO SRQ SUPPORT*/ -#define RESPONDS_2_WRITES - -#define GPIBREAD 1 -#define GPIBWRITE 2 -#define GPIBCMD 3 -#define GPIBCNTL 4 -#define GPIBSOFT 5 -#define GPIBINIT 6 - -/* BUG - dynamically allocate the hvpsTmoTable, don't hard-code this! */ -/* BUG - this is really based on the number of power supplies, not the links */ -#define MAXGPIBLINKS 2 -/* array for determining elapsed timesince last node timeout */ -static unsigned long hvpsTmoTable[MAXGPIBLINKS][2]; - -/*********************************************************** -* -* device common stuff -* -************************************************************/ -int HvpsDebug = 0; -#define UNDEFINED 1e-37 -static char UDF[10] = "Undefined"; -static char pOK[3] = "OK"; - -/********************************************************** -* -* Hvps specific stuff -* -***********************************************************/ -/* initialization and secondary commands*/ - -/* The operating mode of the HVPS*/ -#define MANUAL 0 -#define REMOTE 1 - -/* Response char in all returned messages from hvps */ - -#define NAK 0x15 -#define ACK 0x6 - -/* Local data settable from the shell */ -int hvpsGpibDelay = 0; - -struct msgMetered { - char acknak; - float data[20]; -}meteredData,lastData,onTimerData,countsData; - -struct msgChar { - char acknak; - char data[80]; -}statusData,htrTimerdata,htrStatusData; - -/* binary in strings */ - -char *modeStrs[] = {"Local", "Remote", NULL}; - -/* binary out strings */ - -char *resetStrs[] = {NULL, "RESET\r"}; -char *onStrs[] = {NULL, "HV_ON\r"}; -char *offStrs[] = {NULL, "HV_OFF\r"}; - -/* device initialization string sent one time during iocInit */ -static char *pDevInit = NULL; - -/* forward declarations of some custom convert routines */ -int inMode(); -int inData(); -int getInData(); -int inOnTimers(); -int getInTimers(); -int inCounts(); -int getInCounts(); -int inStatus(); -int getInStatus(); -int getRespStr(); -int inSetpt(); -int setPvSevr(); - - - -/**************** Hvps Declarations *****************/ - -/****************************************************************************** - * - * This structure will be attached to each pv (via psub->dpvt) to store the - * appropriate gpibWork pointer, callback address to record support, - * gpib link #, listen address, talk address and command information. - * - ******************************************************************************/ - -struct hvpsDpvt { - struct dpvtGpibHead head; - - 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... */ -}; - -/****************************************************************************** - * - * Record type enumerations used by init routines for cross-checking - * - ******************************************************************************/ -#define GPIB_AO 0 -#define GPIB_AI 1 -#define GPIB_BO 2 -#define GPIB_BI 3 -#define GPIB_MBBO 4 -#define GPIB_MBBI 5 -#define GPIB_SO 6 -#define GPIB_SI 7 - -/****************************************************************************** - * - * GPIB work routines associated with record types - * - ******************************************************************************/ -#define mbboGpibWork NULL -#define mbbiGpibWork NULL -typedef void (*GPIBSUPFUN)(); /* pointer to gpib support functions*/ -static GPIBSUPFUN pgpibWork[] = { - aoGpibWork, - aiGpibWork, - boGpibWork, - biGpibWork, - mbboGpibWork, - mbbiGpibWork, - soGpibWork, - siGpibWork -}; - -/****************************************************************************** - * - * The next structure defines the GPIB command and format statements to - * extract or send data to a GPIB Instrument. 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 (hvpsDpvt.msg) - * (3) The important data is extracted from the buffer using the - * format string. - * - * GPIBREADW : (1) The cmd string is sent to the instrument - * (2) Wait for SRQ - * (3) Data is read from the inst into a buffer (hvpsDpvt.msg) - * (4) 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 hvpsDpvt->precord->val - * (2) The ascii string is sent to the instrument - * - * GPIBCMND : (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 - * - * GPIBINIT : (1) The instrument is send SDC with command string - * - * 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 .convert - * field to use it rather than the above approaches. - * - ******************************************************************************/ -struct hvpsGpibCmd { - int recType ; /* enum - GPIB_AI, GPIB_AO ... */ - int type; /* enum - GPIBREAD, GPIBWRITE, GPIBCMND */ - short pri; /* priority of gpib request--IB_Q_HIGH or IB_Q_LOW*/ - char *sta; /* status string */ - char *cmd; /* CONSTANT STRING to send to instrument */ - char *format; /* string used to generate or interpret msg*/ - short rspLen; /* room for response error message*/ - short msgLen; /* room for return data message length*/ - int (*convert)(); /* custom routine for wierd conversions */ - int P1; /* parameter used in convert*/ - int P2; /* parameter user in convert*/ - char **P3; /* pointer to array containing pointers to strings */ - struct names *namelist; /* for bx and mbbx record's name fields */ -}; - -# define FILL {10,0,IB_Q_LOW,UDF,NULL,NULL,0,0,NULL,0,0,NULL,NULL } -# define FILL10 FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL - -static struct hvpsGpibCmd hvpsGpibCmds[] = -{ - -/* ai records */ -/* 0 ->59 */ -{GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "RD_DATA\r", NULL, 80, 80, inData, 0 ,0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 0, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 1, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 2, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 3, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 4, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 5, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 6, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 7, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 8, 0, NULL, NULL}, -/*10*/ -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 9, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 10, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 11, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 12, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInData, 13, 0, NULL, NULL}, -{GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "RD_TMRS\r", "%f%f", 80, 80, inOnTimers, 0 ,0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInTimers, 0, 0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInTimers, 1, 0, NULL, NULL}, -{GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "RD_CNTS\r", "%f%f", 80, 80, inCounts, 0 ,0, NULL, NULL}, -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInCounts, 0, 0, NULL, NULL}, -/*10*/ -{GPIB_AI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInCounts, 1, 0, NULL, NULL}, -{GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "RD_SETPT HV_VOLTS\r", "%lf", 80, 80, inSetpt, 0 ,0, NULL, NULL}, -{GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "RD_SETPT MA_VOLTS\r","%lf", 80, 80, inSetpt, 0 ,0, NULL, NULL}, -{GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "RD_SETPT KLHTR_VOLTS\r", "%lf", 80, 80, inSetpt, 0 ,0, NULL, NULL}, -{GPIB_AI, GPIBREAD, IB_Q_LOW, UDF, "RD_SETPT KLMAG_AMPS\r", "%lf", 80, 80, inSetpt, 0 ,0, NULL, NULL}, -FILL,FILL,FILL,FILL,FILL, -/*10*/ -FILL10, -/*10*/ -FILL10, -/*10*/ -FILL10, - - -/* bi records */ -/*start 60 ->119*/ -{GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "RD_STATUS\r", NULL, 80, 80, inStatus, 0, 0, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 0, 0x1, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 0, 0x2, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 0, 0x4, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 0, 0x8, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 0, 0x10, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 0, 0x20, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 0, 0x40, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 0, 0x80, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 1, 0x1, NULL, NULL}, -/*10*/ -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 1, 0x2, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 1, 0x4, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 1, 0x8, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 1, 0x10, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 1, 0x20, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 1, 0x40, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 1, 0x80, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 2, 0x1, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 2, 0x2, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 2, 0x4, NULL, NULL}, -/*10*/ -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 2, 0x8, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 2, 0x10, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 2, 0x20, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 2, 0x40, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 2, 0x80, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 3, 0x1, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 3, 0x2, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 3, 0x4, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 3, 0x8, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 3, 0x10, NULL, NULL}, -/*10*/ -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 3, 0x20, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 3, 0x40, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 3, 0x80, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 4, 0x1, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 4, 0x2, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 4, 0x4, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 4, 0x8, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 4, 0x10, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 4, 0x20, NULL, NULL}, -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 4, 0x40, NULL, NULL}, -/*10*/ -{GPIB_BI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 0, 0, getInStatus, 4, 0x80, NULL, NULL}, -{GPIB_BI, GPIBREAD, IB_Q_LOW, UDF, "RD_MODE\r", NULL, 40,40, NULL, 0 ,0, modeStrs, NULL}, -FILL,FILL,FILL, -FILL,FILL,FILL,FILL,FILL, -/*10*/ -FILL10, - - -/* ao records */ -/* start 120->159*/ -{GPIB_AO, GPIBWRITE, IB_Q_LOW, UDF, NULL, "LD_SETPT HV_VOLTS %10.3E\r", 40, 40, NULL, 0, 0, NULL, NULL}, -{GPIB_AO, GPIBWRITE, IB_Q_LOW, UDF, NULL, "LD_SETPT MA_VOLTS %10.3E\r", 40, 40, NULL, 0, 0, NULL, NULL}, -{GPIB_AO, GPIBWRITE, IB_Q_LOW, UDF, NULL, "LD_SETPT KLHTR_VOLTS %10.3E\r", 40, 40, NULL, 0, 0, NULL, NULL}, -{GPIB_AO, GPIBWRITE, IB_Q_LOW, UDF, NULL, "LD_SETPT KLMAG_AMPS %10.3E\r", 40, 40, NULL, 0, 0, NULL, NULL}, -FILL, -FILL,FILL,FILL,FILL,FILL, -/*10*/ -FILL10, -/*10*/ -FILL10, -/*10*/ -FILL10, - - -/* bo records */ -/*start 160->179*/ -{GPIB_BO, GPIBWRITE, IB_Q_LOW, UDF, NULL, NULL, 80, 80, NULL, 0, 0, resetStrs, NULL}, -{GPIB_BO, GPIBWRITE, IB_Q_LOW, UDF, NULL, NULL, 80, 80, NULL, 0, 0, onStrs, NULL}, -{GPIB_BO, GPIBWRITE, IB_Q_LOW, UDF, NULL, NULL, 80, 80, NULL, 0, 0, offStrs, NULL}, -FILL,FILL, -FILL,FILL,FILL,FILL,FILL, -/*10*/ -FILL10, - - -/* stringin records */ -/*start 180->199*/ -{GPIB_SI, GPIBREAD, IB_Q_LOW, UDF, "RD_HTR_STATUS\r", NULL, 40,40, NULL, 0 ,0, NULL, NULL}, -{GPIB_SI, GPIBREAD, IB_Q_LOW, UDF, "RD_WARMUP\r", NULL, 40,40, NULL, 0 ,0, NULL, NULL}, -{GPIB_SI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 40,40, getRespStr, 101 ,0, NULL, NULL}, -{GPIB_SI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 40,40, getRespStr, 102 ,0, NULL, NULL}, -{GPIB_SI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 40,40, getRespStr, 103 ,0, NULL, NULL}, -{GPIB_SI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 40,40, getRespStr, 160 ,0, NULL, NULL}, -{GPIB_SI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 40,40, getRespStr, 161 ,0, NULL, NULL}, -{GPIB_SI, GPIBSOFT, IB_Q_LOW, UDF, NULL, NULL, 40,40, getRespStr, 162 ,0, NULL, NULL}, -FILL, FILL, -/*10*/ -FILL10, - - -/* stringout records */ -/*start 200->209*/ -{GPIB_SO, GPIBWRITE, IB_Q_LOW, UDF, NULL, NULL, 40,40, NULL, 0 ,0, NULL, NULL} -}; - -#define NUMHVPSPARAMS sizeof(hvpsGpibCmds)/sizeof(struct hvpsGpibCmd) - -/****************************************************************************** - * - * Initialization for Hvps device support - * - ******************************************************************************/ - -static long init_dev_sup() -{ - static char firstInitCall = 0; - - /* check to see if we have been here before */ - if (firstInitCall) - { - return(OK); /* if already initialized, return */ - } - firstInitCall = 1; - - /* continue initalizations */ - logMsg("Hvps Device Support Initializing ...\n"); - - return(OK); -} - -/****************************************************************************** - * - * Initialization routines for each record specifying a Hvps Device Type - * - ******************************************************************************/ - -/****************************************************************************** - * - * ai record init - * - ******************************************************************************/ -static long -init_rec_ai(pai, process) -struct aiRecord *pai; -void (*process)(); -{ - /* do common initialization */ - return(init_rec_xx((caddr_t) pai, &pai->inp, GPIB_AI)); -} - -/****************************************************************************** - * - * ao record init - * - ******************************************************************************/ -static long -init_rec_ao(pao, process) -struct aoRecord *pao; -void (*process)(); -{ - /* do common initialization */ - return(init_rec_xx((caddr_t) pao, &pao->out, GPIB_AO)); -} - -/****************************************************************************** - * - * stringin record init - * - ******************************************************************************/ -static long -init_rec_stringin(pstringin, process) -struct stringinRecord *pstringin; -void (*process)(); -{ - /* do common initialization */ - return( init_rec_xx((caddr_t) pstringin, &pstringin->inp, GPIB_SI)); -} - -/****************************************************************************** - * - * stringout record init - * - ******************************************************************************/ -static long -init_rec_stringout(pstringout, process) -struct stringoutRecord *pstringout; -void (*process)(); -{ - /* do common initialization */ - return(init_rec_xx((caddr_t) pstringout, &pstringout->out, GPIB_SO)); -} - -/****************************************************************************** - * - * bi record init - * - ******************************************************************************/ -static long -init_rec_bi(pbi, process) -struct biRecord *pbi; -void (*process)(); -{ - /* do common initialization */ - return(init_rec_xx((caddr_t) pbi, &pbi->inp, GPIB_BI)); - -/* BUG - what about the button labels?? */ -} - -/* bo record init */ -static long init_rec_bo(pbo, process) -struct boRecord *pbo; -void (*process)(); -{ - /* do common initialization */ - return(init_rec_xx((caddr_t) pbo, &pbo->out, GPIB_BO)); - -/* BUG - what about the button labels?? */ -} - -/****************************************************************************** - * - * This init routine is common to all record types - * - ******************************************************************************/ - -static long -init_rec_xx(prec, plink, recType) -struct dbCommon *prec; -struct link *plink; -int recType; -{ - static short firstTime = TRUE; - - struct hvpsDpvt *pdpvt; - struct dbCommon *pdbCommon = (struct dbCommon *)prec; - char message[100]; - struct hvpsGpibCmd *pCmd; - char subType; - - - if (HvpsDebug) - logMsg("hvps init_rec_xx(): entered\n"); - - /* allocate space for the private structure */ - pdpvt = (struct hvpsDpvt *) malloc(sizeof(struct hvpsDpvt)); - prec->dpvt = (void *) pdpvt; - - pdpvt->precord = prec; - pdpvt->head.workStart = pgpibWork[recType]; - pdpvt->parm = -1; /* In case the sscanf fails */ - pdpvt->linkType = plink->type; - - switch (plink->type) { - case GPIB_IO: /* Is a straight Network Instruments link */ - -/* BUG - this should be a driver supplied function to fill in the header */ - - 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 */ - break; - case BBGPIB_IO: /* Is a bitbus -> gpib link */ - -/* BUG - this should be a driver supplied function to fill in the header */ - - pdpvt->head.device = plink->value.bbgpibio.gpibaddr; /* gpib dev address */ - sscanf(plink->value.bbgpibio.parm, "%hd", &(pdpvt->parm)); - - pdpvt->head.bitBusDpvt = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead)); - pdpvt->head.bitBusDpvt->txMsg = (struct bitBusMsg *) malloc(sizeof(struct bitBusMsg)); - pdpvt->head.bitBusDpvt->rxMsg = (struct bitBusMsg *) malloc(sizeof(struct bitBusMsg)); - 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); - break; - default: - strcpy(message, pdbCommon->name); - strcat(message,": init_record : GPIB link type is invalid"); - errMessage(S_db_badField, message); - return(S_db_badField); - break; - } - - /* check for valid GPIB addr */ - 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); - return(S_db_badField); - } - /* check for valid param entry */ - if ((pdpvt->parm < 0) || (pdpvt->parm > NUMHVPSPARAMS)) - { - strcpy(message, pdbCommon->name); - strcat(message,": init_record : Parameter # out of range"); - errMessage(S_db_badField,message); - return(S_db_badField); - } - - /* check record type*/ - if(hvpsGpibCmds[pdpvt->parm].recType != recType ) - { - strcpy(message, pdbCommon->name); - strcat(message,": init_record : record type invalid for parameter"); - errMessage(S_db_badField,message); - return(S_db_badField); - } - - pCmd = &hvpsGpibCmds[pdpvt->parm]; - if(pCmd->msgLen > 0) - pdpvt->msg = (char *)(calloc(pCmd->msgLen,1)); - if(pCmd->rspLen > 0) - pdpvt->rsp = (char *)(calloc(pCmd->rspLen,1)); - -/* BUG this init logic is wrong for multi-devices... */ -/* BUG - it should be on a per-device address basis */ -/* - fix it when dynamically allocating the per-device structures. */ - -/* BUG!!! this HAS to be done via qGpibReq!!!! */ - if( firstTime && pDevInit != NULL ) - { - if( (*(drvGpib.writeIb))(pdpvt->head.link, pdpvt->head.device, pDevInit, strlen(pDevInit)) == ERROR) - { - logMsg("Hvps device initialization-GPIB setup error\n"); - return(ERROR); - } - } - - /* fill in the required stuff for the callback task */ - pdpvt->process = processCallback; - pdpvt->processPri = priorityLow; - - return(0); -} - -/****************************************************************************** - * - * These are the device support routne entry points called by record support. - * - ******************************************************************************/ -static long -read_ai(pai) -struct aiRecord *pai; -{ - struct hvpsDpvt *pdpvt = (struct hvpsDpvt *)(pai->dpvt); - struct hvpsGpibCmd *pCmd; - - pCmd = &hvpsGpibCmds[pdpvt->parm]; - if (pai->pact) - { - if(HvpsDebug) - logMsg("read_ai with PACT = 1\n"); - return(2); /* work is all done, return '2' to indicate val */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(2); - } - else - { /* put pointer to dvpt field on ring buffer */ - if(HvpsDebug) - logMsg("read_ai with PACT = 0\n"); - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pai,MAJOR_ALARM,INVALID_ALARM); - return(0); - } - return(1); - } -} - - -static long write_ao(pao) -struct aoRecord *pao; -{ - struct hvpsDpvt *pdpvt = (struct hvpsDpvt *)(pao->dpvt); - struct hvpsGpibCmd *pCmd; - - pCmd = &hvpsGpibCmds[pdpvt->parm]; - - if(HvpsDebug) - logMsg("Hvps-write_ao entered type: %d format %s\n",pCmd->type,pCmd->format); - - if (pao->pact) - return(2); /* work is all done, finish processing */ - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pao,WRITE_ALARM,INVALID_ALARM); - return(0); - } - return(1); - } -} - -static long read_stringin(pstringin) -struct stringinRecord *pstringin; -{ - struct hvpsDpvt *pdpvt = (struct hvpsDpvt *)(pstringin->dpvt); - struct hvpsGpibCmd *pCmd; - - pCmd = &hvpsGpibCmds[pdpvt->parm]; - if (pstringin->pact) - { - if(HvpsDebug) - logMsg("read_stringin with PACT = 1\n"); - return(2); /* work is all done, return '2' to indicate val */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if(HvpsDebug) - logMsg("read_stringin with PACT = 0\n"); - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pstringin,MAJOR_ALARM,INVALID_ALARM); - return(0); - } - return(1); - } -} - - -static long write_stringout(pstringout) -struct stringoutRecord *pstringout; -{ - struct hvpsDpvt *pdpvt = (struct hvpsDpvt *)(pstringout->dpvt); - struct hvpsGpibCmd *pCmd; - - pCmd = &hvpsGpibCmds[pdpvt->parm]; - if(HvpsDebug) - logMsg("stringout entered string %s\n",pstringout->val); - - if (pstringout->pact) - { - return(0); /* work is all done, finish processing */ - } - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pstringout,WRITE_ALARM,INVALID_ALARM); - return(0); - } - return(1); - } -} - -static long read_bi(pbi) -struct biRecord *pbi; -{ - struct hvpsDpvt *pdpvt = (struct hvpsDpvt *)(pbi->dpvt); - struct hvpsGpibCmd *pCmd; - - pCmd = &hvpsGpibCmds[pdpvt->parm]; - - if (pbi->pact) - return(2); /* work is all done, finish processing */ - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(2); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pbi,READ_ALARM,INVALID_ALARM); - return(0); - } - return(1); - } -} - - -static long write_bo(pbo) -struct boRecord *pbo; -{ - struct hvpsDpvt *pdpvt = (struct hvpsDpvt *)(pbo->dpvt); - struct hvpsGpibCmd *pCmd; - - pCmd = &hvpsGpibCmds[pdpvt->parm]; - - if (pbo->pact) - return(2); /* work is all done, finish processing */ - else if (pCmd->type == GPIBSOFT) - { - (*pCmd->convert)(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - return(0); - } - else - { /* put pointer to dvpt field on ring buffer */ - if((*(drvGpib.qGpibReq))(pdpvt->linkType, pdpvt->head.link, pdpvt, pCmd->pri) == ERROR) - { - setPvSevr(pbo,WRITE_ALARM,INVALID_ALARM); - return(0); - } - return(1); - } -} - -/****************************************************************************** - * - * Routines to do the real GPIB work. - * - * These functions are invoked by the GPIB link task. As such, they should not - * do any expensive operations within the context of that task. If expensive - * non-I/O related things are to be done, they should be done by scheduling a - * callbackRequest for an other function to handle it. - * - ******************************************************************************/ - -static void -aiGpibWork(pdpvt) -struct hvpsDpvt *pdpvt; -{ - double value; - struct aiRecord *pai= ((struct aiRecord *)(pdpvt->precord)); - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read response into msg[] */ - - if(HvpsDebug) - logMsg("aiGpibWork: starting ...\n"); - - if (xxGpibWork(pdpvt) == ERROR) - { - if(HvpsDebug) - logMsg("aiGpibWork: error in xxGpibWork ...\n"); - setPvSevr(pai,READ_ALARM,INVALID_ALARM); - } - else /* interpret response that came back */ - { /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - if(HvpsDebug) - logMsg("aiGpibWork: calling convert ...\n"); - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - if(HvpsDebug) - logMsg("aiGpibWork: returned from convert ...\n"); - } - 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; - } - else /* sscanf did not find or assign the parameter */ - { - setPvSevr(pai,READ_ALARM,INVALID_ALARM); - } - } - } - if(HvpsDebug) - logMsg("aiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -static void siGpibWork(pdpvt) -struct hvpsDpvt *pdpvt; -{ - struct stringinRecord *pstringin= ((struct stringinRecord *)(pdpvt->precord)); - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[pdpvt->parm]; - - /* go send predefined cmd msg and read response into msg[] */ - - if(HvpsDebug) - logMsg("stringinGpibWork: starting ...\n"); - - if (xxGpibWork(pdpvt) == ERROR) - { - if(HvpsDebug) - logMsg("stringinGpibWork: error in xxGpibWork ...\n"); - setPvSevr(pstringin,READ_ALARM,INVALID_ALARM); - } - else /* interpret response that came back */ - { /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - if(HvpsDebug) - logMsg("stringinGpibWork: calling convert ...\n"); - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - if(HvpsDebug) - logMsg("stringinGpibWork: returned from convert ...\n"); - } - else /* copy up to 39 characters into .val + null terminator */ - { - strncpy(pstringin->val,pdpvt->msg,39); - pstringin->val[40] = '\0'; - pstringin->udf = FALSE; - } - } - if(HvpsDebug) - logMsg("siGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - - - -static void aoGpibWork(pdpvt) -struct hvpsDpvt *pdpvt; -{ - int cnvrtStat = OK; - struct aoRecord *pao= ((struct aoRecord *)(pdpvt->precord)); - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[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 */ - { - sprintf(pdpvt->msg, pCmd->format, pao->val); - } - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt) == ERROR)) - { - setPvSevr(pao,WRITE_ALARM,INVALID_ALARM); - } - else if(pdpvt->rsp[0] == NAK) - { - pCmd->sta = &pdpvt->rsp[1]; - setPvSevr(pao,WRITE_ALARM,INVALID_ALARM); - } - else - { - pCmd->sta = pOK; - } - if(HvpsDebug) - logMsg("aoGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - - static void soGpibWork(pdpvt) -struct hvpsDpvt *pdpvt; -{ - int cnvrtStat = OK; - struct stringoutRecord *pstringout= ((struct stringoutRecord *)(pdpvt->precord)); - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[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 */ - { - pstringout->udf = FALSE; - strncpy(pdpvt->msg,pstringout->val,40 ); - logMsg("parameter %d message %s type %d \n",pdpvt->parm,pdpvt->msg,pCmd->type); - } - - /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt) == ERROR)) - { - setPvSevr(pstringout,WRITE_ALARM,INVALID_ALARM); - } - if(HvpsDebug) - logMsg("aiGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -/* BUG -- use the convertion routine for the mode string stuff */ -static void biGpibWork(pdpvt) -struct hvpsDpvt *pdpvt; -{ - unsigned long value; - struct biRecord *pbi= ((struct biRecord *)(pdpvt->precord)); - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[pdpvt->parm]; - short strIndex; - struct msgChar *pMsg = ( struct msgChar *)pdpvt->msg; - - /* go send predefined cmd msg and read response into msg[] */ - - if (xxGpibWork(pdpvt) == ERROR) - { - setPvSevr(pbi,READ_ALARM,INVALID_ALARM); - } - else /* interpret response that came back */ - { /* call convert routine, if defined */ - if (pCmd->convert != NULL) - { - if(HvpsDebug) - logMsg("biGpibWork calling convert routine\n"); - - (*(pCmd->convert))(pdpvt,pCmd->P1,pCmd->P2, pCmd->P3); - - if(HvpsDebug) - logMsg("biGpibWork return from convert routine\n"); - } - else - if (pCmd->P3 != NULL) /* compare with expected strings */ - { - strIndex = 0; - while(pCmd->P3[strIndex] != NULL) - { - if( strncmp(pCmd->P3[strIndex],pMsg->data,strlen(pCmd->P3[strIndex])) == 0 ) break ; - strIndex++; - if(HvpsDebug) - logMsg("biGpibWork:string index:%d\n",strIndex); - } - if(pCmd->P3[strIndex] != NULL & strIndex < 2) - { - pbi->udf = FALSE; - pbi->val = strIndex; - if(HvpsDebug) - logMsg("biGpibWork: matched string index:%d\n",strIndex); - } - else - { - pbi->udf = TRUE; - setPvSevr(pbi,READ_ALARM,INVALID_ALARM); - } - } - else /* interpret msg with predefined format and write into .rval */ - { - /* 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 */ - { - setPvSevr(pbi,READ_ALARM,INVALID_ALARM); - } - }/*else*/ - }/*else*/ - if(HvpsDebug) - logMsg("biGpibWork calling final callback routine\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -static void boGpibWork(pdpvt) -struct hvpsDpvt *pdpvt; -{ - int cnvrtStat = OK; - int strStat = OK; - struct boRecord *pbo= ((struct boRecord *)(pdpvt->precord)); - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[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 - if(pbo->val == 0 || pbo->val == 1) - { /* generate msg using predefined format and current val */ - pbo->udf = FALSE; - if(pCmd->P3[pbo->val] != NULL) - { - strncpy(pdpvt->msg, pCmd->P3[pbo->val],(pCmd->msgLen)-1); - pdpvt->msg[pCmd->msgLen] = NULL; - } - else - strStat = ERROR; - } - else - cnvrtStat = ERROR; - - if(strStat == OK) - { /* go access board with this message, unless convert was unsuccessful */ - if ((cnvrtStat == ERROR) || (xxGpibWork(pdpvt) == ERROR)) - { - setPvSevr(pbo,WRITE_ALARM,MAJOR_ALARM); - } - else if(pdpvt->rsp[0] == NAK) - { - pCmd->sta = &pdpvt->rsp[1]; - setPvSevr(pbo,WRITE_ALARM,MAJOR_ALARM); - } - else - { - pCmd->sta = pOK; - } - }/*strStat*/ - if(HvpsDebug) - logMsg("boGpibWork: calling process ...\n"); - - pdpvt->head.header.callback.finishProc = pdpvt->process; - pdpvt->head.header.callback.priority = pdpvt->processPri; - callbackRequest(pdpvt); /* jrw */ -} - -/****************************************************************************** - * - * General GPIB work function. - * This is the only place (after initialization) that any GPIB message commands - * are issued. - * - ******************************************************************************/ -static int xxGpibWork(pdpvt) -struct hvpsDpvt *pdpvt; -{ - int status; /* for GPIBREAD, contains ERROR or # of bytes read */ - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[pdpvt->parm]; - short ibnode = pdpvt->head.device; - short bbnode; - - /* If is a BBGPIB_IO link, the bug address is needed */ - if (pdpvt->linkType == BBGPIB_IO) - bbnode = pdpvt->head.bitBusDpvt->txMsg->node; - - if (HvpsDebug) - logMsg("Hvps - xxGpibWork(%08.8X): device = %d, link = %d\n", pdpvt, pdpvt->head.device, pdpvt->head.link); - -/* - * check to see if this node has timed out within last 10 sec - */ - -/* BUG -- loose the hard-coded ticks and fix refs to the tmoTable */ - if(hvpsTmoTable[pdpvt->head.link][1] != 0) - { - if(tickGet() < (hvpsTmoTable[pdpvt->head.link][0] +600) ) - { - if (HvpsDebug) - logMsg("Hvps-xxGpibWork(): timeout flush\n"); - return(ERROR); - } - } - - switch (pCmd->type) { - case GPIBWRITE: /* write the message to the GPIB listen adrs */ - if(HvpsDebug) - logMsg("xxGpibWork : processing GPIBWRITE\n"); - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, bbnode, ibnode, pdpvt->msg, strlen(pdpvt->msg)); - -/* - * use for devices which respond to write commands - */ -#ifdef RESPONDS_2_WRITES - if (status == ERROR) - { - break; - } - if(hvpsGpibDelay) - taskDelay(hvpsGpibDelay); - status = (*(drvGpib.readIb))(pdpvt->linkType, pdpvt->head.link, bbnode, ibnode, pdpvt->rsp, pCmd->rspLen); -#endif - break; - - case GPIBREAD: /* write the command string */ - if(HvpsDebug) - logMsg("xxGpibWork : processing GPIBREAD\n"); - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, bbnode, ibnode, pCmd->cmd, strlen(pCmd->cmd)); - if (status == ERROR) - break; - /* read the instrument */ - if(hvpsGpibDelay) - taskDelay(hvpsGpibDelay); - status = (*(drvGpib.readIb))(pdpvt->linkType, pdpvt->head.link, bbnode, ibnode, pdpvt->msg, pCmd->msgLen); - - if (status == ERROR) - break; - else - if (status >( (pCmd->msgLen) - 1) ) /* check length of resp */ - { - logMsg("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; - -/* BUG - this srq stuff is not right at all */ -#ifdef _SRQSUPPORT_ - case GPIBREADW: /* write the command string */ - if(HvpsDebug) - logMsg("xxGpibWork : processing GPIBREADW\n"); - - /*enable SRQ to set semaphore*/ - srqTable.active = TRUE; - srqTable.status = 0; - - status = (*(drvGpib.writeIb))( pdpvt->link,pdpvt->lad, pCmd->cmd, strlen(pCmd->cmd)); - if (status == ERROR) - break; - - /*wait for SRQ on measurement completion*/ -/* BUG -this should be via callbackRequest span */ - semTake(HvpsSrqSEM); - logMsg("srq startus %x\n",srqTable.status); - - /* read the instrument */ - status = (*(drvGpib.readIb))(pdpvt->link,pdpvt->tad, pdpvt->msg, pCmd->msgLen); - if (status == ERROR) - break; - else - if (status >( (pCmd->msgLen) - 1) ) /* check length of resp */ - { - logMsg("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; -#endif /* _SRQSUPPORT_ */ - - case GPIBCMD: /* write the cmd to the GPIB listen adrs */ - status = (*(drvGpib.writeIb))(pdpvt->linkType, pdpvt->head.link, bbnode, ibnode, pCmd->cmd, strlen(pCmd->cmd)); - break; - -/* BUG - this is not supported... yet */ -#ifdef I_CANT_DO_THIS - case GPIBINIT: /* write the cmd & SDC to GPIB listen adrs */ - status = initib(pdpvt->head.device, pCmd->cmd, strlen(pCmd->cmd)); - break; -#endif - - } - if(HvpsDebug) - logMsg("xxGpibWork : done, status = %d\n",status); - /* if error occurrs then mark it with time */ - if(status == ERROR) - { - hvpsTmoTable[pdpvt->head.link][0] = tickGet(); - hvpsTmoTable[pdpvt->head.link][1]++; - } - 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 xxxWork 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 this purpose. (jrw) - * - ******************************************************************************/ -void processCallback(pDpvt) -struct hvpsDpvt *pDpvt; -{ - if(HvpsDebug) - logMsg("processCallback: locking %08.8X\n", pDpvt->precord); - - dbScanLock(pDpvt->precord); - - if(HvpsDebug) - logMsg("processCallback: calling process\n"); - - (*(struct rset *)(pDpvt->precord->rset)).process(pDpvt->precord); - - if(HvpsDebug) - logMsg("processCallback: unlocking %08.8X\n", pDpvt->precord); - - dbScanUnlock(pDpvt->precord); -} - -/****************************************************************************** - * - * Convert routines for the Hvps - * - ******************************************************************************/ - -/* BUG - deal with hard-coded lengths, they are bad as well as wrong */ -static int inMode(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - strncpy(((struct stringinRecord *)(pdpvt->precord))->val, pdpvt->msg,39); - ((struct stringinRecord *)(pdpvt->precord))->val[39] = '\0'; -} - - -static int getRespStr(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - - struct stringinRecord *pstringin= (struct stringinRecord *)(pdpvt->precord); - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[P1]; - - pstringin->udf = FALSE; - strncpy(pstringin->val,pCmd->sta,39); - pstringin->val[40] = '\0'; -} - - -static int inData(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - short i; - char *pFirstDataByte; - - struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); - struct msgMetered *pMsg = ( struct msgMetered *)pdpvt->msg; - pai->udf = FALSE; - - if(pMsg->acknak == ACK) - { - pFirstDataByte = (pdpvt->msg)+1; - memcpy(meteredData.data,pFirstDataByte,56); -/* for(i=0;i<=13;i++) meteredData.data[i] = pMsg->data[i];*/ - meteredData.acknak = ACK; - } - else if(pMsg->acknak == NAK) - { - for(i=0;i<=13;i++) meteredData.data[i] = UNDEFINED; - meteredData.acknak = NAK; - setPvSevr(pai,MAJOR_ALARM,INVALID_ALARM); - } -} - - -static int getInData(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); - struct msgMetered *pMsg = &meteredData; - - pai->udf = FALSE; - pai->val = pMsg->data[P1]; - if(pMsg->acknak == NAK) setPvSevr(pai,MAJOR_ALARM,INVALID_ALARM); -} - -static int inStatus(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - short i; - - struct biRecord *pbi= (struct biRecord *)(pdpvt->precord); - struct msgChar *pMsg = (struct msgChar *)pdpvt->msg; - - pbi->udf = FALSE; - if(pMsg->acknak == ACK) - { - if(HvpsDebug) logMsg("inStatus entered with ACK\n"); - for(i=0;i<=4;i++) statusData.data[i] = pMsg->data[i]; - statusData.acknak = ACK; - } - else if(pMsg->acknak == NAK) - { - if(HvpsDebug) logMsg("inStatus entered with NAK\n"); - statusData.acknak = NAK; - setPvSevr(pbi,MAJOR_ALARM,INVALID_ALARM); - } -} - -static int getInStatus(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - struct biRecord *pbi= (struct biRecord *)(pdpvt->precord); - struct msgChar *pMsg = &statusData; - - pbi->udf = FALSE; - pbi->val = ( (pMsg->data[P1]) & P2 ) ? 1:0; - if(pMsg->acknak == NAK) setPvSevr(pbi,MAJOR_ALARM,INVALID_ALARM); -} - -static int inOnTimers(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - short i; - struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); - struct msgChar *pMsg = (struct msgChar *)pdpvt->msg; - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[pdpvt->parm]; - - - pai->udf = FALSE; - if(pMsg->acknak == ACK) - { - sscanf(pMsg->data,pCmd->format,&onTimerData.data[0], - &onTimerData.data[1] ); - onTimerData.acknak = ACK; - } - else if(pMsg->acknak == NAK) - { - for(i=0;i<=1;i++) onTimerData.data[i] = UNDEFINED; - - strncpy(pdpvt->rsp, pdpvt->msg,(pCmd->rspLen)-1); - pdpvt->rsp[pCmd->rspLen] = '\0'; - - onTimerData.acknak = NAK; - setPvSevr(pai,MAJOR_ALARM,INVALID_ALARM); - } -} - -static int getInTimers(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); - struct msgMetered *pMsg = &onTimerData; - - pai->udf = FALSE; - pai->val = pMsg->data[P1]; - if(pMsg->acknak == NAK) setPvSevr(pai,MAJOR_ALARM,INVALID_ALARM); -} - - -static int inCounts(pdpvt,P1,P2,P3) -struct hvpsDpvt *pdpvt; -int P1; -int P2; -char **P3; -{ - short i; - struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); - struct msgChar *pMsg = (struct msgChar *)pdpvt->msg; - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[pdpvt->parm]; - - - pai->udf = FALSE; - if(pMsg->acknak == ACK) - { - sscanf(pMsg->data,pCmd->format,&countsData.data[0], - &countsData.data[1] ); - countsData.acknak = ACK; - } - else if(pMsg->acknak == NAK) - { - for(i=0;i<=1;i++) countsData.data[i] = UNDEFINED; - - strncpy(pdpvt->rsp, pdpvt->msg,(pCmd->rspLen)-1); - pdpvt->rsp[pCmd->rspLen] = '\0'; - - countsData.acknak = NAK; - setPvSevr(pai,MAJOR_ALARM,INVALID_ALARM); - } -} - -static int getInCounts(pdpvt,P1,P2,P3) - struct hvpsDpvt *pdpvt; - int P1; - int P2; - char **P3; -{ - struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); - struct msgMetered *pMsg = &countsData; - - pai->udf = FALSE; - pai->val = pMsg->data[P1]; - if(pMsg->acknak == NAK) setPvSevr(pai,MAJOR_ALARM,INVALID_ALARM); -} - -static int inSetpt(pdpvt,P1,P2,P3) - struct hvpsDpvt *pdpvt; - int P1; - int P2; - char **P3; -{ - short i; - float temp; - struct aiRecord *pai= (struct aiRecord *)(pdpvt->precord); - struct msgChar *pMsg = (struct msgChar *)pdpvt->msg; - struct hvpsGpibCmd *pCmd = &hvpsGpibCmds[pdpvt->parm]; - - - pai->udf = FALSE; - if(pMsg->acknak == ACK) - { - sscanf(pMsg->data,pCmd->format,&(pai->val)); - pCmd->sta = pOK; - } - else if(pMsg->acknak == NAK) - { - - strncpy(pdpvt->rsp, pdpvt->msg,(pCmd->rspLen)-1); - pdpvt->rsp[pCmd->rspLen] = '\0'; - - pCmd->sta = pdpvt->rsp; - setPvSevr(pai,MAJOR_ALARM,INVALID_ALARM); - } -} - - -static int setPvSevr(pPv, status,severity) -struct dbCommon *pPv; -short severity; -short status; -{ - if (severity > pPv->nsev) - { - pPv->nsta = status; - pPv->nsev = severity; - } -} diff --git a/src/vxWorks/devOpt/devXxK196Gpib.c b/src/vxWorks/devOpt/devXxK196Gpib.c deleted file mode 100644 index eeb10b11a..000000000 --- a/src/vxWorks/devOpt/devXxK196Gpib.c +++ /dev/null @@ -1,299 +0,0 @@ -/* devXxK196Gpib.c */ -/* share/src/devOpt $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: - * ----------------- - */ - -#define DSET_AI devAiK196Gpib -#define DSET_AO devAoK196Gpib -#define DSET_LI devLiK196Gpib -#define DSET_LO devLoK196Gpib -#define DSET_BI devBiK196Gpib -#define DSET_BO devBoK196Gpib -#define DSET_MBBO devMbboK196Gpib -#define DSET_MBBI devMbbiK196Gpib -#define DSET_SI devSiK196Gpib -#define DSET_SO devSoK196Gpib - -#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 - -static long init_dev_sup(), report(); -static struct devGpibParmBlock devSupParms; - -/****************************************************************************** - * - * Define all the dset's. - * - * Note that the dset names are provided via the #define lines at the top of - * this file. - * - * Other than for the debugging flag(s), these DSETs are the only items that - * will appear in the global name space within the IOC. - * - * The last 3 items in the DSET structure are used to point to the parm - * structure, the work functions used for each record type, and the srq - * handler for each record type. - * - ******************************************************************************/ -gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, - devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; - -gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, - devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; - -gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, - devGpibLib_readBi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; - -gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, - devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; - -gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, - devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; - -gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, - devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; - -gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, - devGpibLib_readSi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; - -gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, - devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; - -gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, - devGpibLib_readLi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; - -gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, - devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; - -int K196Debug = 0; /* debugging flags */ - -/* - * Use the TIME_WINDOW defn to indicate how long commands should be ignored - * for a given device after it times out. The ignored commands will be - * returned as errors to device support. - * - * Use the DMA_TIME to define how long you wish to wait for an I/O operation - * to complete once started. - */ -#define TIME_WINDOW 600 /* 10 seconds on a getTick call */ -#define DMA_TIME 30 /* 1/2 second on a watchdog time */ - -/* - * Strings used by the init routines to fill in the znam, onam, ... - * fields in BI, BO, MBBI, and MBBO record types. - */ - -static char *offOnList[] = { "Off", "On" }; -static struct devGpibNames offOn = { 2, offOnList, NULL, 1 }; - -static char *disableEnableList[] = { "Disable", "Enable" }; -static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 }; - -static char *resetList[] = { "Reset", "Reset" }; -static struct devGpibNames reset = { 2, resetList, NULL, 1 }; - -static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" }; -static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1}; - -static char *invertNormList[] = { "INVERT", "NORM" }; -static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 }; - -static char *fallingRisingList[] = { "FALLING", "RISING" }; -static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 }; - -static char *singleShotList[] = { "SINGLE", "SHOT" }; -static struct devGpibNames singleShot = { 2, singleShotList, NULL, 1 }; - -static char *clearList[] = { "CLEAR", "CLEAR" }; -static struct devGpibNames clear = { 2, clearList, NULL, 1 }; - -static char *tABCDList[] = { "T", "A", "B", "C", "D" }; -static unsigned long tABCDVal[] = { 1, 2, 3, 5, 6 }; -static struct devGpibNames tABCD = { 5, tABCDList, tABCDVal, 3 }; - -static char *ttlNimEclVarList[] = { "TTL", "NIM", "ECL", "VAR" }; -static unsigned long ttlNimEclVarVal[] = { 0, 1, 2, 3 }; -static struct devGpibNames ttlNimEclVar = { 4, ttlNimEclVarList, - ttlNimEclVarVal, 2 }; - -static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL", - "SINGLE SHOT", "BURST MODE", "STOP" }; -static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 }; -static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList, - intExtSsBmStopVal, 2 }; -static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList, - intExtSsBmStopVal, 3 }; - - -/****************************************************************************** - * - * String arrays for EFAST operations. Note that the last entry must be - * NULL. - * - * On input operations, only as many bytes as are found in the string array - * elements are compared. If there are more bytes than that in the input - * message, they are ignored. The first matching string found (starting - * from the 0'th element) will be used as a match. - * - * NOTE: For the input operations, the strings are compared literally! This - * can cause problems if the instrument is returning things like \r and \n - * characters. You must take care when defining input strings so you include - * them as well. - * - ******************************************************************************/ - -static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL}; - -/****************************************************************************** - * - * Array of structures that define all GPIB messages - * supported for this type of instrument. - * - ******************************************************************************/ - -static struct gpibCmd gpibCmds[] = -{ - /* Param 0, (model) */ - FILL, - - /* Param 1 initialization string */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "L0XR3X", NULL, 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 2 read current voltage value */ - {&DSET_AI, GPIBREAD, IB_Q_HIGH, "U7", "%*4c%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1} - -}; - - -/* The following is the number of elements in the command array above. */ -#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) - -/****************************************************************************** - * - * Structure containing the user's functions and operating parameters needed - * by the gpib library functions. - * - * The magic SRQ parm is the parm number that, if specified on a passive - * record, will cause the record to be processed automatically when an - * unsolicited SRQ interrupt is detected from the device. - * - * If the parm is specified on a non-passive record, it will NOT be processed - * when an unsolicited SRQ is detected. - * - ******************************************************************************/ -static struct devGpibParmBlock devSupParms = { - &K196Debug, /* debugging flag pointer */ - -1, /* set to -1 if the device does NOT respond to writes */ - TIME_WINDOW, /* # of clock ticks to skip after a device times out */ - NULL, /* hwpvt list head */ - gpibCmds, /* GPIB command array */ - NUMPARAMS, /* number of supported parameters */ - -1, /* magic SRQ param number (-1 if none) */ - "devXxK196Gpib", /* device support module type name */ - DMA_TIME, /* # of clock ticks to wait for DMA completions */ - - NULL, /* pointer to SRQ handler function (NULL if none) */ - NULL /* pointer to secondary conversion routine */ -}; - -/****************************************************************************** - * - * 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. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -static long -init_dev_sup(int parm) -{ - return(devGpibLib_initDevSup(parm, &DSET_AI)); -} - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -static long -report(void) -{ - return(devGpibLib_report(&DSET_AI)); -} diff --git a/src/vxWorks/devOpt/devXxK263Gpib.c b/src/vxWorks/devOpt/devXxK263Gpib.c deleted file mode 100644 index e1e5a284c..000000000 --- a/src/vxWorks/devOpt/devXxK263Gpib.c +++ /dev/null @@ -1,235 +0,0 @@ -/* devXxK263Gpib.c */ -/* share/src/devOpt $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 05-30-91 jrw Initial Release - * .02 01-06-92 nda dg535 support under EPICS 3.3 - */ - -#define DSET_AI devAiK263Gpib -#define DSET_AO devAoK263Gpib -#define DSET_LI devLiK263Gpib -#define DSET_LO devLoK263Gpib -#define DSET_BI devBiK263Gpib -#define DSET_BO devBoK263Gpib -#define DSET_MBBO devMbboK263Gpib -#define DSET_MBBI devMbbiK263Gpib -#define DSET_SI devSiK263Gpib -#define DSET_SO devSoK263Gpib - -#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 - -static long init_dev_sup(), report(); -static struct devGpibParmBlock devSupParms; - -/****************************************************************************** - * - * Define all the dset's. - * - * Note that the dset names are provided via the #define lines at the top of - * this file. - * - * Other than for the debugging flag(s), these DSETs are the only items that - * will appear in the global name space within the IOC. - * - * The last 3 items in the DSET structure are used to point to the parm - * structure, the work functions used for each record type, and the srq - * handler for each record type. - * - ******************************************************************************/ -gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, - devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; - -gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, - devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; - -gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, - devGpibLib_readBi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; - -gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, - devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; - -gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, - devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; - -gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, - devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; - -gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, - devGpibLib_readSi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; - -gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, - devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; - -gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, - devGpibLib_readLi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; - -gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, - devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; - -int K263Debug = 0; /* debugging flags */ - -/* - * Use the TIME_WINDOW defn to indicate how long commands should be ignored - * for a given device after it times out. The ignored commands will be - * returned as errors to device support. - * - * Use the DMA_TIME to define how long you wish to wait for an I/O operation - * to complete once started. - */ -#define TIME_WINDOW 600 /* 10 seconds on a getTick call */ -#define DMA_TIME 30 /* 1/2 second on a watchdog time */ - - -/****************************************************************************** - * - * Array of structures that define all GPIB messages - * supported for this type of instrument. - * - ******************************************************************************/ - -static struct gpibCmd gpibCmds[] = -{ - /* Param 0, (model) */ - FILL, - - /* Param 1 initialization string */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "F2XR004XZ0XC0XW0XG1XO1XM00XK0XY4X", NULL, 0, 0, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 2 set voltage reference */ - {&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "V%lfX", 32, 32, - NULL, 0, 0, NULL, NULL, -1} - -}; - -/* The following is the number of elements in the command array above. */ -#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) - -/****************************************************************************** - * - * Structure containing the user's functions and operating parameters needed - * by the gpib library functions. - * - * The magic SRQ parm is the parm number that, if specified on a passive - * record, will cause the record to be processed automatically when an - * unsolicited SRQ interrupt is detected from the device. - * - * If the parm is specified on a non-passive record, it will NOT be processed - * when an unsolicited SRQ is detected. - * - ******************************************************************************/ -static struct devGpibParmBlock devSupParms = { - &K263Debug, /* debugging flag pointer */ - -1, /* set to -1 if the device does NOT respond to writes */ - TIME_WINDOW, /* # of clock ticks to skip after a device times out */ - NULL, /* hwpvt list head */ - gpibCmds, /* GPIB command array */ - NUMPARAMS, /* number of supported parameters */ - -1, /* magic SRQ param number (-1 if none) */ - "devXxK263Gpib", /* device support module type name */ - DMA_TIME, /* # of clock ticks to wait for DMA completions */ - - NULL, /* pointer to SRQ handler function (NULL if none) */ - NULL /* pointer to secondary conversion routine */ -}; - -/****************************************************************************** - * - * 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. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -static long -init_dev_sup(int parm) -{ - return(devGpibLib_initDevSup(parm, &DSET_AI)); -} - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -static long -report(void) -{ - return(devGpibLib_report(&DSET_AI)); -} diff --git a/src/vxWorks/devOpt/devXxSkeletonGpib.c b/src/vxWorks/devOpt/devXxSkeletonGpib.c deleted file mode 100644 index c792eab07..000000000 --- a/src/vxWorks/devOpt/devXxSkeletonGpib.c +++ /dev/null @@ -1,419 +0,0 @@ -/* devXxSkeletonGpib.c */ -/* share/src/devOpt $Id$ */ -/* - * Author: John Winans - * Date: 02-18-92 - * - * 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 02-18-92 jrw Initial Release - */ - -/****************************************************************************** - * - * The following define statements are used to declare the names to be used - * for the dset tables. - * - * NOTE: The dsets are referenced by the entries in the command table. - * - ******************************************************************************/ -#define DSET_AI devAiSkeletonGpib -#define DSET_AO devAoSkeletonGpib -#define DSET_LI devLiSkeletonGpib -#define DSET_LO devLoSkeletonGpib -#define DSET_BI devBiSkeletonGpib -#define DSET_BO devBoSkeletonGpib -#define DSET_MBBO devMbboSkeletonGpib -#define DSET_MBBI devMbbiSkeletonGpib -#define DSET_SI devSiSkeletonGpib -#define DSET_SO devSoSkeletonGpib - -#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 - -#define STATIC static - -STATIC long init_dev_sup(), report(); -STATIC int srqHandler(); -static struct devGpibParmBlock devSupParms; - -/****************************************************************************** - * - * Define all the dset's. - * - * Note that the dset names are provided via the #define lines at the top of - * this file. - * - * Other than for the debugging flag(s), these DSETs are the only items that - * will appear in the global name space within the IOC. - * - * The last 3 items in the DSET structure are used to point to the parm - * structure, the work functions used for each record type, and the srq - * handler for each record type. - * - ******************************************************************************/ -gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, - devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; - -gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, - devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; - -gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, - devGpibLib_readBi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; - -gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, - devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; - -gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, - devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; - -gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, - devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; - -gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, - devGpibLib_readSi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; - -gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, - devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; - -gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, - devGpibLib_readLi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; - -gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, - devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; - -/****************************************************************************** - * - * Debugging flags that can be accessed from the shell. - * - ******************************************************************************/ -int SkeletonDebug = 0; -extern int ibSrqDebug; /* declared in the GPIB driver */ - -/****************************************************************************** - * - * Use the TIME_WINDOW defn to indicate how long commands should be ignored - * for a given device after it times out. The ignored commands will be - * returned as errors to device support. - * - * Use the DMA_TIME to define how long you wish to wait for an I/O operation - * to complete once started. - * - * These are to be declared in 60ths of a second. - * - ******************************************************************************/ -#define TIME_WINDOW 600 /* 10 seconds */ -#define DMA_TIME 60 /* 1 second */ - -/****************************************************************************** - * - * Strings used by the init routines to fill in the znam, onam, ... - * fields in BI and BO record types. - * - ******************************************************************************/ - -static char *offOnList[] = { "Off", "On" }; -static struct devGpibNames offOn = { 2, offOnList, NULL, 1 }; - -static char *initNamesList[] = { "Init", "Init" }; -static struct devGpibNames initNames = { 2, initNamesList, NULL, 1 }; - -static char *disableEnableList[] = { "Disable", "Enable" }; -static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 }; - -static char *resetList[] = { "Reset", "Reset" }; -static struct devGpibNames reset = { 2, resetList, NULL, 1 }; - -static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" }; -static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1}; - -static char *invertNormList[] = { "INVERT", "NORM" }; -static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 }; - -static char *fallingRisingList[] = { "FALLING", "RISING" }; -static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 }; - -static char *clearList[] = { "CLEAR", "CLEAR" }; -static struct devGpibNames clear = { 2, clearList, NULL, 1 }; - -/****************************************************************************** - * - * Structures used by the init routines to fill in the onst, twst,... and the - * onvl, twvl,... fields in MBBI and MBBO record types. - * - * Note that the intExtSsBm and intExtSsBmStop structures use the same - * intExtSsBmStopList and intExtSsBmStopVal lists but have a different number - * of elements in them that they use... The intExtSsBm structure only represents - * 4 elements, while the intExtSsBmStop structure represents 5. - * - ******************************************************************************/ - -static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL", - "SINGLE SHOT", "BURST MODE", "STOP" }; - -static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 }; - -static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList, - intExtSsBmStopVal, 2 }; - -static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList, - intExtSsBmStopVal, 3 }; - -/****************************************************************************** - * - * String arrays for EFAST operations. Note that the last entry must be - * NULL. - * - * On input operations, only as many bytes as are found in the string array - * elements are compared. If there are more bytes than that in the input - * message, they are ignored. The first matching string found (starting - * from the 0'th element) will be used as a match. - * - * NOTE: For the input operations, the strings are compared literally! This - * can cause problems if the instrument is returning things like \r and \n - * characters. You must take care when defining input strings so you include - * them as well. - * - ******************************************************************************/ - -static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL}; - -/****************************************************************************** - * - * Array of structures that define all GPIB messages - * supported for this type of instrument. - * - ******************************************************************************/ - -static struct gpibCmd gpibCmds[] = -{ - /* Param 0 */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "init", NULL, 0, 32, - NULL, 0, 0, NULL, &initNames, -1}, - - /* Param 1 */ - {&DSET_BO, GPIBEFASTO, IB_Q_HIGH, NULL, NULL, 0, 32, - NULL, 0, 0, userOffOn, &offOn, -1}, - - /* Param 2 */ - {&DSET_BI, GPIBEFASTI, IB_Q_HIGH, "user?", NULL, 0, 32, - NULL, 0, 0, userOffOn, &offOn, -1}, - - /* Param 3 */ - {&DSET_AI, GPIBREAD, IB_Q_LOW, "send", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1} -}; - -/* The following is the number of elements in the command array above. */ -#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) - -/****************************************************************************** - * - * Structure containing the user's functions and operating parameters needed - * by the gpib library functions. - * - * The magic SRQ parm is the parm number that, if specified on a passive - * record, will cause the record to be processed automatically when an - * unsolicited SRQ interrupt is detected from the device. - * - * If the parm is specified on a non-passive record, it will NOT be processed - * when an unsolicited SRQ is detected. - * - * In the future, the magic SRQ parm records will be processed as "I/O event - * scanned"... not passive. - * - ******************************************************************************/ -static struct devGpibParmBlock devSupParms = { - &SkeletonDebug, /* debugging flag pointer */ - -1, /* device does not respond to writes */ - TIME_WINDOW, /* # of clock ticks to skip after a device times out */ - NULL, /* hwpvt list head */ - gpibCmds, /* GPIB command array */ - NUMPARAMS, /* number of supported parameters */ - -1, /* magic SRQ param number (-1 if none) */ - "devXxSkeletonGpib", /* device support module type name */ - DMA_TIME, /* # of clock ticks to wait for DMA completions */ - NULL, /* SRQ handler function (NULL if none) */ - NULL /* secondary conversion routine (NULL if none) */ -}; - -/****************************************************************************** - * - * 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. - * - ******************************************************************************/ -STATIC long -init_dev_sup(int parm) -{ - return(devGpibLib_initDevSup(parm,&DSET_AI)); -} - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - * This function will no longer be required after epics 3.3 is released - * - ******************************************************************************/ -STATIC long -report(void) -{ - return(devGpibLib_report(&DSET_AI)); -} -/****************************************************************************** - * - * A sample SRQ handler. This one is taken from the DC5009 gpib device support - * module. Its primary function is to check the serial poll byte to determine - * why an SRQ was generated from the device. If the SRQ is an operation - * complete, and the GPIB library code was expecting one, it would have left - * a pointer to a function that can be used to finish processing the - * transaction that solicited the OPC SRQ. In other cases, an error or event - * of interest has occured and notice should be taken. - * - * This is invoked by the linkTask when an SRQ is detected from a device - * operated by this module. - * - * It calls the work routine associated with the type of record expecting - * the SRQ response. - * - * No semaphore locks are needed around the references to anything in the - * hwpvt structure, because it is static unless modified by the linkTask and - * the linkTask is what will execute this function. - * - * THIS ROUTINE WILL GENERATE UNPREDICTABLE RESULTS IF... - * - the MAGIC_SRQ_PARM command is a GPIBREADW command. - * - the device generates unsolicited SRQs while processing GPIBREADW commands. - * - * In general, this function will have to be modified for each device - * type that SRQs are to be supported. This is because the serial poll byte - * format varies from device to device. - * - ******************************************************************************/ - -#define DC5009_GOODBITS 0xef /* I only care about these bits */ - -#define DC5009_PON 65 /* power just turned on */ -#define DC5009_OPC 66 /* operation just completed */ -#define DC5009_USER 67 /* user requested SRQ */ - -STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus) -{ - int status = IDLE; /* assume device will be idle when finished */ - - if (SkeletonDebug || ibSrqDebug) - printf("dc5009 srqHandler(%p, 0x%2.2X): called\n", phwpvt, srqStatus); - - switch (srqStatus & DC5009_GOODBITS) { - case DC5009_OPC: - - /* Invoke the command-type specific SRQ handler */ - if (phwpvt->srqCallback != NULL) - status = ((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus)); - else - printf("dc5009 srqHandler: Unsolicited operation complete from DC5009 device support!\n"); - break; -/* BUG - I have to clear out the error status by doing an err? read operation */ - - case DC5009_USER: - - /* user requested srq event is specific to the Dc5009 */ - printf("dc5009 srqHandler: Dc5009 User requested srq event link %d, device %d\n", phwpvt->link, phwpvt->device); - break; -/* BUG - I have to clear out the error status by doing an err? read operation */ - - case DC5009_PON: - - printf("dc5009 srqHandler: Power cycled on DC5009\n"); - break; -/* BUG - I have to clear out the error status by doing an err? read operation */ - - default: - - - if (phwpvt->unsolicitedDpvt != NULL) - { - if(SkeletonDebug || ibSrqDebug) - printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%2.2X\n", - phwpvt->link, phwpvt->device, srqStatus); - - ((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process; - ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri; - callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt); - } - else - { - printf("dc5009 srqHandler: Unsolicited SRQ ignored from link %d, device %d, status = 0x%2.2X\n", - phwpvt->link, phwpvt->device, srqStatus); - } - } - return(status); -} diff --git a/src/vxWorks/devOpt/devXxSoftMsg.c b/src/vxWorks/devOpt/devXxSoftMsg.c deleted file mode 100644 index c8d88b5f3..000000000 --- a/src/vxWorks/devOpt/devXxSoftMsg.c +++ /dev/null @@ -1,254 +0,0 @@ -/* share/src/devOpt $Id$ */ -/* - * Author: John Winans - * Date: 04-13-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 09-30-91 jrw created - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static long BBinit(), BBreport(), VXinit(), VXreport(); -static msgParmBlock BBParmBlock, VXParmBlock; - -/****************************************************************************** - * - * DSET tables used for BITBUS -> RS-232 ports. - * - ******************************************************************************/ -msgDset devBBAiSoftMsg = { 6, { BBreport, BBinit, drvMsg_initAi, NULL, - drvMsg_procAi, NULL}, &BBParmBlock, &drvMsgAi}; -msgDset devBBAoSoftMsg = { 6, { NULL, NULL, drvMsg_initAo, NULL, - drvMsg_procAo, NULL}, &BBParmBlock, &drvMsgAo}; - -msgDset devBBBiSoftMsg = { 6, { NULL, NULL, drvMsg_initBi, NULL, - drvMsg_procBi, NULL}, &BBParmBlock, &drvMsgBi}; -msgDset devBBBoSoftMsg = { 6, { NULL, NULL, drvMsg_initBo, NULL, - drvMsg_procBo, NULL}, &BBParmBlock, &drvMsgBo}; - -msgDset devBBMiSoftMsg = { 6, { NULL, NULL, drvMsg_initMi, NULL, - drvMsg_procMi, NULL}, &BBParmBlock, &drvMsgMi}; -msgDset devBBMoSoftMsg = { 6, { NULL, NULL, drvMsg_initMo, NULL, - drvMsg_procMo, NULL}, &BBParmBlock, &drvMsgMo}; - -msgDset devBBLiSoftMsg = { 6, { NULL, NULL, drvMsg_initLi, NULL, - drvMsg_procLi, NULL}, &BBParmBlock, &drvMsgLi}; -msgDset devBBLoSoftMsg = { 6, { NULL, NULL, drvMsg_initLo, NULL, - drvMsg_procLo, NULL}, &BBParmBlock, &drvMsgLo}; - -msgDset devBBSiSoftMsg = { 6, { NULL, NULL, drvMsg_initSi, NULL, - drvMsg_procSi, NULL}, &BBParmBlock, &drvMsgSi}; -msgDset devBBSoSoftMsg = { 6, { NULL, NULL, drvMsg_initSo, NULL, - drvMsg_procSo, NULL}, &BBParmBlock, &drvMsgSo}; - -msgDset devBBWfSoftMsg = { 6, { NULL, NULL, drvMsg_initWf, NULL, - drvMsg_procWf, NULL}, &BBParmBlock, &drvMsgWf}; - -/****************************************************************************** - * - * DSET tables used for vxWorks tty ports. - * - ******************************************************************************/ -msgDset devVXAiSoftMsg = { 6, { VXreport, VXinit, drvMsg_initAi, NULL, - drvMsg_procAi, NULL}, &VXParmBlock, &drvMsgAi}; -msgDset devVXAoSoftMsg = { 6, { NULL, NULL, drvMsg_initAo, NULL, - drvMsg_procAo, NULL}, &VXParmBlock, &drvMsgAo}; - -msgDset devVXBiSoftMsg = { 6, { NULL, NULL, drvMsg_initBi, NULL, - drvMsg_procBi, NULL}, &VXParmBlock, &drvMsgBi}; -msgDset devVXBoSoftMsg = { 6, { NULL, NULL, drvMsg_initBo, NULL, - drvMsg_procBo, NULL}, &VXParmBlock, &drvMsgBo}; - -msgDset devVXMiSoftMsg = { 6, { NULL, NULL, drvMsg_initMi, NULL, - drvMsg_procMi, NULL}, &VXParmBlock, &drvMsgMi}; -msgDset devVXMoSoftMsg = { 6, { NULL, NULL, drvMsg_initMo, NULL, - drvMsg_procMo, NULL}, &VXParmBlock, &drvMsgMo}; - -msgDset devVXLiSoftMsg = { 6, { NULL, NULL, drvMsg_initLi, NULL, - drvMsg_procLi, NULL}, &VXParmBlock, &drvMsgLi}; -msgDset devVXLoSoftMsg = { 6, { NULL, NULL, drvMsg_initLo, NULL, - drvMsg_procLo, NULL}, &VXParmBlock, &drvMsgLo}; - -msgDset devVXSiSoftMsg = { 6, { NULL, NULL, drvMsg_initSi, NULL, - drvMsg_procSi, NULL}, &VXParmBlock, &drvMsgSi}; -msgDset devVXSoSoftMsg = { 6, { NULL, NULL, drvMsg_initSo, NULL, - drvMsg_procSo, NULL}, &VXParmBlock, &drvMsgSo}; - -msgDset devVXWfSoftMsg = { 6, { NULL, NULL, drvMsg_initWf, NULL, - drvMsg_procWf, NULL}, &VXParmBlock, &drvMsgWf}; - -int softMsgDebug = 0; - -static msgStrParm wrParms[] = { - { "Parm 0 write string!\n\r", -1}, - { "wrParm-1 raw write string\n\r", -1 }, - { "123456789012", -1 }, - { "1234567890123", -1 }, - { "12345678901234", -1}, -}; - -static msgFoParm foParms[] = { - { "Parm 1 Value is: %lf\n\r" }, - { "pArM 2 VaLuE iS: %lf\n\r" }, - { "longout value is %ld\n\r" } -}; - -static msgFiParm fiParms[] = { - { "%s %lf", 0, 50 }, - { "%lf", 0, 50 }, - { "%ld", 0, 50 }, -}; - -static msgCmd cmds[] = { -{&drvMsgAi, READ_NDLY, {MSG_OP_WRITE, &wrParms[0]}, {MSG_OP_FAI, &fiParms[0]}, NULL, -1}, -{&drvMsgAo, READ_NDLY, {MSG_OP_FAO, &foParms[0]}, {MSG_OP_NOP, NULL}, NULL, -1}, -{&drvMsgAi, READ_NDLY, {MSG_OP_WRITE, &wrParms[1]}, {MSG_OP_FAI, &fiParms[1]}, NULL, -1}, -{&drvMsgAo, READ_NDLY, {MSG_OP_FAO, &foParms[1]}, {MSG_OP_NOP, NULL}, NULL, -1}, -{&drvMsgLi, READ_NDLY, {MSG_OP_WRITE, &wrParms[1]}, {MSG_OP_FLI, &fiParms[2]}, NULL, -1}, -{&drvMsgLo, READ_NDLY, {MSG_OP_FLO, &foParms[2]}, {MSG_OP_NOP, NULL}, NULL, -1}, -{&drvMsgBo, READ_NDLY, {MSG_OP_WRITE, &wrParms[2]}, {MSG_OP_NOP, NULL}, NULL, -1}, -{&drvMsgBo, READ_NDLY, {MSG_OP_WRITE, &wrParms[3]}, {MSG_OP_NOP, NULL}, NULL, -1}, -{&drvMsgBo, READ_NDLY, {MSG_OP_WRITE, &wrParms[4]}, {MSG_OP_NOP, NULL}, NULL, -1}, -}; - -/****************************************************************************** - * - * The devTy232ParmBlock contains vxWorks tty-driver specific extensions to - * the msgParmBlock structure. - * - ******************************************************************************/ -/* For vxWorks tty ports */ -static devTy232ParmBlock parm232extension = { - 0, /* Time window */ - 60, /* DMA time limit */ - KILL_CRLF, /* loose the CRs and LFs */ - 0x0d, /* EOI character, always stop reading when I hit it */ - 9600, /* Baud rate to the machine at */ - OPT_7_BIT /* 7-bit transfers */ -}; - -/****************************************************************************** - * - * The drvBB232ParmBlock contains the bitbus->RS232 specific extensions to the - * msgParmBlock structure. - * - ******************************************************************************/ -static drvBB232ParmBlock parmBB232extension = { - 0, - 9600 -}; -/****************************************************************************** - * - * The parmBlock is used to define the relationship b/w the command table and - * the driverBlock. - * - ******************************************************************************/ - -/* For records requesting Bitbus->232 */ - -static msgParmBlock BBParmBlock = { - &softMsgDebug, - NULL, - cmds, - sizeof(cmds) / sizeof(msgCmd), - "softMsg", - &drvBB232Block, - drvMsg_xactWork, - &parmBB232extension -}; - -/* For records requesting vxWorks tty */ - -static msgParmBlock VXParmBlock = { - &softMsgDebug, - NULL, - cmds, - sizeof(cmds) / sizeof(msgCmd), - "softMsg", - &drv232Block, - drvMsg_xactWork, - &parm232extension -}; - -/****************************************************************************** - * - * These are used to add parameters to calls made to the init routines. - * - ******************************************************************************/ - -/* For records requesting Bitbus->232 */ - -static long -BBinit(parm) -int parm; -{ - return(drvMsg_initMsg(parm, &devBBAiSoftMsg)); -} -static long -BBreport() -{ - return(drvMsg_reportMsg(&devBBAiSoftMsg)); -} - -/* For records requesting vxWorks tty */ - -static long -VXinit(parm) -int parm; -{ - return(drvMsg_initMsg(parm, &devVXAiSoftMsg)); -} -static long -VXreport() -{ - return(drvMsg_reportMsg(&devVXAiSoftMsg)); -} diff --git a/src/vxWorks/devOpt/devXxSr620Gpib.c b/src/vxWorks/devOpt/devXxSr620Gpib.c deleted file mode 100644 index e432a727b..000000000 --- a/src/vxWorks/devOpt/devXxSr620Gpib.c +++ /dev/null @@ -1,324 +0,0 @@ -/* devXxSr620Gpib.c */ -/* share/src/devOpt $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 05-30-91 jrw Initial Release - */ - -#define DSET_AI devAiSr620Gpib -#define DSET_AO devAoSr620Gpib -#define DSET_LI devLiSr620Gpib -#define DSET_LO devLoSr620Gpib -#define DSET_BI devBiSr620Gpib -#define DSET_BO devBoSr620Gpib -#define DSET_MBBO devMbboSr620Gpib -#define DSET_MBBI devMbbiSr620Gpib -#define DSET_SI devSiSr620Gpib -#define DSET_SO devSoSr620Gpib - -#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 - -#define STATIC static - -STATIC long init_dev_sup(), report(); -STATIC int srqHandler(); -static struct devGpibParmBlock devSupParms; - -/****************************************************************************** - * - * Define all the dset's. - * - * Note that the dset names are provided via the #define lines at the top of - * this file. - * - * Other than for the debugging flag(s), these DSETs are the only items that - * will appear in the global name space within the IOC. - * - ******************************************************************************/ -gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL, - devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}}; -gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL, - devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_aoGpibWork, NULL}}; -gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL, - devGpibLib_readBi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}}; -gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL, - devGpibLib_writeBo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_boGpibWork, NULL}}; -gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL, - devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}}; -gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL, - devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}}; -gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL, - devGpibLib_readSi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}}; -gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL, - devGpibLib_writeSo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}}; -gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL, - devGpibLib_readLi, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}}; -gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL, - devGpibLib_writeLo, (DRVSUPFUN)&devSupParms, - (DRVSUPFUN)devGpibLib_loGpibWork, NULL}}; - -int sr620Debug = 0; /* debugging flags */ -extern int ibSrqDebug; - -/* - * Use the TIME_WINDOW defn to indicate how long commands should be ignored - * for a given device after it times out. The ignored commands will be - * returned as errors to device support. - */ -#define TIME_WINDOW 600 /* 10 seconds on a getTick call */ -#define DMA_TIME 60 - -static char *offOnList[] = { "Off", "On" }; -static struct devGpibNames offOn = { 2, offOnList, NULL, 1 }; - -static char *offOffList[] = { "Off", "Off" }; -static struct devGpibNames offOff = { 2, offOffList, NULL, 1 }; - -static char *onOnList[] = { "On", "On" }; -static struct devGpibNames onOn = { 2, onOnList, NULL, 1 }; - -static char *initNamesList[] = { "Init", "Init" }; -static struct devGpibNames initNames = { 2, initNamesList, NULL, 1 }; - -static char *disableEnableList[] = { "Disable", "Enable" }; -static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 }; - -static char *resetList[] = { "Reset", "Reset" }; -static struct devGpibNames reset = { 2, resetList, NULL, 1 }; - -static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" }; -static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1}; - -static char *invertNormList[] = { "INVERT", "NORM" }; -static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 }; - -static char *fallingRisingList[] = { "FALLING", "RISING" }; -static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 }; - -static char *clearList[] = { "CLEAR", "CLEAR" }; -static struct devGpibNames clear = { 2, clearList, NULL, 1 }; - -/****************************************************************************** - * - * Array of structures that define all GPIB messages - * supported for this type of instrument. - * - ******************************************************************************/ - -static struct gpibCmd gpibCmds[] = -{ - /* Param 0, init the instrument */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "*RST;*WAI;*CLS;*ESE 1", NULL, 0, 32, - NULL, 0, 0, NULL, &reset, -1}, - - /* Param1 */ - {&DSET_LO, GPIBWRITE, IB_Q_HIGH, NULL, "mode %ld", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param2 */ - {&DSET_LO, GPIBWRITE, IB_Q_HIGH, NULL, "ARMM %ld", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 3 */ - {&DSET_BO, GPIBCMD, IB_Q_HIGH, "*OPC %d", NULL, 0, 32, - NULL, 0, 0, NULL, &offOn, -1}, - - /* Param 4 send an mean?0 and generate an SRQ when finished */ - {&DSET_AI, GPIBREADW, IB_Q_HIGH, "*SRE 16;meas?0;*wai;*SRE 0", "%lf", 0, 32, - NULL, 0, 0, NULL, NULL, -1}, - - /* Param 5 */ - {&DSET_AI, GPIBREAD, IB_Q_HIGH, "XALL?", NULL, 0, 32, - NULL, 0, 0, NULL, NULL, -1} -}; - -/* The following is the number of elements in the command array above. */ -#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd) - -/****************************************************************************** - * - * Structure containing the user's functions and operating parameters needed - * by the gpib library functions. - * - * The magic SRQ parm is the parm number that, if specified on a passive - * record, will cause the record to be processed automatically when an - * unsolicited SRQ interrupt is detected from the device. - * - * If the parm is specified on a non-passive record, it will NOT be processed - * when an unsolicited SRQ is detected. - * - ******************************************************************************/ -static struct devGpibParmBlock devSupParms = { - &sr620Debug, /* debugging flag pointer */ - -1, /* device does not respond to writes */ - TIME_WINDOW, /* # of clock ticks to skip after a device times out */ - NULL, /* hwpvt list head */ - gpibCmds, /* GPIB command array */ - NUMPARAMS, /* number of supported parameters */ - -1, /* magic SRQ param number */ - "devXxSr620Gpib", /* device support module type name */ - DMA_TIME, - - srqHandler, /* pointer to SRQ handler function */ - - NULL /* pointer to secondary converstion routine */ -}; - -/****************************************************************************** - * - * This is invoked by the linkTask when an SRQ is detected from a device - * operated by this module. - * - * It calls the work routine associated with the type of record expecting - * the SRQ response. - * - * No semaphore locks are needed around the references to anything in the - * hwpvt structure, because it is static unless modified by the linkTask and - * the linkTask is what will execute this function. - * - * THIS ROUTINE WILL GENERATE UNPREDICTABLE RESULTS IF... - * - the MAGIC_SRQ_PARM command is a GPIBREADW command. - * - the device generates unsolicited SRQs while processing GPIBREADW commands. - * - * In general, this function will have to be heavily modified for each device - * type that SRQs are to be supported. This is because the serial poll byte - * format varies from device to device. - * - ******************************************************************************/ - -#define SR620_ERROR 0x04 /* bit masks for status indicators */ -#define SR620_TIC 0x08 -#define SR620_MAV 0x10 -#define SR630_ESB 0x20 - -STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus) -{ - int status = IDLE; /* assume device will be idle when finished */ - - if (sr620Debug || ibSrqDebug) - logMsg("srqHandler(0x%08.8X, 0x%02.2X): called\n", phwpvt, srqStatus); - - if (srqStatus & SR620_MAV) /* is data available to be read? */ - { - /* Invoke the command-type specific SRQ handler */ - if (phwpvt->srqCallback != NULL) - status = ((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus)); - else if (sr620Debug || ibSrqDebug) - logMsg("Unsolicited operation complete from SR620 device support!\n"); - } - else - { - if (phwpvt->unsolicitedDpvt != NULL) - { - if (sr620Debug || ibSrqDebug) - logMsg("Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n", - phwpvt->link, phwpvt->device, srqStatus); - - ((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process; - ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri; - callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt); - } - else - { - if (sr620Debug || ibSrqDebug) - logMsg("Unsolicited SRQ ignored from link %d, device %d, status = 0x%02.2X\n", - phwpvt->link, phwpvt->device, srqStatus); - } - } - return(status); -} - -/****************************************************************************** - * - * 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. - * - ******************************************************************************/ -STATIC long -init_dev_sup(int parm) -{ - return(devGpibLib_initDevSup(parm, &DSET_AI)); -} - -/****************************************************************************** - * - * Print a report of operating statistics for all devices supported by this - * module. - * - ******************************************************************************/ -STATIC long -report(void) -{ - return(devGpibLib_report(&DSET_AI)); -} diff --git a/src/vxWorks/drv/ansi/drvAt5Vxi.c b/src/vxWorks/drv/ansi/drvAt5Vxi.c deleted file mode 100644 index 14a0d29d6..000000000 --- a/src/vxWorks/drv/ansi/drvAt5Vxi.c +++ /dev/null @@ -1,1414 +0,0 @@ -/* base/src/drv $Id$ */ - -/* - * - * driver for at5 designed VXI modules - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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 joh 021490 first release - * .02 joh 040490 took out init of binary outs as requested by AT5 - * .03 joh 040490 KLUDGED so DC is invarient of model number - * .04 joh 072590 fixed case where a missing SC module could - * be accessed before checking to prevent bus error - * .05 joh 102990 slightly improved sync to busy in init - * .06 joh 032191 added code to implement a new register - * interface from AT5 - * .07 joh 080291 disable ints during control X reboot - * .08 joh 080291 fixed ints on before handler installed problem - * introduced by .06 - * .09 joh 080291 synch source with sorce release control version - * .10 joh 080891 delinting - * .11 joh 090591 converted to v5 vxWorks - * .12 joh 120591 reorganized for use with new vxi support and removed - * KLUDGE introduced in .03 - * .13 joh 042492 removed support for (ifdefs for) the old - * style register map - * .14 joh 071792 added model name registration - * .15 joh 072992 print more raw values in io report - * .16 joh 081092 merged at5vxi_models.h into this source - * .17 joh 081992 function name change - * .18 joh 082792 converted to ansi C - * .19 joh 111392 removed shifts on analog IO - * .20 joh 071593 fixed comment - * .21 joh 081193 took out EPICS_V2 compile switches - * - * Notes: - * ------ - * .01 Dont use C bitfields to write the AT5VXI CSR - * directly because some bits have different meanings - * for read than for write (bitfields writes generate RMW - * instructions- performing reads with C bitfields - * from an IO module works fine however). - * - * To avoid this I write all bits in the CSR with - * each write. See the codes defined by at5vxi_init(). - */ - -/* - * Improvements: - * - * Dont allow them to connect an interrupt if another device is - * installed there ! Perhaps intConnectSafe() should be written? - */ - - - -/* - * Code Portions - * - * AT5VXI_INIT initialize all at5vxi cards - * AT5VXI_INIT_CARD initialize single at5vxi card - * AT5VXI_INT_SERVICE update card busy writes, notify IO scanner - * AT5VXI_ONE_SHOT setup AMD9513 STC with a one shot - * AT5VXI_ONE_SHOT_READ read back timing from an AMD 9513 STC - * AT5VXI_STAT print status for a single at5 vxi card - * AT5VXI_READ_TEST diagnostic - * AT5VXI_AI_DRIVER analog input driver - * AT5VXI_AO_DRIVER analog output driver - * AT5VXI_AO_READ analog output read back - * AT5VXI_BI_DRIVER binary input driver - * AT5VXI_BO_DRIVER binary output driver - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char SccsId[] = "@(#)drvAt5Vxi.c 1.19\t8/27/93"; - -LOCAL void at5vxi_int_service( - int addr -); - -LOCAL void at5vxi_init_card( - unsigned addr, - void *pArg -); - -LOCAL int at5vxi_shutdown(void); - -LOCAL void at5vxi_shutdown_card( - unsigned la, - void *pArg -); - -LOCAL at5VxiStatus at5vxi_report_timing( - unsigned card, - unsigned channel -); - -LOCAL void at5vxi_stat( - unsigned card, - int level -); - -LOCAL at5VxiStatus at5vxi_init( - void -); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvAt5Vxi={ - 2, - NULL, /* VXI io report takes care of this */ - at5vxi_init}; - -#define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */ - -/* - * Set this flag if you wish for the driver to - * to disable the busy period and operate - * without periodic interrupts - * -#define CONTINUOUS_OPERATION - * - */ - -/* - * all AT5VXI cards will use this VME interrupt level - */ -#ifdef CONTINUOUS_OPERATION -# define AT5VXI_INT_LEVEL 0 -# define AT5VXI_INT_ENABLE FALSE -# define AT5VXI_BUSY_ENABLE FALSE -#else -# define AT5VXI_INT_LEVEL 5 -# define AT5VXI_INT_ENABLE TRUE -# define AT5VXI_BUSY_ENABLE TRUE -#endif - -#define abort(A) taskSuspend(0) - -/* - * bit fields allocated starting with the ms bit - */ -struct at5vxi_status{ - unsigned pad0:1; - unsigned modid_cmpl:1; - unsigned dev255:1; - unsigned busy:1; - unsigned pad1:2; - unsigned timer_bank:1; - unsigned ipend:1; - unsigned ienable:1; - unsigned ilevel:3; - unsigned ready:1; - unsigned passed:1; - unsigned sfinh:1; - unsigned sreset:1; -}; - - -#define PSTATUS(PCSR)\ -(&((struct vxi_csr *)PCSR)->dir.r.status) - -struct at5vxi_control{ - unsigned pad0:3; - unsigned busy_enable:1; - unsigned pad1:2; - unsigned timer_bank:1; - unsigned softint:1; - unsigned ienable:1; - unsigned ilevel:3; - unsigned pad2:2; - unsigned sfinh:1; - unsigned sreset:1; -}; - -/* - * Insert or extract a bit field using the standard - * masks and shifts defined below - */ -#ifdef __STDC__ -# define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S)) -# define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M)) -#else -# define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S)) -# define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M)) -#endif - -/* - * in the constants below _M is a right justified mask - * and _S is a shift required to right justify the field - */ -#define FD_INT_ENABLE_M (0x1) -#define FD_INT_ENABLE_S (7) -#define FD_BUSY_ENABLE_M (0x1) -#define FD_BUSY_ENABLE_S (12) -#define FD_BUSY_STATUS_M (0x1) -#define FD_BUSY_STATUS_S (12) -#define FD_INT_LEVEL_M (0x7) -#define FD_INT_LEVEL_S (4) -#define FD_TIMER_BANK_M (0x1) -#define FD_TIMER_BANK_S (9) - -#define BUSY(PCSR)\ -(((struct vxi_csr *)PCSR)->dir.r.status & INSERT(BUSY_STATUS,1)) - -/* - * Some constants for the CSR. - * - */ -#ifndef CONTINUOUS_OPERATION -# define INTDISABLE\ - ( \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_ENABLE, FALSE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) -#endif - -/* - * Used to initialize the control register. - * (enables interrupts) - */ -#define CSRINIT\ - ( \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_ENABLE, AT5VXI_INT_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) - -/* - * Use bank zero of the timing. - */ -#define BANK0\ - ( \ - INSERT(TIMER_BANK, 0) | \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) -/* - * Use bank one of the timing. - */ -#define BANK1\ - ( \ - INSERT(TIMER_BANK, 1) | \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) - -/* - * Some constants for the CSR. - * set at initialization for better readability - */ -#define PCONTROL(PCSR)\ -(&((struct vxi_csr *)PCSR)->dir.w.control) - - - - -#define AT5VXI_TIMER_BANKS_PER_MODULE 2 -#define AT5VXI_CHANNELS_PER_TIMER_BANK 5 -#define AT5VXI_NTIMER_CHANNELS\ - (AT5VXI_TIMER_BANKS_PER_MODULE*AT5VXI_CHANNELS_PER_TIMER_BANK) - - -struct at5vxi_dd{ - vxi16_t bio[2]; - vxi16_t tdata; - vxi8_t pad; - vxi8_t tcmd; - vxi16_t ai[8]; - vxi16_t ao[16]; -}; - - -struct at5vxi_setup{ -# define UNITY 0 -# define TIMES2 1 - unsigned gainA:1; - unsigned gainB:1; - unsigned gainC:1; - unsigned gainD:1; -# define UNIPOLAR 0 -# define BIPOLAR 1 - unsigned modeA:1; - unsigned modeB:1; - unsigned modeC:1; - unsigned modeD:1; - unsigned ch2enbl:1; - unsigned ch2select:3; - unsigned ch1enbl:1; - unsigned ch1select:3; -}; - - -#define AT5VXI_BUSY_PERIOD 2 - -struct bo_val { - volatile int32_t val; - volatile int32_t mask; -}; - -struct ao_val { - volatile int16_t mdt; - volatile int16_t val; -}; - -struct time_val { - volatile unsigned preset; - volatile int16_t iedge0_delay; - volatile int16_t iedge1_delay; - volatile char mdt; - volatile char valid; -}; - -struct at5vxi_config{ - FAST_LOCK lock; /* mutual exclusion */ - struct bo_val bv; /* binary out values */ - struct ao_val av[16]; /* analog out values */ - struct time_val tv[10]; /* delayed pulse values */ - volatile char mdt; /* modified data tag */ - struct vxi_csr *pcsr; /* vxi device hdr ptr */ - struct at5vxi_dd *pdd; /* at5 device dep ptr */ - IOSCANPVT ioscanpvt; -}; - -LOCAL unsigned long at5vxiDriverID; - -#define AT5VXI_PCONFIG(CARD, PTR) \ -epvxiFetchPConfig(CARD, at5vxiDriverID, PTR) - -#define AT5VXI_CORRECT_MAKE(PCSR) (VXIMAKE(PCSR)==VXI_MAKE_LANSCE5) - -struct at5vxi_model{ - char *name; /* AT5 VXI module name */ - char *drawing; /* AT5 VXI assembly drawing number */ -}; - -#define AT5VXI_INDEX_FROM_MODEL(MODEL) ((unsigned)((MODEL)&0xff)) -#define AT5VXI_MODEL_FROM_INDEX(INDEX) ((unsigned)((INDEX)|0xf00)) - -/* - * NOTE: The macro AT5VXI_INDEX_FROM_MODEL(MODEL) defined above - * should return an index into the correct data given the - * VXI device's model code. - */ -struct at5vxi_model at5vxi_models[] = { - {"INTERFACE SIMULATOR", "112Y-280158"}, - {"I CONTROLLER", "112Y-280176"}, - {"CONTROL PREDISTORTER", "112Y-280172"}, - {"VECTOR DETECTOR", "112Y-280230"}, - {"VECTOR MODULATOR", "112Y-280177"}, - {"425MHz ENVELOPE DETECTOR", "112Y-280169"}, - {"425MHz DOWNCONVERTER", "112Y-280165"}, - {"POLAR DETECTOR", "112Y-280567"}, - {"UPCONVERTER", "112Y-280225"}, - {"MONITOR TRANSMITTER", "112Y-280187"}, - {"TIMING DISTRIBUTION", "112Y-280582"}, - {"LINE CONDITIONER", "112Y-280305"}, - {"BEAM FEEDFORWARD", "112Y-280564"}, - {"TIMING RECEIVER", "112Y-280243"}, - {"FAST PROTECTION", "112Y-280246"}, - {"ADAPTIVE FEEDFORWARD", "112Y-280563"}, - {"CABLE CONTROLLER", "112Y-280307"}, - {"Q CONTROLLER", "112Y-280180"}, - {"ENVELOPE DETECTOR", "112Y-280249"}, - {"DOWNCONVERTER", "112Y-280456"}, - {"COAX MONITOR TRANSMITTER", "112Y-280587"}, - {"CAVITY SIMULATOR", "112Y-280232"}, - {"CABLE CONTROLLER (2 CHANNEL)","112Y-280539"}, - {"BREADBOARD", "112Y-280358"}, - {"I/O INTERFACE", "112Y-280359"}, - {"DIAGNOSTIC - BPM", "112Y-280422-1"}, - {"FAST ENVELOPE DETECTOR", "112Y-280421"}, - {"DIAGNOSTIC - CM", "112Y-280422-2"}, - {"DIAGNOSTIC - MISC", "112Y-280422-3"}, - {"FAST VECTOR DETECTOR", "112Y-280651"}, - {"SINGLE-WIDE VECTOR DETECTOR", "112Y-280672"}, - {"FM / AM", "112Y-280xxx"} -}; - -#define AT5VXI_VALID_MODEL(MODEL) \ -(AT5VXI_INDEX_FROM_MODEL(MODEL)dir.w.control = INTDISABLE; -#endif -} - - - -/* - * AT5VXI_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL -void at5vxi_init_card( - unsigned addr, - void *pArg -) -{ - at5VxiStatus r0; - struct at5vxi_config *pc; - struct time_val *ptv; - unsigned chan; - int i; - int model; - - r0 = epvxiOpen( - addr, - at5vxiDriverID, - (unsigned long) sizeof(*pc), - at5vxi_stat); - if(r0){ - errPrintf( - r0, - __FILE__, - __LINE__, - "AT5VXI: device open failed %d\n", addr); - return; - } - - r0 = AT5VXI_PCONFIG(addr, pc); - if(r0){ - errMessage(r0, NULL); - epvxiClose(addr, at5vxiDriverID); - return; - } - - pc->pcsr = VXIBASE(addr); - pc->pdd = (struct at5vxi_dd *) &pc->pcsr->dir.r.dd; - - FASTLOCKINIT(&pc->lock); - - scanIoInit(&pc->ioscanpvt); - - - /* - * revert to power up control - * (temporarily disable the busy period) - */ - pc->pcsr->dir.w.control = 0; - - -#ifndef CONTINUOUS_OPERATION - /* - * wait 5 sec for the end of current busy cycle as required - * (busy period is temporarily disabled - * - */ - for(i=0; i<5 && BUSY(pc->pcsr); i++) - taskDelay(sysClkRateGet()); - if(BUSY(pc->pcsr)){ - epvxiClose(addr, at5vxiDriverID); - return; - } -#endif - -#if defined(INIT_BINARY_OUTS) - /* - * Set AD 664 default - */ - { - struct at5vxi_setup su; - - su.gainA = TIMES2; - su.gainB = TIMES2; - su.gainC = TIMES2; - su.gainD = TIMES2; - - su.modeA = BIPOLAR; - su.modeB = BIPOLAR; - su.modeC = BIPOLAR; - su.modeD = BIPOLAR; - - su.ch2enbl = FALSE; - su.ch1enbl = FALSE; - - (* (struct at5vxi_setup *) &pc->pdd->bio[1]) = su; - } -#endif - - /* - * Init AMD 9513 for - * - * binary division - * data ptr seq enbl - * 16 bit bus - * FOUT on - * FOUT divide by 16 - * FOUT source (F1) - * Time of day disabled - */ -# define MASTER_MODE ((uint16_t)0x2000) - *PCONTROL(pc->pcsr) = BANK0; - r0 = stc_init( &pc->pdd->tcmd, - &pc->pdd->tdata, - MASTER_MODE); - if(r0!=STC_SUCCESS){ - epvxiClose(addr, at5vxiDriverID); - return; - } - - *PCONTROL(pc->pcsr) = BANK1; - r0 = stc_init( - &pc->pdd->tcmd, - &pc->pdd->tdata, - MASTER_MODE); - if(r0!=STC_SUCCESS){ - epvxiClose(addr, at5vxiDriverID); - return; - } - - for(chan=0, ptv = pc->tv; chantv); chan++, ptv++){ - unsigned int_source; - - if(chan/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pc->pcsr) = BANK1; - } - else{ - *PCONTROL(pc->pcsr) = BANK0; - } - - /* - * casting below discards volatile - * (ok in this case) - */ - r0 = stc_one_shot_read( - (unsigned *)&ptv->preset, - (uint16_t *)&ptv->iedge0_delay, - (uint16_t *)&ptv->iedge1_delay, - &pc->pdd->tcmd, - &pc->pdd->tdata, - chan, - &int_source); - if(r0 == STC_SUCCESS && int_source == FALSE) - ptv->valid = TRUE; - else - ptv->valid = FALSE; - } - -# ifndef CONTINUOUS_OPERATION - r0 = intConnect( - INUM_TO_IVEC(addr), - at5vxi_int_service, - addr); - if(r0 == ERROR) - return; - - sysIntEnable(AT5VXI_INT_LEVEL); -# endif - - /* - * init the csr - * (see at5vxi_init() for field definitions) - * interrupts enabled if not compiled for continuous operation - */ - *PCONTROL(pc->pcsr) = CSRINIT; - - model = VXIMODEL(pc->pcsr); - if(AT5VXI_VALID_MODEL(model)){ - r0 = epvxiRegisterModelName( - VXIMAKE(pc->pcsr), - model, - at5vxi_models[AT5VXI_INDEX_FROM_MODEL(model)].name); - if(r0){ - errMessage(r0,NULL); - } - - r0 = epvxiRegisterMakeName(VXI_MAKE_LANSCE5, "LANL LANSCE-5"); - if(r0){ - errMessage(r0,NULL); - } - } - - return; -} - - -/* - * - * AT5VXI_INT_SERVICE - * - * update card busy writes and notify the IO interrupt scanner - */ -void at5vxi_int_service( - int addr -) -{ - struct at5vxi_config *pconfig; - at5VxiStatus r0; - - r0 = AT5VXI_PCONFIG(addr, pconfig); - if(r0){ - epicsPrintf("AT5VXI: int before init\n"); - return; - } - - /* - * wake up the I/O event scanner - */ - scanIoRequest(pconfig->ioscanpvt); - - /* - * Update outputs while it is safe to do so - */ - if(pconfig->mdt){ - struct at5vxi_dd *pdd; - struct vxi_csr *pcsr; - unsigned chan; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - for(chan=0; chantv); chan++){ - unsigned chip_chan; - - if(!pconfig->tv[chan].mdt) - continue; - - - if(chan/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - } - else{ - *PCONTROL(pcsr) = BANK0; - } - - chip_chan = chan% - AT5VXI_CHANNELS_PER_TIMER_BANK; - - r0 = stc_one_shot( - pconfig->tv[chan].preset, - pconfig->tv[chan].iedge0_delay, - pconfig->tv[chan].iedge1_delay, - &pdd->tcmd, - &pdd->tdata, - chip_chan, - FALSE); - if(r0 != STC_SUCCESS){ - epicsPrintf("AT5 VXI- AMD9513 load fail\n"); - } - else{ - pconfig->tv[chan].valid = TRUE; - } - - /* - * reenable interrupts - */ - *PCONTROL(pcsr) = CSRINIT; - - pconfig->tv[chan].mdt = FALSE; - } - - for(chan=0; chanav); chan++){ - if(!pconfig->av[chan].mdt) - continue; - pdd->ao[chan] = pconfig->av[chan].val; - pconfig->av[chan].mdt = FALSE; - } - - if(pconfig->bv.mask){ - uint32_t work; - - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | - pdd->bio[0]); - - /* alter specified bits */ - work = (work & ~pconfig->bv.mask) | - (pconfig->bv.val & pconfig->bv.mask); - - pdd->bio[0] = work; - pdd->bio[1] = work>>(NBBY*sizeof(uint16_t)); - - pconfig->bv.mask = 0; - } - - if(BUSY(pcsr)) - logMsg( "AT5 VXI INT- finished with card busy\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - - pconfig->mdt = FALSE; - } - -} - - - -/* - * - * AT5VXI_ONE_SHOT - * - * setup AMD 9513 STC for a repeated two edge timing signal - */ -at5VxiStatus at5vxi_one_shot( - unsigned preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - unsigned int_source, /* (FALSE)External/(TRUE)Internal source */ - void (*event_rtn)(void *pParam),/* subroutine to run on events */ - void *event_rtn_param /* parameter to pass to above routine */ -) -{ - at5VxiStatus status; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - status = AT5VXI_PCONFIG(card, pconfig); - if(status){ - return status; - } - - pcsr = pconfig->pcsr; - -/* AT5VXI does not support internal source for now -*/ if(int_source){ - status = S_dev_badRequest; - errMessage( - status, - "AT5VXI does not support internal trigger source"); - return status; - } - -/* AT5VXI does not support interrupts on timing channels for now -*/ if(event_rtn){ - status = S_dev_badRequest; - errMessage(status, "AT5VXI does not support interrupts on timing channels"); - return status; - } - - if(channel>=AT5VXI_NTIMER_CHANNELS) - return S_dev_badSignalNumber; - -/* dont overflow unsigned short in STC -*/ if(edge0_delay >= devCreateMask(NBBY*sizeof(uint16_t))/EXT_TICKS) - return S_dev_highValue; - if(edge1_delay >= devCreateMask(NBBY*sizeof(uint16_t))/EXT_TICKS) - return S_dev_highValue; - if(edge0_delay < 0.0) - return S_dev_lowValue; - if(edge1_delay < 0.0) - return S_dev_lowValue; - - FASTLOCK(&pconfig->lock); - -# ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - if(channel/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - }else{ - *PCONTROL(pcsr) = BANK0; - } - channel = channel%AT5VXI_CHANNELS_PER_TIMER_BANK; - - status = stc_one_shot( - preset, - (uint16_t) (edge0_delay * EXT_TICKS), - (uint16_t) (edge1_delay * EXT_TICKS), - &pdd->tcmd, - &pdd->tdata, - channel, - FALSE); - - /* - * not required for now but safe - * against future mods - */ - *PCONTROL(pcsr) = CSRINIT; - } -# else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->tv[channel].preset = preset; - pconfig->tv[channel].iedge0_delay = - (edge0_delay * EXT_TICKS); - pconfig->tv[channel].iedge1_delay = - (edge1_delay * EXT_TICKS); - pconfig->tv[channel].mdt = TRUE; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; - - status = STC_SUCCESS; -# endif - - FASTUNLOCK(&pconfig->lock); - - if(status!=STC_SUCCESS){ - return status; - } - - return VXI_SUCCESS; -} - - -/* - * - * AT5VXI_ONE_SHOT_READ - * - * read back two edge timing from an AMD 9513 STC - */ -at5VxiStatus at5vxi_one_shot_read( - unsigned *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - unsigned *int_source /* (FALSE)External/(TRUE)Internal src */ -) -{ -#ifdef CONTINUOUS_OPERATION - uint16_t iedge0; - uint16_t iedge1; -#endif - at5VxiStatus status; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - status = AT5VXI_PCONFIG(card, pconfig); - if(status) - return status; - - pcsr = pconfig->pcsr; - - if(channel>=AT5VXI_NTIMER_CHANNELS) - return S_dev_badSignalNumber; - - -# ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - FASTLOCK(&pconfig->lock); - - if(channel/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - }else{ - *PCONTROL(pcsr) = BANK0; - } - channel = channel%AT5VXI_CHANNELS_PER_TIMER_BANK; - status = stc_one_shot_read( - preset, - &iedge0, - &iedge1, - &pdd->tcmd, - &pdd->tdata, - channel, - int_source); - /* - * not required for noe but safe - * against future mods - */ - *PCONTROL(pcsr) = CSRINIT; - FASTUNLOCK(&pconfig->lock); - - if(status==STC_SUCCESS){ - /* - * AT5VXI does not support external - * source for now - */ - if(int_source) - return S_dev_badRequest; - - *edge0_delay = iedge0 / EXT_TICKS; - *edge1_delay = iedge1 / EXT_TICKS; - } - - - return status; - } -# else - if(!pconfig->tv[channel].valid) - return S_dev_badRequest; - - FASTLOCK(&pconfig->lock); - - *preset = pconfig->tv[channel].preset; - *edge0_delay = pconfig->tv[channel].iedge0_delay - /EXT_TICKS; - *edge1_delay = pconfig->tv[channel].iedge1_delay - /EXT_TICKS; - *int_source = FALSE; - - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -# endif -} - - - -/* - * - * AT5VXI_STAT - * - * print status for a single at5 vxi card - * - * - */ -void at5vxi_stat( - unsigned card, - int level -) -{ - struct vxi_csr *pcsr; - register struct at5vxi_dd *pdd; - struct at5vxi_status status; - unsigned channel; - at5VxiStatus r0; - struct at5vxi_config *pconfig; - - static char *busy_status[] = {"","busy"}; - static char *modid_status[] = {"modid-on",""}; - static char *ipend_status[] = {"","int-pending"}; - static char *ienable_status[] = {"int-disabled","int-enabled"}; - static char *ext_st_status[] = {"extended-self-testing",""}; - static char *st_status[] = {"self-testing",""}; - static char *sfinh_status[] = {"","sys-fail-inhibit"}; - static char *sreset_status[] = {"","sys-reset"}; - static char *addr_mode_status[] = {"SC","DC"}; - - if(level==0) - return; - - r0 = AT5VXI_PCONFIG(card, pconfig); - if(r0){ - errMessage(r0,NULL); - return; - } - - pcsr = VXIBASE(card); - pdd = pconfig->pdd; - - r0 = vxMemProbe( (char *)&pcsr->dir.r.status, - READ, - sizeof(status), - (char *)&status); - if(r0 != OK) - return; - - if(VXIMAKE(pcsr) != VXI_MAKE_LANSCE5) - return; - - if(AT5VXI_VALID_MODEL(VXIMODEL(pcsr))){ - printf( "\tDrawing: %s\n", - at5vxi_models[AT5VXI_INDEX_FROM_MODEL(VXIMODEL(pcsr))].drawing); - } - - printf( - "\tcard=%d address-mode=%s %s %s %s %s ilevel=%d %s %s %s %s\n", - card, - addr_mode_status[status.dev255], - busy_status[ status.busy ], - modid_status[ status.modid_cmpl ], - ipend_status[ status.ipend ], - ienable_status[ status.ienable ], - status.ilevel, - ext_st_status[ status.ready ], - st_status[ status.passed ], - sfinh_status[ status.sfinh ], - sreset_status[ status.sreset ]); - - if(pconfig){ - if(pconfig->mdt){ - printf("\toutput update is pending for interrupt\n"); - } - } - - if(level <= 1) - return; - - for(channel=0; channelai); channel++){ - printf( - "\tAI: channel %d value %x\n", - channel, - pdd->ai[channel]); - } - - for(channel=0; channelao); channel++){ - printf( - "\tAO: channel %d value %x\n", - channel, - pdd->ao[channel]); - } - - { - uint32_t work; - - work = ((uint32_t)pdd->bio[1]) << (sizeof(uint16_t)*NBBY); - work |= pdd->bio[0]; - printf("\tBIO: value %lx\n", (unsigned long) work); - } - - for(channel=0; channeltv); channel++){ - at5vxi_report_timing(card, channel); - } - - return; -} - - -/* - * - * - * AT5VXI_REPORT_TIMING - * - * diagnostic - */ -LOCAL -at5VxiStatus at5vxi_report_timing( - unsigned card, - unsigned channel -) -{ - unsigned preset; - double edge0_delay; - double edge1_delay; - unsigned int_source; - at5VxiStatus status; - char *clk_src[] = {"external-clk", "internal-clk"}; - - status = - at5vxi_one_shot_read( - &preset, - &edge0_delay, - &edge1_delay, - card, - channel, - &int_source); - if(status == VXI_SUCCESS) - printf( - "\tTI: channel %d preset %u delay %f width %f %s\n", - channel, - preset, - edge0_delay, - edge1_delay, - clk_src[int_source?1:0]); - - return status; -} - - -/* - * - * - * AT5VXI_AI_DRIVER - * - * analog input driver - */ -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -) -{ - at5VxiStatus s; - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ai)) - return S_dev_badSignalNumber; - - *prval = pdd->ai[chan]; - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_AO_DRIVER - * - * analog output driver - */ -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -) -{ - struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ao)) - return S_dev_badSignalNumber; - -#ifdef CONTINUOUS_OPERATION - pdd->ao[chan] = *prval; - *prbval = pdd->ao[chan]; -#else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->av[chan].val = *prval; - pconfig->av[chan].mdt = TRUE; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; - - *prbval = *prval; -#endif - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_AO_READ - * - * analog output read back - */ -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -) -{ - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s){ - return s; - } - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ao)) - return S_dev_badSignalNumber; - - *pval = pdd->ao[chan]; - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_BI_DRIVER - * - * binary input driver - */ -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -) -{ - register uint32_t work; - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - FASTLOCK(&pconfig->lock); - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | pdd->bio[0]); - *prval = mask & work; - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_BO_DRIVER - * - * binary output driver - */ -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -) -{ -#ifdef CONTINUOUS_OPERATION - register uint32_t work; -#endif - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - - FASTLOCK(&pconfig->lock); - -#ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | pdd->bio[0]); - - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - pdd->bio[0] = work; - pdd->bio[1] = work>>(NBBY*sizeof(uint16_t)); - } -#else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->bv.val = (pconfig->bv.val & ~mask) | (val & mask); - pconfig->bv.mask |= mask; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; -#endif - - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -} - - -/* - * - * at5vxi_getioscanpvt() - * - * - */ -at5VxiStatus at5vxi_getioscanpvt( -unsigned card, -IOSCANPVT *scanpvt -) -{ - struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s == VXI_SUCCESS){ - *scanpvt = pconfig->ioscanpvt; - } - return s; -} - diff --git a/src/vxWorks/drv/ansi/drvAt5Vxi.h b/src/vxWorks/drv/ansi/drvAt5Vxi.h deleted file mode 100644 index ab3b5f546..000000000 --- a/src/vxWorks/drv/ansi/drvAt5Vxi.h +++ /dev/null @@ -1,94 +0,0 @@ -/* base/src/drv $Id$ */ - -/* - * - * driver for at5 designed VXI modules - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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 - -typedef long at5VxiStatus; - -at5VxiStatus at5vxi_one_shot( - unsigned preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - unsigned int_source, /* (FALSE)External/(TRUE)Internal source */ - void (*event_rtn)(void *pParam), /* subroutine to run on events */ - void *event_rtn_param/* parameter to pass to above routine */ -); - -at5VxiStatus at5vxi_one_shot_read( - unsigned *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - unsigned *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -); - -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -); - -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -); - -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -); - -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -); - -at5VxiStatus at5vxi_getioscanpvt( - unsigned card, - IOSCANPVT *scanpvt -); - diff --git a/src/vxWorks/drv/ansi/drvHp1404a.c b/src/vxWorks/drv/ansi/drvHp1404a.c deleted file mode 100644 index c3f04d271..000000000 --- a/src/vxWorks/drv/ansi/drvHp1404a.c +++ /dev/null @@ -1,414 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * - * HP E1404A VXI bus slot zero translator - * device dependent routines - * - * share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93 - * - * Author Jeffrey O. Hill - * Date 030692 - * - * 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 joh 073092 Added msg device support & interrupt shutdown for - * soft reboots - * .02 joh 082792 converted to ANSI C - * .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals - * - * - * - */ - -static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93"; - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include - -LOCAL unsigned long hpE1404DriverID; - -struct hpE1404_config{ - void (*pSignalCallback)(int16_t signal); -}; - -#define TLTRIG(N) (1<<(N)) -#define ECLTRIG(N) (1<<((N)+8)) - -/* - * enable int when signal register is written - */ -#define HP1404A_INT_ENABLE 0x0008 -#define HP1404A_INT_DISABLE 0x0000 - -/* - * - * tag the device dependent registers - */ -#define IRQ_enable dir.w.dd.reg.ddx1a -#define MSG_status dir.w.dd.reg.ddx1e -#define fp_trig_drive dir.w.dd.reg.ddx2a -#define bp_trig_drive dir.w.dd.reg.ddx22 -#define signal_read dir.r.dd.reg.ddx10 - -#define hpE1404PConfig(LA, PC) \ - epvxiFetchPConfig((LA), hpE1404DriverID, (PC)) - -LOCAL void hpE1404InitLA( - unsigned la, - void *pArg -); - -LOCAL int hpE1404ShutDown( - void -); - -LOCAL void hpE1404ShutDownLA( - unsigned la, - void *pArg -); - -LOCAL void hpE1404IOReport( -unsigned la, -unsigned level -); - -LOCAL void hpE1404Int( -unsigned la -); - - - -/* - * - * hpE1404Init - * - */ -hpE1404Stat hpE1404Init(void) -{ - hpE1404Stat status; - - status = rebootHookAdd(hpE1404ShutDown); - if(status<0){ - status = S_dev_internal; - errMessage(status, "rebootHookAdd() failed"); - return status; - } - - hpE1404DriverID = epvxiUniqueDriverID(); - - status = epvxiRegisterMakeName( - VXI_MAKE_HP, - "Hewlett-Packard"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_REG_SLOT0, - "Slot Zero Translator (reg)"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_REG, - "Translator (reg)"); - if(status){ - errMessage(status, NULL); - } - status = epvxiRegisterModelName( - VXI_MAKE_HP, - VXI_HP_MODEL_E1404_MSG, - "Translator (msg)"); - if(status){ - errMessage(status, NULL); - } - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0; - status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return status; - } - - dsp.model = VXI_HP_MODEL_E1404_REG; - status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return status; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404ShutDown() - * - * - */ -LOCAL int hpE1404ShutDown(void) -{ - hpE1404Stat status; - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0; - status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return ERROR; - } - - dsp.model = VXI_HP_MODEL_E1404_REG; - status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL); - if(status){ - errMessage(status, NULL); - return ERROR; - } - return OK; -} - - -/* - * - * hpE1404ShutDownLA() - * - * - */ -LOCAL -void hpE1404ShutDownLA( - unsigned la, - void *pArg -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->IRQ_enable = HP1404A_INT_DISABLE; -} - - -/* - * - * hpE1404InitLA() - * - */ -LOCAL -void hpE1404InitLA( - unsigned la, - void *pArg -) -{ - struct hpE1404_config *pc; - struct vxi_csr *pcsr; - hpE1404Stat status; - - status = epvxiOpen( - la, - hpE1404DriverID, - sizeof(*pc), - hpE1404IOReport); - if(status){ - errMessage(status, NULL); - return; - } - - pcsr = VXIBASE(la); - - status = hpE1404PConfig(la, pc); - if(status){ - errMessage(status, NULL); - epvxiClose(la, hpE1404DriverID); - return; - } - - /* - * set the self test status to passed for - * the message based device - */ - pcsr->MSG_status = VXIPASS<<2; - - intConnect( - INUM_TO_IVEC(la), - hpE1404Int, - la); - - /* - * enable int when signal register is written - */ - pcsr->IRQ_enable = HP1404A_INT_ENABLE; - - return; -} - - -/* - * - * hpE1404SignalConnect() - * - */ -hpE1404Stat hpE1404SignalConnect( -unsigned la, -void (*pSignalCallback)(int16_t signal) -) -{ - hpE1404Stat s; - struct hpE1404_config *pc; - - s = hpE1404PConfig(la, pc); - if(s){ - return s; - } - - pc->pSignalCallback = pSignalCallback; - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404Int() - * - */ -LOCAL -void hpE1404Int( - unsigned la -) -{ - hpE1404Stat s; - struct vxi_csr *pcsr; - unsigned short signal; - struct hpE1404_config *pc; - - s = hpE1404PConfig(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - - /* - * vector is only D8 so we cant check the cause of the int - * (signal cause is assumed since that was all that was enabled) - */ - - pcsr = VXIBASE(la); - - signal = pcsr->signal_read; - - if(pc->pSignalCallback){ - (*pc->pSignalCallback)(signal); - } -} - - -/* - * - * hpE1404RouteTriggerECL - * - */ -hpE1404Stat hpE1404RouteTriggerECL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->fp_trig_drive = (io_map&enable_map)<<8; - pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8; - - return VXI_SUCCESS; -} - - -/* - * - * - * hpE1404RouteTriggerTTL - * - * - */ -hpE1404Stat hpE1404RouteTriggerTTL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->fp_trig_drive = io_map&enable_map; - pcsr->bp_trig_drive = (~io_map)&enable_map; - - return VXI_SUCCESS; -} - - -/* - * - * hpE1404IOReport() - * - * - */ -LOCAL -void hpE1404IOReport( - unsigned la, - unsigned level -) -{ - - - - -} diff --git a/src/vxWorks/drv/ansi/drvHp1404a.h b/src/vxWorks/drv/ansi/drvHp1404a.h deleted file mode 100644 index f6f6d2bfb..000000000 --- a/src/vxWorks/drv/ansi/drvHp1404a.h +++ /dev/null @@ -1,74 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * drvHp1404a.h - * - * HP E1404A VXI bus slot zero translator - * device dependent routines header file - * - * share/src/drv/@(#)drvHp1404a.h 1.1 8/27/93 - * - * Author Jeffrey O. Hill - * Date 030692 - * - * 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: - * ----------------- - * - * - * - */ - -typedef long hpE1404Stat; - -hpE1404Stat hpE1404Init(void); - -hpE1404Stat hpE1404SignalConnect( - unsigned la, - void (*pSignalCallback)(int16_t signal) -); - -hpE1404Stat hpE1404RouteTriggerECL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -); - -hpE1404Stat hpE1404RouteTriggerTTL( -unsigned la, /* slot zero device logical address */ -unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */ - /* a 1 enables a trigger */ - /* a 0 disables a trigger */ -unsigned io_map /* bits 0-5 correspond to trig 0-5 */ - /* a 1 sources the front panel */ - /* a 0 sources the back plane */ -); - -#define VXI_HP_MODEL_E1404_REG_SLOT0 0x10 -#define VXI_HP_MODEL_E1404_REG 0x110 -#define VXI_HP_MODEL_E1404_MSG 0x111 - - diff --git a/src/vxWorks/drv/ansi/drvHpe1368a.c b/src/vxWorks/drv/ansi/drvHpe1368a.c deleted file mode 100644 index 4b1db74ff..000000000 --- a/src/vxWorks/drv/ansi/drvHpe1368a.c +++ /dev/null @@ -1,361 +0,0 @@ -/* drvHpe1368a.c*/ -/* base/src/drv $Id$ */ - -/* - * hpe1368a_driver.c - * - * driver for hpe1368a and hpe1369a microwave switch VXI modules - * - * Author: Jeff Hill - * Date: 052192 - * - * 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 071792 joh Added model name registration - * .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID - * .03 082692 mrk Added support for new I/O event scanning and DRVET - * .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - * - */ - -static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93"; - -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define HPE1368A_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), hpe1368aDriverId, (PC)) - -#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08) -#define ModuleStatus(PCSR) ((PCSR)->dir.r.status) - -#define ALL_SWITCHES_OPEN 0 - -struct hpe1368a_config{ - FAST_LOCK lock; /* mutual exclusion */ - uint16_t pending; /* switch position pending int */ - uint16_t shadow; /* shadow of actual switch pos */ - int busy; /* relays active */ - IOSCANPVT ioscanpvt; -}; - -#define HPE1368A_INT_LEVEL 1 - -LOCAL int hpe1368aDriverId; - -LOCAL void hpe1368a_int_service(unsigned la); -LOCAL void hpe1368a_init_card(unsigned la, void *pArg); -LOCAL void hpe1368a_stat(unsigned la, int level); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvHpe1368a={ - 2, - NULL, /*VXI io report takes care of this */ - hpe1368a_init}; - - -/* - * hpe1368a_init - * - * initialize all hpe1368a cards - * - */ -hpe1368aStat hpe1368a_init(void) -{ - hpe1368aStat r0; - - /* - * do nothing on crates without VXI - */ - if(!epvxiResourceMangerOK){ - return VXI_SUCCESS; - } - - hpe1368aDriverId = epvxiUniqueDriverID(); - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_MODEL_HPE1368A; - r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL); - if(r0){ - errMessage(r0, NULL); - return r0; - } - } - - return VXI_SUCCESS; -} - - - -/* - * HPE1368A_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL void hpe1368a_init_card(unsigned la, void *pArg) -{ - hpe1368aStat r0; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - int model; - - r0 = epvxiOpen( - la, - hpe1368aDriverId, - (unsigned long) sizeof(*pc), - hpe1368a_stat); - if(r0){ - errMessage(r0,NULL); - return; - } - - r0 = HPE1368A_PCONFIG(la, pc); - if(r0){ - errMessage(r0, NULL); - return; - } - - pcsr = VXIBASE(la); - - /* - * we must reset the device to a known state since - * we cant read back the current state - */ - pc->pending = ALL_SWITCHES_OPEN; - pc->shadow = ALL_SWITCHES_OPEN; - ChannelEnable(pcsr) = ALL_SWITCHES_OPEN; - - FASTLOCKINIT(&pc->lock); - scanIoInit(&pc->ioscanpvt); - - r0 = intConnect( - INUM_TO_IVEC(la), - hpe1368a_int_service, - la); - if(r0 == ERROR){ - errMessage(S_dev_vxWorksVecInstlFail, NULL); - return; - } - - sysIntEnable(HPE1368A_INT_LEVEL); - - model = VXIMODEL(pcsr); - r0 = epvxiRegisterModelName( - VXIMAKE(pcsr), - model, - "E 1368A Microwave Switch\n"); - if(r0){ - errMessage(r0, NULL); - } - r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard"); - if(r0){ - errMessage(r0,NULL); - } -} - - -/* - * - * hpe1368a_int_service() - * - * - * This device interrupts once the - * switches have settled - * - */ -LOCAL void -hpe1368a_int_service(unsigned la) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la,pc); - if(s){ - return; - } - - /* - * operation completed so we can update - * the shadow value - */ - pc->shadow = pc->pending; - pc->busy = FALSE; - - /* - * tell them that the switches have settled - */ - scanIoRequest(pc->ioscanpvt); -} - - -/* - * HPE1368A_STAT - * - * initialize single at5vxi card - * - */ -LOCAL void hpe1368a_stat( -unsigned la, -int level -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return; - } - pcsr = VXIBASE(la); - - if(level>0){ - printf("\tSwitch states %x\n", pc->shadow); - printf("\tModule status %x\n", pcsr->dir.r.status); - if(pc->busy){ - printf("\tModule is busy.\n"); - } - } -} - - -/* - * hpe1368a_getioscanpvt() - */ -hpe1368aStat hpe1368a_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - *scanpvt = pc->ioscanpvt; - return VXI_SUCCESS; -} - - -/* - * HPE1368A_BO_DRIVER - */ -hpe1368aStat hpe1368a_bo_driver( -unsigned la, -unsigned val, -unsigned mask -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - unsigned int work; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pc->lock); - - work = pc->pending; - - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - pc->pending = work; - - ChannelEnable(pcsr) = work; - - FASTUNLOCK(&pc->lock); - - return VXI_SUCCESS; -} - - - -/* - * - * HPE1368A_BI_DRIVER - * - * - * - */ -hpe1368aStat hpe1368a_bi_driver( -unsigned la, -unsigned mask, -unsigned *pval -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - FASTLOCK(&pc->lock); - - *pval = pc->shadow & mask; - - FASTUNLOCK(&pc->lock); - - return VXI_SUCCESS; -} diff --git a/src/vxWorks/drv/ansi/drvHpe1368a.h b/src/vxWorks/drv/ansi/drvHpe1368a.h deleted file mode 100644 index 6e7688555..000000000 --- a/src/vxWorks/drv/ansi/drvHpe1368a.h +++ /dev/null @@ -1,60 +0,0 @@ -/* drvHpe1368a.h*/ -/* base/src/drv $Id$ */ - -/* - * hpe1368a_driver.h - * - * driver for hpe1368a and hpe1369a microwave switch VXI modules - * - * Author: Jeff Hill - * Date: 052192 - * - * 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: - * ----------------- - * - */ - -#define VXI_MODEL_HPE1368A (0xf28) - -typedef long hpe1368aStat; - -hpe1368aStat hpe1368a_init(void); - -hpe1368aStat hpe1368a_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -); - -hpe1368aStat hpe1368a_bo_driver( -unsigned la, -unsigned val, -unsigned mask -); - -hpe1368aStat hpe1368a_bi_driver( -unsigned la, -unsigned mask, -unsigned *pval -); - diff --git a/src/vxWorks/drv/ansi/drvHpe1445a.c b/src/vxWorks/drv/ansi/drvHpe1445a.c deleted file mode 100644 index 58ec441e9..000000000 --- a/src/vxWorks/drv/ansi/drvHpe1445a.c +++ /dev/null @@ -1,1188 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * driver for hpe1445a arbitrary function generator VXI modules - * - * Author: Jeff Hill - * Date: 082492 - * - * 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 021192 joh Fixed hpe1445aUnloadWaveformLocked() ANSI C - * function prototype missmatch. Changed - * unsigned short to unsigned. - * - * - */ - -static char *sccsId = "@(#)drvHpe1445a.c 1.5\t8/27/93"; - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include -#include - -/* - * comment out this line if you prefer - * to use backplane ttl trigger 0 - */ -#define FRONT_PANEL_TRIGGER - -#define VXI_MODEL_HPE1445A (418) - -LOCAL int hpe1445aDriverId; - -#define HPE1445A_MAX_POINTS 0x40000 -#define HPE1445A_MIN_POINTS 4 - -#define HPE1445_DATA_PORT_OFFSET (0x26) - -struct hpe1445aConfig { - FAST_LOCK lck; - char device_active; - double dacPeakAmplitude; - double dacOffset; - char buf[256]; -}; - -#define HPE1445A_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), hpe1445aDriverId, (PC)) - -typedef long hpe1445aStat; - -/* - * - * For External Use - * - */ -hpe1445aStat hpe1445aInit(void); -hpe1445aStat hpe1445aSetupDAC(unsigned la, double dacPeakAmplitude, double dacOffset); -hpe1445aStat hpe1445aSetupFreq(unsigned la, char *pFreqString); -void hpe1445aIoReport(unsigned la, int level); -hpe1445aStat hpe1445aLoadWaveform(unsigned la, char *pWaveformName, - double *pdata, unsigned long npoints); -hpe1445aStat hpe1445aUnloadWaveform(unsigned la, char *pWaveformName); -hpe1445aStat hpe1445aActivateWaveform(unsigned la, char *pWaveformName); -hpe1445aStat hpe1445aTest(unsigned la); -hpe1445aStat hpe1445aWriteWithLineno(unsigned la, char *pmsg, unsigned lineno); -void hpe1445aLogErrorsWithLineno(unsigned la, int lineno); - - -/* - * - * For Driver Internal Use - * - */ -LOCAL void hpe1445aInitCard(unsigned la, void *pArg); -LOCAL hpe1445aStat hpe1445aReset(unsigned la); -LOCAL hpe1445aStat logEntireError(unsigned la, int lineno); -LOCAL hpe1445aStat hpe1445aActivateWaveformLocked(unsigned la, char *pWaveformName, - struct hpe1445aConfig *pc); -LOCAL hpe1445aStat hpe1445aSetupFunction(unsigned la); -LOCAL hpe1445aStat hpe1445aSetupOutput(unsigned la); -LOCAL hpe1445aStat hpe1445aArm(unsigned la); -LOCAL hpe1445aStat hpe1445aUnloadWaveformLocked(unsigned la, char *pWaveformName); -LOCAL hpe1445aStat hpe1445aLoadWaveformLocked(unsigned la, - struct hpe1445aConfig *pc, - char *pWaveformName, double *pdata, - unsigned long npoints); - - -#define logErrors(LA) hpe1445aLogErrorsWithLineno(LA, __LINE__) -#define hpe1445aWrite(LA, PMSG) hpe1445aWriteWithLineno(LA, PMSG, __LINE__) - -#define HPE1445A_MAX_NAME_LENGTH 12 -#define SEGMENT_NAME_PREFIX "e_" -#define SEQUENCE_NAME_PREFIX "e__" -#define PREFIX_MAX_NAME_LENGTH 3 -#define MAX_NAME_LENGTH (HPE1445A_MAX_NAME_LENGTH-PREFIX_MAX_NAME_LENGTH) - -#define TEST_FILE_NAME "hpe1445a.dat" - - -/* - * - * hpe1445aTest() - * - * - */ -hpe1445aStat hpe1445aTest(unsigned la) -{ - hpe1445aStat s; - FILE *pf; - char *pfn = TEST_FILE_NAME; - double *pwaveform; - int nsamples; - int i; - - pf = fopen(pfn, "r"); - if(!pf){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "file access problems %s", - pfn); - fclose(pf); - return s; - } - s = fscanf(pf, "%d", &nsamples); - if(s!=1){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "no element count in the file %s", - pfn); - fclose(pf); - return s; - } - - pwaveform = (double *) calloc(nsamples, sizeof(double)); - if(!pwaveform){ - s = S_dev_noMemory; - errPrintf( - s, - __FILE__, - __LINE__, - "specified sample count to large %s", - pfn); - fclose(pf); - return s; - } - - for(i=0; ibuf, - sizeof(pc->buf), - &read_count, - 0); - if(s!=S_epvxi_bufferFull && s!=VXI_SUCCESS){ - errPrintf( - s, - __FILE__, - lineno, - "error fetch problem at LA=0X%X", - la); - return s; - } - nreads++; - /* - * return of zero indicates no errors - * this will always be a very short message - */ - if(nreads==1){ - int val; - int n; - - n = sscanf(pc->buf,"%d",&val); - if(n==1){ - if(val==0){ - return S_epvxi_internal; - } - } - } - errPrintf( - S_epvxi_msgDeviceStatus, - __FILE__, - lineno, - "LA=0X%X: Error => %s", - la, - pc->buf); - - if(s==VXI_SUCCESS){ - break; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aReset() - * - * - */ -LOCAL -hpe1445aStat hpe1445aReset(unsigned la) -{ - hpe1445aStat s; - - s = hpe1445aWrite(la, "*RST"); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list1:ssequence:delete:all"); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list1:segment:delete:all"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupFreq() - * - * - */ -hpe1445aStat hpe1445aSetupFreq(unsigned la, char *pFreqString) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return s; - } - - /* - * - * Set the sample rate - * - */ - sprintf(pc->buf, "source:frequency:fixed %s", pFreqString); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupFunction() - * - * - */ -LOCAL -hpe1445aStat hpe1445aSetupFunction(unsigned la) -{ - hpe1445aStat s; - - /* - * - * set the function to arbitrary waveform - * - */ - s = hpe1445aWrite(la, "source:function:shape user"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupOutput() - * - * - */ -LOCAL -hpe1445aStat hpe1445aSetupOutput(unsigned la) -{ - hpe1445aStat s; - - - /* - * set the output impedance - * (50 Ohm coax assumed) - * - */ - s = hpe1445aWrite(la, "output:impedance 50 Ohm"); - if(s){ - return s; - } - - /* - * - * disable output low pass filter - * (freq would need to be set if it were turned on) - * - */ - s = hpe1445aWrite(la, "output:filter:lpass:state off"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * hpe1445aArm() - * - */ -hpe1445aStat hpe1445aArm(unsigned la) -{ - hpe1445aStat s; - - /* - * - * initiate waveform output off the external trigger input - * - */ -#ifdef FRONT_PANEL_TRIGGER - s = hpe1445aWrite(la, "arm:start:layer2:source external"); -#else - s = hpe1445aWrite(la, "arm:start:layer2:source ttltrg0"); -#endif - if(s){ - return s; - } - - /* - * - * initiate waveform output on the rising edge - * - */ - s = hpe1445aWrite(la, "arm:start:layer2:slope positive"); - if(s){ - return s; - } - - /* - * - * output the waveform once only after receiving - * a trigger - * - */ - s = hpe1445aWrite(la, "arm:start:layer1:count 1"); - if(s){ - return s; - } - - /* - * - * output the waveform after each trigger edge - * forever - * - */ - s = hpe1445aWrite(la, "arm:start:layer2:count infinity"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * - * hpe1445aSetupDAC - * - * - * - */ -hpe1445aStat hpe1445aSetupDAC( -unsigned la, -double dacPeakAmplitude, -double dacOffset) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la,pc); - if(s){ - errMessage(s,NULL); - return s; - } - - sprintf(pc->buf, - "source:voltage:level:immediate:amplitude %f V", - dacPeakAmplitude); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - pc->dacPeakAmplitude = dacPeakAmplitude; - - sprintf(pc->buf, - "source:voltage:level:immediate:offset %f V", - dacOffset); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - pc->dacOffset = dacOffset; - - logErrors(la); - - return VXI_SUCCESS; -} - - - -/* - * - * hpe1445aActivateWaveform() - * - * - * - */ -hpe1445aStat hpe1445aActivateWaveform( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return s; - } - - FASTLOCK(&pc->lck); - - s = hpe1445aActivateWaveformLocked(la, pWaveformName, pc); - - FASTUNLOCK(&pc->lck); - - return s; -} - - -/* - * - * hpe1445aActivateWaveformLocked() - * - * - * - */ -LOCAL hpe1445aStat -hpe1445aActivateWaveformLocked( -unsigned la, -char *pWaveformName, -struct hpe1445aConfig *pc -) -{ - int s; - - if(pc->device_active){ - s = hpe1445aWrite(la, "abort"); - if(s){ - return s; - } - pc->device_active = FALSE; - } - - /* - * - * select active sequence - * - */ - sprintf( pc->buf, - "source:function:user %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * - * initiate the trigger system - * - */ - s = hpe1445aWrite(la, "initiate:immediate"); - if(s){ - return s; - } - pc->device_active = TRUE; - - logErrors(la); - - return VXI_SUCCESS; -} - - - -/* - * - * hpe1445aUnloadWaveform() - * - * - * - */ -hpe1445aStat hpe1445aUnloadWaveform( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - FASTLOCK(&pc->lck); - - s = hpe1445aUnloadWaveformLocked(la, pWaveformName); - - FASTUNLOCK(&pc->lck); - - logErrors(la); - - return s; -} - - -/* - * - * hpe1445aUnloadWaveformLocked() - * - * - * - */ -LOCAL hpe1445aStat hpe1445aUnloadWaveformLocked( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - sprintf( - pc->buf, - "source:list:ssequence:select %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list:ssequence:delete:selected"); - if(s){ - return s; - } - - sprintf( - pc->buf, - "source:list:segment:select %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list:segment:delete:selected"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - - -/* - * hpe1445aLoadWaveform() - */ -hpe1445aStat -hpe1445aLoadWaveform( -unsigned la, -char *pWaveformName, -double *pdata, -unsigned long npoints -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - if(strlen(pWaveformName)>MAX_NAME_LENGTH){ - s = S_dev_highValue; - errMessage(s, "waveform element name to long"); - return s; - } - - if(npointslck); - - s = hpe1445aLoadWaveformLocked(la, pc, pWaveformName, pdata, npoints); - - FASTUNLOCK(&pc->lck); - - return s; -} - - -/* - * - * hpe1445aLoadWaveformLocked() - * - * - */ -LOCAL hpe1445aStat hpe1445aLoadWaveformLocked( -unsigned la, -struct hpe1445aConfig *pc, -char *pWaveformName, -double *pdata, -unsigned long npoints -) -{ - unsigned long read_count; - hpe1445aStat s; - - s = hpe1445aWrite(la, "source:list:segment:free?"); - if(s){ - return s; - } - s = epvxiRead( - la, - pc->buf, - sizeof(pc->buf), - &read_count, - 0); - if(s){ - errMessage(s, "\"source:list:segment:free?\" query failed"); - return s; - } - - { - int nfree; - int nused; - - s = sscanf(pc->buf, "%d,%d", &nfree, &nused); - if(s!=2){ - s = S_dev_internal; - errMessage(s, "bad \"source:list:segment:free?\" resp"); - return s; - } - if(nfree < npoints){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "%d waveform elements available", - nfree); - errPrintf( - s, - __FILE__, - __LINE__, - "%d element waveform rejected", - npoints); - return s; - } - } - - - /* - * - * select the segment for subsequent - * commands - * - */ - sprintf( - pc->buf, - "source:list:segment:select %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - sprintf(pc->buf, "source:list:segment:define %lu", npoints); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - sprintf( pc->buf, - "source:arbitrary:download VXI,%s%s,%lu", - SEGMENT_NAME_PREFIX, - pWaveformName, - npoints); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * wait for the device to finish with the download - * command prior to the backplane download - */ - s = hpe1445aWrite(la, "*OPC?"); - if(s){ - return s; - } - s = epvxiRead( - la, - pc->buf, - sizeof(pc->buf), - &read_count, - 0); - if(s){ - errMessage(s,"\"*OPC?\" query failed"); - return s; - } - - { - double truncationOffset; - double dacPeakAmplitude; - double dacOffset; - double *pwf; - uint16_t *pdata_port; - - pdata_port = (unsigned short *) epvxiA24Base(la); - pdata_port += (HPE1445_DATA_PORT_OFFSET/sizeof(*pdata_port)); - dacPeakAmplitude = pc->dacPeakAmplitude; - dacOffset = pc->dacOffset; - truncationOffset = dacPeakAmplitude/(4095*2); - for(pwf=pdata; pwf < &pdata[npoints]; pwf++){ - short idata; - double fdata; - - /* - * extra step here preserves precision - */ - fdata = (*pwf-dacOffset)*4095; - fdata = fdata/dacPeakAmplitude; - /* - * This offset causes round up to occur and - * not truncation - */ - fdata += truncationOffset; - idata = (short) fdata; - idata = idata << 3; - - if(pwf == &pdata[npoints-4]){ -# define LAST_POINT 1 - idata |= LAST_POINT; - } - - /* - * load the waveform element into the 1445 - */ - *pdata_port = idata; - } - } - - s = hpe1445aWrite(la, "source:arbitrary:download:complete"); - if(s){ - return s; - } - - /* - * - * install this segment into the sequence - * - */ - sprintf( pc->buf, - "source:list:ssequence:select %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * set the number of segments in this sequence - */ - s = hpe1445aWrite(la, "source:list:ssequence:define 1"); - if(s){ - return s; - } - sprintf(pc->buf, - "source:list:ssequence:sequence %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - s = hpe1445aWrite(la, "source:list:ssequence:dwell:count 1"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aWriteWithLineno() - * - */ -hpe1445aStat hpe1445aWriteWithLineno( - unsigned la, - char *pmsg, - unsigned lineno -) -{ - unsigned long nactual; - hpe1445aStat s; - - s = epvxiWrite( - la, - pmsg, - strlen(pmsg), - &nactual, - 0); - if(s){ - errPrintf( - s, - __FILE__, - lineno, - "LA=0X%02X MSG=%s", - la, - pmsg); - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aIoReport() - * - * - */ -void hpe1445aIoReport(unsigned la, int level) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - char *pStateName[] = {"in",""}; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - - if(level>0){ - printf("\tdevice %sactive, DAC peak = %f V, DAC offset = %f V\n", - pStateName[(unsigned)pc->device_active], - pc->dacPeakAmplitude, - pc->dacOffset); - } -} diff --git a/src/vxWorks/drv/ansi/drvStc.c b/src/vxWorks/drv/ansi/drvStc.c deleted file mode 100644 index 45b779cde..000000000 --- a/src/vxWorks/drv/ansi/drvStc.c +++ /dev/null @@ -1,316 +0,0 @@ -/* drvStc.c */ -/* base/src/drv $Id$ */ -/* - * The following are specific driver routines for the AMD STC - * - * NOTE: if multiple threads use these routines at once you must provide locking - * so command/data sequences are gauranteed. See mz8310_driver.c for examples. - * - * - * Author: Jeff Hill - * Date: Feb 89 - * - * 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: - * ----------------- - * - * joh 022089 Init Release - * joh 042889 Added read back - * joh 111789 Fixed reset goes to byte mode bug - * joh 121090 Fixed confusion about the polarity of internal/external - * clock between DB and the drivers. - * joh 110791 Prevent the stc from generating tc prior to the trigger - * in delayed pulse mode by forcing edge 0 delays of zero to be - * a delay of one instead. - * joh 010491 force all edge 0 delays less than two to two - * joh 082493 ANSI C and EPICS return codes - */ - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include -#include - - - -/* - * stc_io_report() - */ -stcStat stc_io_report( -volatile uint8_t *pcmd, -volatile uint16_t *pdata -) -{ - uint8_t cmd; - uint16_t data; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - - /* - * addd AMD STC status here - */ - - return STC_SUCCESS; -} - - - -/* - * stc_init() - */ -stcStat stc_init( -volatile uint8_t *pcmd, -volatile uint16_t *pdata, -unsigned master_mode -) -{ - uint8_t cmd; - uint16_t data; - unsigned channel; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - - /* - * go to 16 bit mode in order to test the master mode register - */ - STC_BUS16; - if(master_mode != STC_MASTER_MODE){ - - /* - * start in a known state - */ - STC_RESET; - - /* - * required since the reset puts it in byte mode - */ - STC_BUS16; - STC_SET_MASTER_MODE(master_mode); - for(channel=0; channel=CHANONCHIP) - return S_dev_badSignalNumber; - - STC_CTR_READ(mode, edge0, edge1); - - /* - * Only return values if the counter is in the proper mode - * see stc_one_shot() for info on conversions and functions selected - * by these bit fields - */ - if(mode == 0xc16a){ - *int_source = FALSE; - *preset = TRUE; - *edge0_count = ~edge0; - *edge1_count = ~edge1+1; - } - else if(mode == 0xc162){ - *int_source = FALSE; - *preset = FALSE; - *edge0_count = edge0-1; - *edge1_count = edge1; - } - else if(mode == 0xcb6a){ - *int_source = TRUE; - *preset = TRUE; - *edge0_count = ~edge0; - *edge1_count = ~edge1+1; - } - else if(mode == 0xcb62){ - *int_source = TRUE; - *preset = FALSE; - *edge0_count = edge0-1; - *edge1_count = edge1; - } - else - return S_dev_internal; - - return STC_SUCCESS; -} - - - -/* - * stc_one_shot() - */ -stcStat stc_one_shot( -unsigned preset, -unsigned edge0_count, -unsigned edge1_count, -volatile uint8_t *pcmd, -volatile uint16_t *pdata, -unsigned channel, -unsigned int_source -) -{ - uint8_t cmd; - uint16_t data; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - if(channel>=CHANONCHIP) - return S_dev_badSignalNumber; - - /* - * joh 110791 - * Prevent the stc from generating tc prior to the trigger - * in delayed pulse mode by forcing edge 0 delays of zero to be - * a delay of one instead. - * - * 010492 - * Strange extra edges occur when the delay is 0 or 1 - * and the counter is reinitialized to a width of - * zero so I have disabled a delay of one also - * - * These extra edges occur when TC is set - */ - - if(edge0_count < 2) - edge0_count = 2; - - STC_DISARM; - - /* - * active positive going edge (gate input) - * count on the rising edge of source - * ctr source: (F1- internal) (SRC1- external) - * mode L - Hardware triggered delayed pulse one-shot - * binary count - * count down (count up if preset is TRUE) - * TC toggled output - * - * see chapter 7 of the Am9513 STC tech man concerning count + 1 - * - */ - - /* - * NOTE: I must be able to read back the state of the preset later - * so I encode this information in the count down/up bit. - * count up on TRUE preset - * count down on FALSE preset - * - * see stc_one_shot_read() above - */ - if(int_source){ - if(preset) - STC_CTR_INIT(0xcb6a, ~edge0_count, ~edge1_count+1) - else - STC_CTR_INIT(0xcb62, edge0_count+1, edge1_count); - }else{ - if(preset) - STC_CTR_INIT(0xc16a, ~edge0_count, ~edge1_count+1) - else - STC_CTR_INIT(0xc162, edge0_count+1, edge1_count); - } - - STC_LOAD; - /* - *see chapter 7 of the Am9513 STC tech man concerning this step - */ - - STC_STEP; - - STC_SET_TC(preset); - - /* - * Only arm counter if the pulse has a finite duration - */ - if(edge1_count != 0){ - STC_ARM; - } - - return STC_SUCCESS; -} - -/* - * stcWriteData() - */ -void stcWriteData(volatile uint16_t *pdata, uint16_t data) -{ - *pdata = data; -} - -/* - * stcReadData() - */ -uint16_t stcReadData(volatile uint16_t *pdata) -{ - uint16_t data; - data = *pdata; - return data; -} - -/* - * stcWriteCmd() - */ -void stcWriteCmd(volatile uint8_t *pcmd, uint8_t cmd) -{ - *pcmd = cmd; -} - diff --git a/src/vxWorks/drv/ansi/drvStc.h b/src/vxWorks/drv/ansi/drvStc.h deleted file mode 100644 index a0cccacef..000000000 --- a/src/vxWorks/drv/ansi/drvStc.h +++ /dev/null @@ -1,116 +0,0 @@ -/* drvStc.h */ -/* base/src/drv $Id$ */ -/* - * The following are specific driver routines for the AMD STC - * - * NOTE: if multiple threads use these routines at once you must provide locking - * so command/data sequences are gauranteed. See mz8310_driver.c for examples. - * - * - * Author: Jeff Hill - * Date: Feb 89 - * - * 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: - * ----------------- - * - * joh 022089 Init Release - * joh 082493 ANSI C and EPICS return codes - */ - -/* - * AMD STC constants - */ -#define CHANONCHIP 5U -#define CHIPCHAN (channel%CHANONCHIP) -#define CHIPNUM (channel/CHANONCHIP) - -#define STC_RESET stcWriteCmd(pcmd,0xffU); -#define STC_BUS16 stcWriteCmd(pcmd,0xefU); -#define STC_BUS16 stcWriteCmd(pcmd,0xefU); -#define STC_SET_MASTER_MODE(D) {stcWriteCmd(pcmd,0x17U); \ - stcWriteData(pdata,(D));} -#define STC_MASTER_MODE (stcWriteCmd(pcmd,0x17U), stcReadData(pdata)) - -#define STC_CTR_INIT(MODE,LOAD,HOLD)\ -{stcWriteCmd(pcmd,CHIPCHAN+1); stcWriteData(pdata,(MODE)); \ -stcWriteData(pdata,(LOAD)); stcWriteData(pdata,(HOLD));} - -#define STC_CTR_READ(MODE,LOAD,HOLD)\ -{stcWriteCmd(pcmd,CHIPCHAN+1); (MODE) = stcReadData(pdata); \ -(LOAD) = stcReadData(pdata); (HOLD) = stcReadData(pdata);} - -#define STC_SET_TC(D) stcWriteCmd(pcmd, \ - 0xe0U | ((D)?8:0)|(CHIPCHAN+1U) ) - -#define STC_LOAD stcWriteCmd(pcmd, 0x40U | 1<<(CHIPCHAN)) -#define STC_STEP stcWriteCmd(pcmd, 0xf0U | (CHIPCHAN+1U)) -#define STC_ARM stcWriteCmd(pcmd, 0x20U | 1< -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define COMET_NCHAN 4 -#define COMET_CHANNEL_MEM_SIZE 0x20000 /* bytes */ -#define COMET_DATA_MEM_SIZE (COMET_CHANNEL_MEM_SIZE*COMET_NCHAN) -static short scan_control; /* scan type/rate (if >0 normal, <=0 external control) */ - -/* comet conrtol register map */ -struct comet_cr{ - unsigned char csrh; /* control and status register - high byte */ - unsigned char csrl; /* control and status register - low byte */ - unsigned char lcrh; /* location status register - high byte */ - unsigned char lcrl; /* location status register - low byte */ - unsigned char gdcrh; /* gate duration status register - high byte*/ - unsigned char gdcrl; /* gate duration status register - low byte */ - unsigned char cdr; /* channel delay register */ - unsigned char acr; /* auxiliary control register */ - char pad[0x100-8]; -}; - - -/* defines for the control status register - high byte */ -#define DIGITIZER_ACTIVE 0x80 /* 1- Active */ -#define ARM_DIGITIZER 0x40 /* 1- Arm the digitizer */ -#define CIRC_BUFFER_ENABLED 0x20 /* 0- Stop when memory is full */ -#define WRAP_MODE_ENABLED 0x10 /* 0- Disable wrap around */ -#define AUTO_RESET_LOC_CNT 0x08 /* 1- Reset addr to 0 on trigger */ -#define EXTERNAL_TRIG_ENABLED 0x04 /* 1- use external clk to trigger */ -#define EXTERNAL_GATE_ENABLED 0x02 /* 0- use pulse start conversion */ -#define EXTERNAL_CLK_ENABLED 0x01 /* 0- uses the internal clock */ - - -/* commands for the COMET digitizer */ -#define COMET_INIT_CSRH -#define COMET_INIT_READ - -/* mode commands for the COMET digitizer */ -#define READREG 0 -#define WRITEREG 1 -#define SCANCONTROL 2 -#define SCANSENSE 3 -#define SCANDONE 4 - -/* register selects */ -#define COMET_CSR 0 -#define COMET_LCR 1 -#define COMET_GDCR 2 -#define COMET_CDACR 3 - -/* defines for the control status register - low byte */ -#define SOFTWARE_TRIGGER 0x80 /* 1- generates a software trigger */ -#define UNUSED 0x60 -#define CHAN_DELAY_ENABLE 0x10 /* 0- digitize on trigger */ -#define DIG_RATE_SELECT 0x0f - -/* digitizer rates - not defined but available for 250KHz to 122Hz */ -#define COMET_5MHZ 0x0000 -#define COMET_2MHZ 0x0001 -#define COMET_1MHZ 0x0002 -#define COMET_500KHZ 0x0003 - -/* defines for the auxiliary control register */ -#define ONE_SHOT 0x10 -#define ALL_CHANNEL_MODE 0x80 - - -/* comet configuration data */ -struct comet_config{ - struct comet_cr *pcomet_csr; /* pointer to the control/status register */ - unsigned short *pdata; /* pointer to data area for this COMET card */ - void (*psub)(); /* subroutine to call on end of conversion */ - void *parg[4]; /* argument to return to the arming routine */ - FAST_LOCK lock; /* mutual exclusion lock */ - IOSCANPVT ioscanpvt; - unsigned long nelements; /* number of elements to digitize/read */ - -}; - -/* task ID for the comet done task */ -int cometDoneTaskId; -struct comet_config *pcomet_config; - -static long report(); -static long init(); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvComet={ - 2, - report, - init}; - - -/* - * cometDoneTask - * - * wait for comet waveform record cycle complete - * and call back to the database with the waveform size and address - * - */ -void -cometDoneTask() -{ - register unsigned card; - register struct comet_config *pconfig; - - while(TRUE) - { - - if (scan_control <= 0) - taskDelay(2); - else - { - taskDelay(scan_control); - -/* printf("DoneTask: entering for loop...\n"); */ - - /* check each card for end of conversion */ - for(card=0, pconfig = pcomet_config; card < 2;card++, pconfig++) - { -/* is the card present */ - if (!pconfig->pcomet_csr) - { - if (card == 0) - { -/* - printf("DoneTask: checking card present?...\n"); - printf("DoneTask: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); -*/ - } - continue; - } - -/* is the card armed */ - if (!pconfig->psub) - { - if (card == 0) - { -/* printf("DoneTask: checking card armed?...\n"); */ - } - continue; - } - -/* is the digitizer finished conversion */ -/* printf("pconfig->pdata: %x \n", pconfig->pdata); */ - - if (*(pconfig->pdata+pconfig->nelements) == 0xffff) - { - if (card == 0) - { -/* printf("DoneTask: finished conversion?...\n"); */ - } - continue; - } - -/* printf("DoneTask: pcomet_config->pcomet_csr %x...\n",pcomet_config->pcomet_csr); */ -/* printf("DoneTask: DONE\n"); */ - - -#if 0 - /* reset each of the control registers */ - pconfig->pcomet_csr->csrh = pconfig->pcomet_csr->csrl = 0; - pconfig->pcomet_csr->lcrh = pconfig->pcomet_csr->lcrl = 0; - pconfig->pcomet_csr->gdcrh = pconfig->pcomet_csr->gdcrl = 0; - pconfig->pcomet_csr->acr = 0; -#endif - - /* clear the pointer to the subroutine to allow rearming */ -/* pconfig->psub = NULL; */ - -/* post the event */ -/* - is there a bus error for long references to this card?? copy into VME mem? */ - - if(pconfig->parg[0]) - { - (*pconfig->psub)(pconfig->parg[0],pconfig->pdata); - } - if(pconfig->parg[1]) - { - (*pconfig->psub)(pconfig->parg[1],(((char*)pconfig->pdata)+0x20000)); - } - - if(pconfig->parg[2]) - { - (*pconfig->psub)(pconfig->parg[2],(((char*)pconfig->pdata)+0x40000)); - } - - if(pconfig->parg[3]) - { - (*pconfig->psub)(pconfig->parg[3],(((char*)pconfig->pdata)+0x60000)); - } - - - } - } - } -} - - - -/* - * COMET_INIT - * - * intialize the driver for the COMET digitizer from omnibyte - * - */ -int comet_init() -{ - register struct comet_config *pconfig; - short readback,got_one,card; - int status; - struct comet_cr *pcomet_cr; - unsigned char *extaddr; - -/* free memory and delete tasks from previous initialization */ - if (cometDoneTaskId) - { - taskwdRemove(cometDoneTaskId); - if ((status = taskDelete(cometDoneTaskId)) < 0) - logMsg("\nCOMET: Failed to delete cometDoneTask: %d",status); - } - else - { - pcomet_config = (struct comet_config *)calloc(wf_num_cards[COMET],sizeof(struct comet_config)); - if (pcomet_config == 0) - { - logMsg("\nCOMET: Couldn't allocate memory for the configuration data"); - return(0); - } - } - -/* get the standard and short address locations */ - if ((status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,wf_addrs[COMET],&pcomet_cr)) != OK){ - logMsg("\nCOMET: failed to map VME A16 base address\n"); - return(0); - } - if ((status = sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,wf_memaddrs[COMET],&extaddr)) != OK){ - logMsg("\nCOMET: failed to map VME A32 base address\n"); - return(0); - } - -/* determine which cards are present */ - got_one = FALSE; - pconfig = pcomet_config; - - for ( card = 0; - card < 2; - card++, pconfig++, pcomet_cr++, extaddr+= COMET_DATA_MEM_SIZE){ - - /* is the card present */ - if (vxMemProbe(pcomet_cr,READ,sizeof(readback),&readback) != OK) - { - continue; - } - if (vxMemProbe(extaddr,READ,sizeof(readback),&readback) != OK) - { - logMsg("\nCOMET: Found CSR but not data RAM %x\n",extaddr); - continue; - } - - /* initialize the configuration data */ - pconfig->pcomet_csr = pcomet_cr; - pconfig->pdata = (unsigned short *) extaddr; - got_one = TRUE; - - - FASTLOCKINIT(&pcomet_config[card].lock); - - /* initialize the card */ - pcomet_cr->csrh = ARM_DIGITIZER | AUTO_RESET_LOC_CNT; - pcomet_cr->csrl = COMET_1MHZ; - pcomet_cr->lcrh = pcomet_cr->lcrl = 0; - pcomet_cr->gdcrh = 0; - pcomet_cr->gdcrl = 1; - pcomet_cr->cdr = 0; - - /* run it once */ - pcomet_cr->csrl |= SOFTWARE_TRIGGER; - taskDelay(1); - /* reset */ - pcomet_cr->csrl = COMET_5MHZ; - pcomet_cr->acr = ONE_SHOT | ALL_CHANNEL_MODE; - - scanIoInit(&pconfig->ioscanpvt); - - } /*end of for loop*/ - - /* initialization for processing comet digitizers */ - if(got_one) - { - /* start the waveform readback task */ - scan_control = 2; /* scan rate in vxWorks clock ticks */ - cometDoneTaskId = taskSpawn("cometWFTask",WFDONE_PRI,WFDONE_OPT,WFDONE_STACK,(FUNCPTR) cometDoneTask); - taskwdInsert(cometDoneTaskId,NULL,NULL); - } - return(0); -} - - -static long report(level) - int level; -{ - comet_io_report(level); - return(0); -} - -static long init() -{ - - comet_init(); - return(0); -} - - -/* - * COMET_DRIVER - * - * initiate waveform read - * - */ -int comet_driver(card, signal, pcbroutine, parg, nelements) -register short card; -register unsigned short signal; -unsigned int *pcbroutine; -unsigned int *parg; /* pointer to the waveform record */ -unsigned long nelements; -{ - register struct comet_cr *pcomet_csr; - register struct comet_config *pconfig; - -/* printf("comet_driver: BEGIN...\n"); */ -/* printf("comet_driver: nelements: %d ...\n",nelements); */ - - /* check for valid card number */ - if(card >= wf_num_cards[COMET]) - return ERROR; - pconfig = (pcomet_config+card); - if(signal >= NELEMENTS(pconfig->parg)) - return ERROR; - pconfig->nelements = nelements * 2; - -/* printf("comet_driver: check for card present...\n"); */ - - /* check for card present */ - if(!pconfig->pcomet_csr) return ERROR; - - /* mutual exclusion area */ - FASTLOCK(&pconfig->lock); - -/* printf("comet_driver: mark the card as armed...\n"); */ - - /* mark the card as armed */ -/* if (pconfig->parg[signal] != 0) */ - pconfig->parg[signal] = parg; -/* if (pconfig->psub) return; */ - pconfig->psub = (void (*)()) pcbroutine; - - /* exit mutual exclusion area */ - FASTUNLOCK(&pconfig->lock); - - pcomet_csr = pconfig->pcomet_csr; - - /* reset each of the control registers */ - pcomet_csr->csrh = pcomet_csr->csrl = 0; - pcomet_csr->lcrh = pcomet_csr->lcrl = 0; - pcomet_csr->gdcrh = pcomet_csr->gdcrl = 0; - pcomet_csr->acr = 0; - - /* arm the card */ - *(pconfig->pdata+pconfig->nelements) = 0xffff; -/* printf("comet_driver: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); */ - - if (scan_control > 0) - { -#if 0 /* for debugging purposes */ - pcomet_csr->gdcrh = 0x03; /* # samples per channel */ - pcomet_csr->gdcrl = 0xe8; /* # samples per channel */ -#endif - - pcomet_csr->gdcrh = (pconfig->nelements >> 8) & 0xff; /* # samples per channel */ - pcomet_csr->gdcrl = pconfig->nelements & 0xff; /* # samples per channel */ - pcomet_csr->acr = ONE_SHOT | ALL_CHANNEL_MODE; /* disarm after the trigger */ - pcomet_csr->csrl = COMET_5MHZ; /* sample at 5MhZ */ - - /* arm, reset location counter to 0 on trigger, use external trigger */ - pcomet_csr->csrh = ARM_DIGITIZER | AUTO_RESET_LOC_CNT | EXTERNAL_TRIG_ENABLED; -/* printf("comet_driver: gdcrh: %x gdcrl: %x nelements: %x\n ",pcomet_csr->gdcrh,pcomet_csr->gdcrl, pconfig->nelements); */ - - } - else - pcomet_csr->csrh |= ARM_DIGITIZER; -/* printf("comet_driver: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); */ - -/* printf("comet_driver: END...\n"); */ - return OK; -} - - -/* - * COMET_IO_REPORT - * - * print status for all cards in the specified COMET address range - */ -int comet_io_report(level) -short int level; -{ - struct comet_config *pconfig; - unsigned card; - unsigned nelements; - int status; - - pconfig = pcomet_config; - for(card=0; card < wf_num_cards[COMET]; card++){ - - if(!pconfig->pcomet_csr) - continue; - - printf( "WF: COMET:\tcard=%d\n", card); - if (level >= 2){ - printf("enter the number of elements to dump:"); - status = scanf("%d",&nelements); - if(status == 1){ - comet_dump(card, nelements); - } - } - pconfig++; - } - return OK; -} - - -/* - * comet_dump - * - */ -int comet_dump(card, n) -unsigned card; -unsigned n; -{ - unsigned short *pdata; - unsigned short *psave; - unsigned short *pbegin; - unsigned short *pend; - - if (card >= wf_num_cards[COMET]) - return ERROR; - - pdata = pcomet_config[card].pdata; - psave = (unsigned short *) malloc(n * sizeof(*psave)); - if(!psave){ - return ERROR; - } - - pbegin = psave; - pend = &psave[n]; - for( pdata = pcomet_config[card].pdata; - psave= wf_num_cards[COMET]) - return ERROR; - if (!pcomet_config[card].pcomet_csr) - return ERROR; - switch (mode) - { - case READREG: - /*cptr = (unsigned char *)pcomet_config[card].pcomet_csr; - for (i = 0; i < 6; i++, cptr++) - printf("%x %x\n",cptr,*cptr);*/ - cptr = (unsigned char *)pcomet_config[card].pcomet_csr; /* point to offset 0 */ - cptr += arg<<1; /* build new offset */ - val = (*cptr++)<<8; /* read value and return */ - val |= *cptr; - return val; - break; - case WRITEREG: - cptr = (unsigned char *)pcomet_config[card].pcomet_csr; - cptr += arg<<1; - *cptr++ = val>>8; - *cptr = val; - break; - case SCANCONTROL: - scan_control = val; - break; - case SCANSENSE: - return scan_control; - break; - case SCANDONE: - if (!pcomet_config[card].psub) - return ERROR; - /*pcomet_config[card].psub = NULL;*/ /* clear the pointer to subroutine to allow rearming */ - (*pcomet_config[card].psub)(pcomet_config[card].parg,0xffff,pcomet_config[card].pdata); - break; - default: - return ERROR; - } - return OK; -} - -/*********************************************/ -int cometGetioscanpvt(card,scanpvt) -short card; -IOSCANPVT *scanpvt; -{ - register struct comet_config *pconfig; - - pconfig=pcomet_config; - pconfig+=card; - - if ((card >= wf_num_cards[COMET]) || (card < 0)) /* make sure hardware exists */ - return(0); - -/* -This is present in the mix driver...I don't know if I really need it. - if (!pconfig->present) - return(0); -*/ - - *scanpvt = pconfig->ioscanpvt; - - return(0); -} - diff --git a/src/vxWorks/drv/old/drvCompuSm.c b/src/vxWorks/drv/old/drvCompuSm.c deleted file mode 100644 index 863e0e853..000000000 --- a/src/vxWorks/drv/old/drvCompuSm.c +++ /dev/null @@ -1,868 +0,0 @@ -/* drvCompuSm.c */ -/* base/src/drv $Id$ */ -/* - * subroutines and tasks that are used to interface to the Compumotor 1830 - * stepper motor drivers - * - * Author: Bob Dalesio - * Date: 01-03-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 02-07-90 lrd add command to read the motor status - * .02 04-11-90 lrd made velocity mode motor go active - * .03 04-12-90 lrd only allow one connection to a motor - * .04 04-13-90 lrd add externally initiated motor motion monitoring - * .05 09-05-91 joh updated for v5 vxWorks - * .06 10-09-91 lrd monitor for external motion once every 2 seconds - * not at 30 Hz (.04 was not implemented correctly) - * .06 11-31-91 bg added compu_sm_io_report. Added sysBusToLocalAdrs() - * for addressing. - * .07 03-02-92 bg added level and ability to print raw values to - * compu_sm_io_report for level > 0. - * .08 05-04-92 bg added compu_sm_reset and rebootHookAdd so ioc can be - * rebooted with control X. - * .09 06-25-92 bg Combined drvCompuSm.c and compu_sm_driver.c - * .10 06-26-92 bg Added level to compu_sm_io_report in drvCompuSm - * structure - * .11 06-29-92 joh took file ptr arg out of io report - * .12 08-06-92 joh merged compu sm include file - * .13 08-27-92 joh silenced ANSI C function proto warning - * .14 08-27-92 joh fixed no epics init - * .15 08-02-93 mrk Added call to taskwdInsert - * .16 10-29-93 jba Fixed max number of cards to use module_types.c - * Fixed error in calculating card addresses - * .17 04-09-96 ric Added SM_FIND_LIMIT, SM_FIND_HOME - */ -#include -#include -#include -#include -#include /* library for semaphore support */ -#include /* library for semaphore support */ -#include /* library for semaphore support */ -#include /* library for semaphore support */ -#include -#include /* library for ring buffer support */ - -/* drvCompuSm.c - Driver Support Routines for CompuSm */ - -#include -#include -#include -#include -#include -#include -#include - - -long compu_sm_io_report(); -long compu_driver_init(); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvCompuSm={ - 2, - compu_sm_io_report, - compu_driver_init}; - -/* compumotor vme interface information */ -#define MAX_COMPU_MOTORS 8 - -#define RESP_SZ 16 /* card returns 16 chars - cmd & resp */ -#define RESPBUF_SZ (RESP_SZ+1) /* intr routine also passes motor no. */ - -/* Control Byte bit definitions for the Compumotor 1830 */ - /* bits 0 and 1 are not used */ -#define CBEND 0x04 /* end of command string */ -#define CBLMR 0x08 /* last message byte read */ -#define CBCR 0x10 /* command ready in cm_idb */ -#define CBMA 0x20 /* message accepted from odb */ -#define CBEI 0x40 /* enable interrupts */ -#define CBBR 0x80 /* board reset */ -#define SND_MORE CBCR | CBEI /* more chars to send */ -#define SND_LAST CBEND | SND_MORE /* last char being sent */ -#define RD_MORE CBMA | CBEI /* more chars to read */ -#define RD_LAST CBLMR | RD_MORE /* last byte we need to read */ - -/* Status Byte bit definitions */ -#define SBIRDY 0x10 /* idb is ready */ - -/* Structure used for communication with a Compumotor 1830 -** Motor Controller. The data buffer is repeated 64 times -** on even word addresses (0xXXXXXX1,0xXXXXX5...) and the -** control location is repeated 64 times on odd word -** addresses (0xXXXXX3, 0xXXXXX7...). The registers must -** be read and written as bytes. -*/ -struct compumotor { - char cm_d1; /* not accessable */ - char cm_idb; /* input data buffer */ - char cm_d2; /* not accessable */ - char cm_cb; /* control byte */ - char cm_d3[0x100-4]; /* fill to next standard address */ -}; - - -/* This file includes defines for all compumotor 1830 controller -** commands. */ - -#define SM_NULL 0x0 /* Null command */ -#define SM_INT 0x1 /* Interrupt X */ -#define SM_WRT_STAT 0x8 /* Write X to the user defined status bits */ -#define SM_SET_STAT 0x9 /* Set user defined status bit number X */ -#define SM_CLR_STAT 0xa /* Clear user defined status bit number X */ -#define SM_SET_PROG 0xb /* Set programmable output bit X */ -#define SM_CLR_PROG 0xc /* Clear programmable output bit X */ -#define SM_WRT_PROG 0xd /* Write X to the programmable output bits */ -#define SM_DEF_X_TO_Y 0xf /* Define bit X to indicate state Y */ -#define SM_TOG_JOG 0x10 /* Disable/enable the JOG inputs */ -#define SM_DEF_JOG 0x11 /* Define JOG input functions */ -#define SM_TOG_REM_PWR 0x12 /* Turn off/on remote power shutdown */ -#define SM_TOG_REM_SHUT 0x13 /* Disable/enable the "remote shutdown" bit */ -#define SM_SET_CW_MOTN 0x14 /* Set CW motion equal to +- */ -#define SM_TOG_POS_MTN 0x18 /* Turn off/on post-move position maintenance */ -#define SM_TOG_STOP_STL 0x19 /* Turn off/on termination on stall detect */ -#define SM_REP_X_Y 0x20 /* Repeat the following X commands Y times */ -#define SM_REP_TIL_CONT 0x21 /* Repeat the following X commands - until a CONTINUE is received */ -#define SM_WAIT_CONT 0x28 /* Wait for a CONTINUE */ -#define SM_WAIT_MILLI 0x29 /* Wait X milliseconds */ -#define SM_WAIT_SECOND 0x2a /* Wait X seconds */ -#define SM_WAIT_MINUTE 0x2b /* Wait X minutes */ -#define SM_WAIT_TRIGGER 0x2c /* Wait for trigger X to go active */ -#define SM_DEF_A_OP_POS 0x2e /* Define the abs open-loop position as X */ -#define SM_DEF_A_CL_POS 0x2f /* Define absolute closed-loop position */ -#define SM_DEF_ABS_ZERO 0x30 /* Define the present position as the - absolute zero position */ -#define SM_DEF_VEL_ACC 0x31 /* Define default velocity and acceleration */ -#define SM_MOV_DEFAULT 0x32 /* Perform the default move (trapezoidal - continuous) */ -#define SM_MOV_REL_POS 0x33 /* Go to relative position X at default - velocity and acceleration */ -#define SM_MOV_ABS_POS 0x34 /* Go to absolute position X at default - velocity and acceleration */ -#define SM_MOV_REL_ENC 0x35 /* Go to relative encoder position X */ -#define SM_MOV_ABS_ENC 0x36 /* Go to absolute encoder position X */ -#define SM_DEF_OP_HOME 0x38 /* Define HOME location (open loop */ -#define SM_DEF_CL_HOME 0x38 /* Define HOME location (closed loop) */ -#define SM_MOV_HOME_POS 0x39 /* Go HOME at the default velocity and - acceleration */ -#define SM_MOV_HOME_ENC 0x3a /* Go to encoder HOME at the default - velocity and acceleration */ -#define SM_DO_MOV_X 0x40 /* Perform move number X */ -#define SM_DO_SEQ_X 0x41 /* Perform sequence buffer X */ -#define SM_DO_VEL_STR 0x42 /* Perform the velocity streaming buffer */ -#define SM_CONT 0x48 /* CONTINUE (perform next command) */ -#define SM_OP_LOOP_MODE 0x50 /* Enter open loop indexer mode */ -#define SM_VEL_DIS_MODE 0x51 /* Enter velocity-distance streaming mode */ -#define SM_VEL_TIM_MODE 0x52 /* Enter velocity-time streaming mode */ -#define SM_STOP 0x70 /* STOP motion */ -#define SM_DSC_SEQ 0x71 /* Discontinue the sequence buffer */ -#define SM_SSP_SEQ 0x72 /* Suspend the sequence buffer; - wait for a CONTINUE to resume */ -#define SM_DSC_SNGL 0x73 /* Discontinue any singular command - currently being performed */ -#define SM_STOP_ON_TRG 0x74 /* STOP motion when trigger X goes active */ -#define SM_DSC_SEQ_TRG 0x75 /* Discontinue the sequence buffer when - trigger X goes active */ -#define SM_SSP_SEQ_TRG 0x76 /* Suspend sequence buffer when trigger - X goes active */ -#define SM_DSC_SNGL_TRG 0x77 /* Discontinue any singular command when - trigger X goes active */ -#define SM_KILL 0x78 /* Kill motion */ -#define SM_KILL_SEQ 0x79 /* Kill the sequence buffer */ -#define SM_KILL_SEQ_SNGL 0x7a /* Kill current sequence singular command; - wait for CONTINUE */ -#define SM_KILL_VEL_STR 0x7b /* Kill the velocity streaming buffer */ -#define SM_KILL_ON_TRG 0x7c /* Kill motion when trigger X goes active */ -#define SM_KILL_SEQ_TRG 0x7d /* Kill the sequence buffer when trigger - X goes active */ -#define SM_KL_SQSNG_TRG 0x7e /* Kill current sequence singular command - when trigger X goes active; wait for - a continue */ -#define SM_KL_VLSTR_TRG 0x7f /* Kill the velocity streaming buffer - when trigger X goes active */ -#define SM_GET_B_REL_POS 0x80 /* Request position relative to the - beginning of the current move */ -#define SM_GET_E_REL_POS 0x81 /* Request position relative to the - end of the current move */ -#define SM_GET_H_REL_POS 0x82 /* Request position relative to the home - limit switch */ -#define SM_GET_Z_REL_POS 0x83 /* Request position relative to the - absolute zero position */ -#define SM_GET_CUR_DIR 0x84 /* Request current direction */ -#define SM_GET_VEL 0x85 /* Request current velocity */ -#define SM_GET_ACC 0x86 /* Request current acceleration */ -#define SM_GET_MOV_STAT 0x88 /* Request current move status */ -#define SM_GET_LIM_STAT 0x89 /* Request state of the limit switches */ -#define SM_GET_HOME_STAT 0x8a /* Request state of the HOME switch */ -#define SM_GET_TRV_DIR 0x8b /* Request direction of travel */ -#define SM_GET_MOT_MOV 0x8c /* Request whether motor is moving or not */ -#define SM_GET_MOT_CONST 0x8d /* Request whether motor is at constant, - nonzero velocity or not */ -#define SM_GET_MOT_ACC 0x8e /* Request whether motor is or is not - accelerating */ -#define SM_GET_MOT_DEC 0x8f /* Request whether motor is or is not - decelerating */ -#define SM_GET_MODE 0x90 /* Request present mode */ -#define SM_GET_MV_PARM 0x91 /* Request move parameters for move number X */ -#define SM_GET_SEQ_CMMD 0x92 /* request commands stored in the - sequence buffer */ -#define SM_GET_MVDEF_STAT 0x93 /* Request state of the move definitions */ -#define SM_GET_TRG_STAT 0x94 /* Request state of trigger inputs */ -#define SM_GET_JOG_STAT 0x95 /* Request state of JOG inputs */ -#define SM_GET_Z_STAT 0x96 /* Request state of the Channel Z home input */ -#define SM_GET_OUT_STAT 0x97 /* Request the state of the programmable - output bits */ -#define SM_GET_REL_ENC 0x98 /* Request relative encoder count */ -#define SM_GET_REL_ERR 0x99 /* Request relative error from desired - closed loop position */ -#define SM_GET_ABS_ENC 0x9a /* Request absolute encoder count */ -#define SM_GET_SLIP_STAT 0x9b /* Request slip detect status */ -#define SM_GET_RATIO 0x9c /* Request motor pulse to encoder pulse ratio */ -#define SM_GET_RESOLTN 0x9d /* Request motor resolution */ -#define SM_GET_BACK_SIG 0x9e /* Request backlash sigma (motor steps)*/ -#define SM_GET_ALG 0x9f /* Request position maintenance alg. - const, and max velocity */ -#define SM_INT_NXT_MOV 0xa0 /* Interrupt at start of next move */ -#define SM_INT_ALL_MOV 0xa1 /* Interrupt at the start of every move */ -#define SM_INT_NXT_NZ 0xa2 /* Interrupt at constant nonzero velocity - of next move */ -#define SM_INT_ALL_NZ 0xa3 /* Interrupt at constant nonzero velocity - of every move */ -#define SM_INT_NXT_END 0xa4 /* Interrupt at next end of motion */ -#define SM_INT_ALL_END 0xa5 /* Interrupt at every end of motion */ -#define SM_INT_NXT_STL 0xa6 /* Interrupt on next stall detect */ -#define SM_INT_ALL_STL 0xa7 /* Interrupt on every stall detect */ -#define SM_INT_NXT_PLIM 0xa8 /* Interrupt the next time the motor - hits the positive limit */ -#define SM_INT_ALL_PLIM 0xa9 /* Interrupt on every positive limit */ -#define SM_INT_NXT_NLIM 0xaa /* Interrupt the next time the motor - hits the negative limit */ -#define SM_INT_ALL_NLIM 0xab /* Interrupt on every negative limit */ -#define SM_INT_TRG 0xac /* Interrupt on trigger X active */ -#define SM_INT_INHBT 0xaf /* Inhibit all interrupts */ -#define SM_DEF_RATIO 0xb0 /* Define motor pulse to encoder pulse ratio */ -#define SM_DEF_RESOLTN 0xb1 /* Define motor resolution */ -#define SM_DEF_BACK_SIG 0xb2 /* Define backlash sigma (motor steps)*/ -#define SM_DEF_ALG 0xb3 /* Define position maintenance algorithm - const, and max velocity */ -#define SM_DEF_TEETH 0xb4 /* Define the number of rotor teeth */ -#define SM_DEF_DEADBAND 0xb5 /* Def the deadband region in encoder pulses */ -#define SM_DEF_REL_TRP 0xc8 /* Define move X as a relative, - trapezoidal move */ -#define SM_DEF_ABS_TRP 0xcb /* Define move X as an absolute - trapezoidal move */ -#define SM_DEF_CONT 0xce /* Define move X as a continuous move */ -#define SM_DEF_REL_CL 0xd4 /* Define move X, define it as relative, - closed-loop move */ -#define SM_DEF_ABS_CL 0xd5 /* Def move X as an abs, closed- loop move */ -#define SM_DEF_STSTP_VEL 0xd6 /* Define the start/stop velocity */ -#define SM_DEL_MOV_X 0xd7 /* Delete move X */ -#define SM_END_SEQ_DEF 0xd8 /* End definition of sequence buffer */ -#define SM_BEG_SEQ_DEF 0xd9 /* Begin definition of sequence buffer */ -#define SM_DEL_SEQ_X 0xda /* Delete sequence buffer X */ -#define SM_LD_VD_DATA 0xe0 /* Place data into the velocity-distance buffer */ -#define SM_LD_VT_DATA 0xe1 /* Place data into the velocity-time buffer */ -#define SM_GET_FREE_BYT 0xe2 /* Request number of free bytes in vel- - streaming/sequence buffer */ -#define SM_DEF_VS_CMMD 0xee /* Define command to be executed during - the velocity streaming buffer */ -#define SM_GET_NUM_REV 0xfd /* Request software part number and revision */ -#define SM_TEST_SWITCH 0xff /* Perform the test switch function */ - - -#define VELOCITY_MODE 0 -#define MAX_COMMANDS 256 -#define COMPU_INT_LEVEL 5 - -/* array of pointers to stepper motor driver cards present in system */ -struct compumotor *pcompu_motors[MAX_COMPU_MOTORS]; - -LOCAL SEM_ID compu_wakeup; /* compumotor data request task semaphore */ - -/* response variables */ -LOCAL SEM_ID smRespSem; /* task semaphore */ -LOCAL RING_ID smRespQ; /* ring buffer */ -int smRespId; /* task id */ -#define RESP_Q_SZ (RESPBUF_SZ * 50) /* response ring buffer size */ - -/* interrupt buffers */ -unsigned char sm_responses[MAX_COMPU_MOTORS][RESPBUF_SZ]; -unsigned short counts[MAX_COMPU_MOTORS]; -/* counts for debugging */ -long dbicounts; /* counts number of times through interrupt routine */ -long dbrcounts; /* counts number of times through response routine */ -long dbscounts; /* counts number of times through send routine */ - -/* VME memory Short Address Space is set up in gta_init */ -static int *compu_addr; - -/* motor information */ -struct compu_motor{ -short active; /* flag to tell the oms_task if the motor is moving */ -int callback; /* routine in database library to call with status */ -int callback_arg; /* argument to callback routine */ -short update_count; -short mode; -short motor_resolution; -}; -struct compu_motor compu_motor_array[MAX_COMPU_MOTORS]; - -/* Forward reference. */ -VOID compu_sm_reset(); -VOID compu_sm_stat(); - -/* motor status - returned to the database library routines */ -struct motor_data compu_motor_data_array[MAX_COMPU_MOTORS]; - -/* moving status bit descriptions */ -#define CW_LIMIT 0x01 /* clockwise???? limit */ -#define CCW_LIMIT 0x02 /* counter-clockwise???? limit */ -#define DIRECTION 0x08 /* direction bit */ -#define MOVING 0x10 /* moving status bit */ -#define CONSTANT_VEL 0x20 /* constant velocity */ - -/* directions in driver card-ese */ -#define CLKW 0 /* clockwise direction */ -#define CCLKW 1 /* counter clockwise direction */ - -/* - * Code Portions: - * - * smCmdTask Task which writes commands to the hardware - * smRespTask Task which places reponses from the hardware into resp buffers - * sm_intr Interrupt Handler - collects response data from the hardware - * sm_drv_init Initializes all motors, semaphores, ring buffers and interrupts - * sm_driver Subroutine for outside world to issue commands to motors - * motor_select Subroutine to setting callback arg and verifying no other user - * motor_deselect Subroutine to free the motor for other users - * - * Interaction Chart: - * -------------- ------------------- - * / \ / \ - * | smRespTask | | smCmdTask | - * \ / \ / - * --------------- ------------------- - * ^ ^ | - * TAKES | | GETS | - * | | | - * -------------- --------------- | - * Resp Semaphore Response Queue | - * -------------- --------------- | - * ^ ^ | - * GIVES | | PUTS | - * | | | - * --------------- | - * / \ | - * | sm_intr | | - * \ / | - * --------------- | - * ^ reads responses writes commands | - * | from hardware to hardware V - */ - -/* - * COMPU_RESP_TASK - * - * converts readback from the compumotor 1830 cards into a structure that - * is returned to the database library layer every .1 second while a motor - * is moving - */ -int compu_resp_task() -{ - unsigned char resp[RESPBUF_SZ]; - register struct motor_data *pmotor_data; - - FOREVER { - /* wait for somebody to wake us up */ - semTake (smRespSem, WAIT_FOREVER); - (dbrcounts < 0xFFFF ? dbrcounts++: 0); - /* the response buffer contains: */ - /* 0 - motor number */ - /* 1 - the command which solicited this response */ - /* 2 - the first byte of the response */ - - /* process requests in the command ring buffer */ - while (rngBufGet(smRespQ,(char *)resp,RESPBUF_SZ) == RESPBUF_SZ){ - pmotor_data = &compu_motor_data_array[resp[0]]; - - /* convert argument */ - switch(resp[1]){ - - case (SM_GET_VEL): - { - register long *pvelocity = (long *)(&resp[3]); - pmotor_data->velocity = *pvelocity; - - break; - } - case (SM_GET_MOV_STAT): - { - register struct compu_motor *pcompu_motor; - register int (*psmcb_routine)(); - - pcompu_motor = &compu_motor_array[resp[0]]; - pmotor_data->moving = (resp[2] & MOVING)?1:0; - pmotor_data->constant_velocity = (resp[2] & CONSTANT_VEL)?1:0; - pmotor_data->cw_limit = (resp[2] & CW_LIMIT)?1:0; - pmotor_data->ccw_limit = (resp[2] & CCW_LIMIT)?1:0; - pmotor_data->direction = (resp[2] & DIRECTION)?1:0; - - /* post every .1 second or not moving */ - if ((pcompu_motor->update_count-- <= 0) - || (pmotor_data->moving == 0)){ - if (pcompu_motor->callback != 0){ - (int)psmcb_routine = pcompu_motor->callback; - (*psmcb_routine)(pmotor_data,pcompu_motor->callback_arg); - } - if (pmotor_data->moving){ - /* motors are reported at 10 Hz */ - pcompu_motor->update_count = 3; - }else{ - pcompu_motor->active = FALSE; - pcompu_motor->update_count = 0; - } - } - break; - } - case (SM_GET_ABS_ENC): - { - register long *pencoder = (long *)(&resp[2]); - pmotor_data->encoder_position = *pencoder; - break; - } - case (SM_GET_Z_REL_POS): - { - register long *pmotor = (long *)(&resp[4]); - pmotor_data->motor_position = *pmotor; - break; - } - case (SM_GET_CUR_DIR): - pmotor_data->direction = (resp[2] == 0xff)?CLKW:CCLKW; - break; - } - } - } -} - -/* Data request commands for the positional and velocity mode motors */ -char compu_velo_reqs[] = { SM_GET_VEL, SM_GET_MOV_STAT }; -#define NUM_VEL_REQS 2 -char compu_pos_reqs[] = { SM_GET_ABS_ENC, SM_GET_Z_REL_POS, SM_GET_MOV_STAT }; -#define NUM_POS_REQS 3 -/* - * COMPU_TASK - * - * task to solicit currnet status from the compumotor 1830 cards while they - * are active - */ -int compu_task() -{ - register short inactive_count; - register short card; - register short i; - register struct compumotor *pmotor; - register char *preqs; - - /* inactive motors get monitored once every 2 seconds in case they are */ - /* being moved manually */ - inactive_count = 60; - while(1){ - /* This task is run 30 times a second */ - taskDelay(2); - for (card = 0; card < sm_num_cards[CM57_83E]; card++){ - pmotor = pcompu_motors[card]; - if (pmotor == 0) continue; - if ((compu_motor_array[card].active) - || (inactive_count <=0)){ - if (compu_motor_array[card].mode == VELOCITY_MODE){ - preqs = &compu_velo_reqs[0]; - /* request status data */ - for (i = 0; i < NUM_VEL_REQS; i++,preqs++) - compu_send_msg(pmotor,preqs,1); - }else{ - preqs = &compu_pos_reqs[0]; - /* request status data */ - for (i = 0; i < NUM_POS_REQS; i++,preqs++) - compu_send_msg(pmotor,preqs,1); - } - } - } - if (--inactive_count < 0) inactive_count = 60; - } -} - -/* - * COMPU_INTR - * - * interrupt vector for the compumotor 1830 card - */ -int compu_intr(mdnum) -register int mdnum; -{ - register struct compumotor *pmtr; /* memory port to motor card */ - register int key; - - key = intLock(); - - /* pointer to the compumotor card interface */ - pmtr = pcompu_motors[mdnum]; - if (pmtr == 0) - { - intUnlock(key); - return(0); - }; - (dbicounts < 0xFFFF ? dbicounts++: 0); - /* place the response byte into the appropriate response buffer */ - sm_responses[mdnum][counts[mdnum]] = pmtr->cm_idb; - counts[mdnum]++; - - /* when the buffer is full pass it onto the repsonse task */ - if (counts[mdnum] == RESPBUF_SZ){ - if (rngBufPut(smRespQ,(char *)sm_responses[mdnum],RESPBUF_SZ) != RESPBUF_SZ) - logMsg("smRespQ %d - Full\n",mdnum); - else - semGive (smRespSem); - - /* the zero-th byte is the motor number */ - counts[mdnum] = 1; /* start with command */ - - /* inform the hardware that the response is complete */ - pmtr->cm_cb = RD_LAST; - }else{ - /* inform the hardware there is more to send */ - pmtr->cm_cb = RD_MORE; - } - - intUnlock(key); - return(0); -} - -/* - * COMPU_DRIVER_INIT - * - * initialization for the compumotor 1830 card - */ -long -compu_driver_init(){ - register short i; - int status; - struct compumotor *pmtr; /* memory port to motor card */ - int cok = CBBR; /*to reset board */ - short none_found; /* flags a steppermotor is present */ - int taskId; - struct compumotor *pmtrb; - - /* intialize each driver which is present */ - none_found = TRUE; - rebootHookAdd((FUNCPTR)compu_sm_reset); - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - sm_addrs[CM57_83E], - (int **)&compu_addr); - if (status != OK){ - printf("%s: failed to map A16 base\n", __FILE__); - return ERROR; - } - - pmtrb = (struct compumotor *)compu_addr; - for (i = 0; i < sm_num_cards[CM57_83E]; i++) { - pmtr = (struct compumotor *)((int)pmtrb + (i<<8)); - - /* initialize when card is present */ - - if (vxMemProbe(&pmtr->cm_cb,WRITE,1,&cok) != ERROR){ - none_found = FALSE; - pcompu_motors[i] = pmtr; /* ptr to interface */ - intConnect((MD_INT_BASE+i)*4,compu_intr,i); /* interrupt enable */ - sysIntEnable(COMPU_INT_LEVEL); - - /* init interrupt receive buffers */ - sm_responses[i][0] = i; /* motor number */ - counts[i] = 1; /* buffer index */ - }else{ - pcompu_motors[i] = 0; /* flags no board is present */ - } - } - if (none_found) return(0); - - /* initialize the response task ring buffer */ - if ((smRespQ = rngCreate(RESP_Q_SZ)) == (RING_ID)NULL) - panic ("sm_init: cmRespQ\n"); - - /* intialize the semaphores which awakens the sleeping * - * stepper motor command task and the stepper motor response task */ - if(!(smRespSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))) - errMessage(0,"semBcreate failed in compu_driver_init"); - if(!(compu_wakeup=semBCreate(SEM_Q_FIFO,SEM_EMPTY))) - errMessage(0,"semBcreate failed in compu_driver_init"); - - /* spawn the sleeping motor driver command and response tasks */ - smRespId = - taskSpawn("compu_resp_task",SMRESP_PRI,SMRESP_OPT,SMRESP_STACK,compu_resp_task); - taskwdInsert(smRespId,NULL,NULL); - taskId = taskSpawn("compu_task",SMRESP_PRI,SMRESP_OPT,2000,compu_task); - taskwdInsert(taskId,NULL,NULL); - return(0); -} - -short trigger = 0; -/* - * COMPU_DRIVER - * - * driver interface to the database library layer - */ -int compu_driver(card, channel, value_flag,arg1,arg2) -register short card; -short channel; -short value_flag; -register int arg1; -register int arg2; -{ - register int *pint; - register short *pshort; - short i; - char compu_msg[20]; - i = 0; - /* verify the stepper motor driver card is present */ - if ((card < 0) || (card > sm_num_cards[CM57_83E]) || (!pcompu_motors[card])) - return (-1); - - switch (value_flag){ - case (SM_MODE): - /* set the motor mode */ - compu_motor_array[card].mode = arg1; - break; - - case (SM_VELOCITY): - compu_motor_data_array[card].velocity = arg1; - compu_motor_data_array[card].accel = arg2; - - /* set the velocity */ - compu_msg[0] = SM_DEF_VEL_ACC; - compu_msg[1] = 0; /* time is in seconds */ - compu_msg[2] = 0; - pint = (int *)&compu_msg[3]; /* velocity */ - *pint = arg1; - pint++; /* acceleration */ - *pint = arg2; - compu_send_msg(pcompu_motors[card],compu_msg,11); - - break; - - case (SM_FIND_HOME): /* Move to a home switch */ - break; /* Not supported by this device */ - - case (SM_FIND_LIMIT): /* Move to a limit switch */ - arg1 = arg1 >= 0 ? 0x000fffff : -0x000fffff; - /* break purposely left out to continue with SM_MOVE */ - - case (SM_MOVE): - if (compu_motor_array[card].mode == VELOCITY_MODE) - return(0); - - /* move the motor */ - i = 0; - compu_msg[i++] = SM_MOV_REL_POS; - pint = (int *)&compu_msg[i]; - *pint = arg1; - i += 4; - - compu_send_msg(pcompu_motors[card],compu_msg,i); - - /* set the motor to active */ - compu_motor_array[card].active = TRUE; - - /* wakeup the compu task */ - semGive(compu_wakeup); - - break; - - case (SM_MOTION): - if (arg1 == 0){ - compu_msg[0] = SM_STOP; - compu_send_msg(pcompu_motors[card],compu_msg,1); - }else if (compu_motor_array[card].mode == VELOCITY_MODE){ - compu_msg[0] = SM_MOV_DEFAULT; - compu_msg[1] = arg2; /* direction */ - compu_send_msg(pcompu_motors[card],compu_msg,2); - compu_motor_array[card].active = TRUE; - } - - /* wakeup the compu task */ - semGive(compu_wakeup); - break; - - case (SM_CALLBACK): - /* put the callback routine and argument into the data array */ - i = 0; - if (compu_motor_array[card].callback != 0) return(-1); - compu_motor_array[card].callback = arg1; - compu_motor_array[card].callback_arg = arg2; - break; - - case (SM_SET_HOME): - if (compu_motor_array[card].mode == VELOCITY_MODE) - return(OK); - - /* set the motor and encoder position to zero */ - compu_msg[0] = SM_DEF_ABS_ZERO; - compu_send_msg(pcompu_motors[card],compu_msg,1); - - break; - - case (SM_ENCODER_RATIO): - compu_motor_array[card].motor_resolution = arg1; - - /* set the encoder ratio */ - compu_msg[0] = SM_DEF_RATIO; - pshort = (short *)&compu_msg[1]; - *pshort = arg1; /* motor resolution */ - pshort++; - *pshort = arg2; /* encoder resolution */ - compu_send_msg(pcompu_motors[card],compu_msg,5); - - /* set the motor resolution */ - compu_msg[0] = SM_DEF_RESOLTN; - pshort = (short *)&compu_msg[1]; - *pshort = 0; - pshort++; - *pshort = arg1; /* motor resolution */ - compu_send_msg(pcompu_motors[card],compu_msg,5); - - break; - case (SM_READ): - /* set the motor to active */ - compu_motor_array[card].active = TRUE; - - /* wakeup the compu task */ - semGive(compu_wakeup); - - break; - - } - return (OK); -} - -/* - * COMPU_SEND_MSG - * - * send a message to the compumotor 1830 - */ -int wait_count; -int compu_send_msg(pmotor,pmsg,count) -register struct compumotor *pmotor; -register char *pmsg; -register short count; -{ - (dbscounts < 0xFFFF ? dbscounts++: 0); - /* write out this command one byte at a time */ - while (count){ - - /* wait for the driver to be ready */ - while ((pmotor->cm_cb & SBIRDY) == 0){ - taskDelay(0); - wait_count++; - } - - /* next byte in the input data buffer of compumotor */ - pmotor->cm_idb = *pmsg; - pmsg++; - count--; - - /* tell compumotor more or complete */ - if (count == 0){ - pmotor->cm_cb = SND_LAST; - }else{ - pmotor->cm_cb = SND_MORE; - } - } - return(0); -} - - -/* - * COMPU_SM_IO_REPORT - * - * send a message to the compumotor 1830 - */ - -long compu_sm_io_report(level) - short int level; - { - register int i; - - for (i = 0; i < sm_num_cards[CM57_83E]; i++){ - if (pcompu_motors[i]){ - - printf("SM: CM1830: card %d\n",i); - if (level > 0) - compu_sm_stat(i); - } - } - - return OK; - } - -VOID compu_sm_stat(compu_num) - short int compu_num; - { - printf("\tCW limit = %d\t,CCW limit = %d\tMoving = %d\tDirection = %d\n", - compu_motor_data_array[compu_num].cw_limit, - compu_motor_data_array[compu_num].ccw_limit, - compu_motor_data_array[compu_num].moving, - compu_motor_data_array[compu_num].direction); - - printf("\tConstant Velocity = %d\t, Velocity = %d\t \n", - compu_motor_data_array[compu_num].constant_velocity, - compu_motor_data_array[compu_num].velocity); - - printf("\tAcceleration = %d\tEncoder Position = %d\tMotor Position = %d\n", - compu_motor_data_array[compu_num].accel, - compu_motor_data_array[compu_num].encoder_position, - compu_motor_data_array[compu_num].motor_position); - } - -/* - * - * Subroutine to be called during a CTL X reboot. Inhibits interrupts. - * - */ - -VOID compu_sm_reset() - { - short int i; - char compu_msg[20]; - - for (i = 0; i < sm_num_cards[CM57_83E]; i++){ - if (pcompu_motors[i]){ - compu_msg[0] = SM_INT_INHBT; - compu_send_msg(pcompu_motors[i],compu_msg,1); - } - } - } diff --git a/src/vxWorks/drv/old/drvFp.c b/src/vxWorks/drv/old/drvFp.c deleted file mode 100644 index 9885943a6..000000000 --- a/src/vxWorks/drv/old/drvFp.c +++ /dev/null @@ -1,532 +0,0 @@ -/* drvFp.c */ -/* base/src/drv $Id$ - * routines which are used to test and interface with the - * FP10S fast protect module - * - * Author: Matthew Stettler - * Date: 6-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 joh 070992 integrated into GTACS & added std header - * .02 joh 070992 merged in include file fp.h - * .03 joh 070992 converted some symbols to LOCAL so they stay out - * of the vxWorks global symbol table - * .04 joh 070992 took out sysSetBCL() and substituted - * sysIntEnable() so this will not be hkv2f - * specific. - * .05 joh 070992 added INUM_TO_IVEC so this will be less - * 68k dependence (added include of iv.h) - * .06 joh 070992 FP_ILEV passed to call sysIntEnable() so that the - * interrupt level can be easily changed - * .07 joh 070992 changed some printf() calls to logMsg() - * so that driver diagnostics will show up in - * the log - * .08 joh 071092 now fetches base addr from module_types.h - * .09 joh 071092 added io_report routine - * .10 joh 071092 added scan task wakeup from ISR - * .11 joh 071092 moved ivec allocation to module_types.h - * .12 joh 072792 added soft reboot int disable - * .13 joh 082792 converted to V5 vxorks - * .14 mrk 090192 support epics I/O event scan, and added DRVET - * .15 mrk 080293 Add call to taskwdInsert - * .16 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals - */ - - - -/* - * - * Routines: - * - * fp_init Finds and initializes fast protect cards - * fp_driver System interface to FP10S modules - * fp_int Interrupt service routine - * fp_en Enables/disables interrupts (toggles) - * fp_mode Sets interrupt reporting mode - * fp_reboot Clean up for soft reboots - * - * Diagnostic Routines: - * - * fp_srd Reads current local inputs and enables - * fp_frd Reads last failure register - * fp_csrd Reads control/status register - * fp_read Command line interface to fp_driver - * fp_dump Prints all fast protect status to console - * fp_monitor Monitor all cards and print failure data to - * console - * - * Routines Return: - * - * -1 No card present - * -2 Interrupt connection error - * -3 Semaphore creation error - * -4 addressing error - * -5 no memory - * 0-8 successfull completion, or # of cards found - * - */ - -static char *sccsId = "@(#)drvFp.c 1.12\t6/4/93"; - -#include "vxWorks.h" -#include "stdlib.h" -#include "stdio.h" -#include "intLib.h" -#include "rebootLib.h" -#include "vme.h" -#include "taskLib.h" -#include /* in h/68k if this is compiling for a 68xxx */ - -#include "module_types.h" -#include -#include -#include -#include - -static long report(); -static long init(); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvFp={ - 2, - report, - init}; - -static long report() -{ - fp_io_report(); - return(0); -} - -static long init() -{ - fp_init(0); - return(0); -} - -/* general constants */ -#define FP_INTLEV 5 /* interrupt level */ -#define FP_BUFSIZ 8 /* input buffer size */ - -/* csr bit definitions */ -#define CSR_RST 0x1 /* reset status */ -#define CSR_CMD1 0x2 /* force local fail */ -#define CSR_IEN 0x4 /* interrupt enable */ -#define CSR_UDEF0 0x8 /* undefined */ -#define CSR_I0 0x10 /* interrupt level bit #1 */ -#define CSR_I1 0x20 /* interrupt level bit #2 */ -#define CSR_I2 0x40 /* interrupt level bit #3 */ -#define CSR_UDEF1 0x80 /* undefined */ -#define CSR_CARM0_L 0x100 /* latched carrier monitor #0 (one shot) */ -#define CSR_CARM1_L 0x200 /* latched carrier monitor #1 (freq mon) */ -#define CSR_OPTIC 0x400 /* optical carrier input enabled */ -#define CSR_CARM 0x800 /* carrier OK */ -#define CSR_LFAIL0 0x1000 /* local fail #0 (pal monitor) */ -#define CSR_LFAIL1 0x2000 /* local fail #1 (fpga monitor) */ -#define CSR_CMON 0x4000 /* clock fail (one shot) */ -#define CSR_CHNG 0x8000 /* enable switch configuration change */ - -/* csr mask definitions */ -#define CSR_STM 0xff00 /* status mask */ -#define CSR_IM 0x70 /* interrupt level mask */ - -/* driver status */ -#define DRV_MOM 0x010000 /* momentary fault */ -#define DRV_LOC 0x020000 /* local fault */ -#define DRV_REM 0x040000 /* remote fault */ -#define DRV_CLR 0x080000 /* fault cleared */ -#define DRV_HWF 0x800000 /* hardware fault */ - -/* operating modes */ -#define FP_NMSG 0 /* no messages to console */ -#define FP_TMSG 1 /* terse messages to console */ -#define FP_FMSG 2 /* full messages to console */ -#define FP_RUN 3 /* normal operating mode */ - -/* register address map for FP10s */ -struct fp1 - { - unsigned short csr; /* control and status register */ - unsigned short srd; /* current status */ - unsigned short frd; /* latched status */ - unsigned short ivec; /* interrupt vector */ - char end_pad[0xff-0x8]; /* pad to 256 byte boundary */ - }; - -/* fast protect control structure */ -struct fp_rec - { - struct fp1 *fptr; /* pointer to device registers */ - unsigned int drvstat; /* fast protect physical inputs */ - unsigned short lastswitch; /* previous enable switch data */ - short type; /* device type */ - short num; /* device number */ - short fp_vector; /* interrupt vector */ - short mode; /* operating mode */ - unsigned int int_num; /* interrupt number */ - IOSCANPVT ioscanpvt; - }; - -static struct fp_rec *fp; /* fast protect control structure */ -static int fp_num; /* # of fast protect cards found -1 */ -static SEM_ID fp_semid; /* semaphore for monitor task */ - -static void fp_reboot(); - -/* - * fp_int - * - * interrupt service routine - * - */ -int fp_int(card) -unsigned card; -{ - register struct fp_rec *ptr = &fp[card]; - register struct fp1 *regptr; - unsigned short temp0, temp1, temp2; - - regptr = ptr->fptr; - temp0 = regptr->csr; - temp1 = regptr->frd; - temp2 = regptr->srd; - switch (ptr->mode) - { - case FP_TMSG: - logMsg("fast protect interrupt!\n"); - logMsg("csr status = %x\n",temp0); - break; - case FP_FMSG: - logMsg("fast protect #%d fault! fault input = %x enable switches = %x\n", - ptr->num,temp1 & 0xff,temp2>>8); - logMsg("csr status = %x\n",temp0); - break; - case FP_RUN: - ptr->drvstat = temp2; /* save last switch data */ - ptr->drvstat |= temp1<<16; /* save fault data */ - ptr->drvstat |= (temp0 & 0xff00)<<16; /* csr status bits */ - if ((temp1 ^ (temp2>>8)) || (temp0 & CSR_CHNG)) /* fault or enable change */ - semGive(fp_semid); /* wake up monitor */ - - /* - * wakeup the interrupt driven scanner - */ - scanIoRequest(fp[card].ioscanpvt); - break; - } - ptr->int_num++; /* log interrupt */ - regptr->csr |= CSR_RST; /* clear status and rearm */ - regptr->csr ^= CSR_RST; - return(0); -} - - -/* - * fp_init - * - * initialization routine for FP10s fast protect modules - * - * - */ -int fp_init(addr) -unsigned int addr; -{ - int i; - short junk; - short intvec = AT8FP_IVEC_BASE; - struct fp1 *ptr; - int status; - - fp = (struct fp_rec *) calloc(bi_num_cards[AT8_FP10S_BI], sizeof(*fp)); - if(!fp){ - return -5; - } - - if(!addr){ - addr = bi_addrs[AT8_FP10S_BI]; - } - - status = sysBusToLocalAdrs( VME_AM_SUP_SHORT_IO, addr, &ptr); - if(status<0){ - logMsg("VME shrt IO addr err in the slave fast protect driver\n"); - return(-4); - } - - status = rebootHookAdd(fp_reboot); - if(status<0){ - logMsg("%s: reboot hook add failed\n", __FILE__); - } - - for (i = 0; - (i < bi_num_cards[AT8_FP10S_BI]) && (vxMemProbe(ptr,READ,2,&junk) == OK); - i++,ptr++) { - - /* register initialization */ - ptr->csr = 0x0000; /* disable interface */ - fp[i].fptr = ptr; /* hardware location */ - fp[i].fp_vector = intvec++; /* interrupt vector */ - ptr->ivec = fp[i].fp_vector; /* load vector */ - fp[i].mode = FP_NMSG; /* set default mode (no messages) */ - fp[i].int_num = 0; /* initialize interrupt number */ - fp[i].type = 10; /* board type */ - fp[i].num = i; /* board number */ - - /* initialize input buffer */ - fp[i].drvstat = ptr->srd; /* initialize enable switch data */ - fp[i].drvstat |= ptr->frd<<16; /* initialize fault data */ - fp[i].drvstat |= (ptr->csr & 0xff00)<<16; /* csr status bits */ - - /* set up interrupt handler */ - ptr->csr |= FP_INTLEV<<4; /* level 5 interrupt */ - if (intConnect(INUM_TO_IVEC(fp[i].fp_vector),fp_int,i) != OK) - return(-2); /* abort if can't connect */ - sysIntEnable(FP_INTLEV); - ptr->csr |= 0x0001; - ptr->csr ^= 0x0001; /* clear status bits */ - if (ptr->csr & CSR_OPTIC) - logMsg("fast protect #%d optically coupled\n",i); - else - logMsg("fast protect #%d elecrically coupled\n",i); - - /* start up module */ - fp[i].fptr->csr |= CSR_IEN; /* enable interrupts */ - fp[i].mode = FP_RUN; /* normal run mode */ - scanIoInit(&fp[i].ioscanpvt); - } - fp_num = i - 1; /* record max card # */ - - /* create the semaphore */ - fp_semid = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - if ((int)fp_semid == 0) /* abort if can't create semaphore */ - return(-3); - - return(i); /* return # found */ -} - - -/* - * - * fp_reboot() - * - * turn off interrupts to avoid ctrl X reboot problems - */ -LOCAL -void fp_reboot() -{ - int i; - - if(!fp){ - return; - } - - for (i = 0; i < bi_num_cards[AT8_FP10S_BI]; i++){ - - if(!fp[i].fptr){ - continue; - } - - fp[i].fptr->csr &= ~CSR_IEN; - } -} - - - -/* - * fp_en - * - * interrupt enable/disable - * (toggles the interrupt enable - joh) - * - */ -int fp_en(card) -short card; -{ - - if (card < 0 || (card > fp_num)) - return -1; - fp[card].fptr->csr = fp[card].fptr->csr ^ CSR_IEN; - if (fp[card].fptr->csr & CSR_IEN) - printf("fast protect interrupts enabled\n"); - else - printf("fast protect interrupts disabled\n"); - return 0; -} -/* - * fp_mode - * - * set interrupt reporting mode - * - */ -int fp_mode(card,mode) - short card, mode; -{ - if (card < 0 || (card > fp_num)) - return -1; - fp[card].mode = mode; - return 0; -} -/* - * fp_srd - * - * read current local inputs and enable switches - * - */ -int fp_srd(card,option) - short card; - short option; -{ - if (card > fp_num) return -1; - if (!option) - printf("local inputs = %x enable switches = %x\n",fp[card].fptr->srd & 0xff, - fp[card].fptr->srd>>8); - return fp[card].fptr->srd; -} -/* - * fp_frd - * - * read latched local inputs - * - */ -int fp_frd(card) - short card; -{ - if (card < 0 || (card > fp_num)) - return -1; - return fp[card].fptr->frd & 0xff; -} -/* - * fp_csrd - * - * read csr contents - * - */ -int fp_csrd(card) - short card; -{ - if (card < 0 || (card > fp_num)) - return -1; - return fp[card].fptr->csr & 0xff77; -} -/* - * fp_driver - * - * epics interface to fast protect - * - */ -int fp_driver(card,mask,prval) - register unsigned short card; - unsigned int mask; - register unsigned int *prval; -{ - register unsigned int temp; - - if (card > fp_num) return -1; - temp = fp[card].drvstat & 0xffff0000; /* latched status info */ - temp |= fp[card].fptr->srd; /* current switches & inputs */ - *prval = temp & mask; - return 0; -} -/* - * fp_read - * - * command line interface to fp_driver - * - */ -int fp_read(card) - short card; -{ - unsigned int fpval,ret; - - if ((ret = fp_driver(card,0xffffffff,&fpval)) != 0) - return ret; - printf("Card #%d enable switches = %x inputs = %x\n",card,(fpval & 0x0000ff00)>>8, - fpval & 0x000000ff); - printf("csr status = %x last fault = %x\n",fpval>>24,(fpval & 0x00ff0000)>>16); - printf("raw readback = %x\n",fpval); - return 0; -} -/* - * fp_dump - * - * dump fast protect status to console - * - */ -int fp_dump() -{ - int i; - - printf("Fast protect status (fault and CSR are latched):\n"); - printf("Card#\tenables\tinputs\tfault\tCSR status\n"); - for(i = 0; i < (fp_num + 1); i++) - printf("%d\t%x\t%x\t%x\t%x\n",i,fp[i].fptr->srd>>8,fp[i].fptr->srd & 0xff, - (fp[i].drvstat & 0x00ff0000)>>16,fp[i].drvstat>>24); - return i; -} -/* - * fp_monitor - * - * monitor fast protect cards and report failures to console - * - */ -void fp_mon() -{ - for(semTake(fp_semid,WAIT_FOREVER);fp_dump() != 0;semTake(fp_semid,WAIT_FOREVER)); -} -int fp_monitor() -{ - static char *name = "fpmon"; - int tid; - - if ((tid = taskNameToId(name)) != ERROR) { - taskwdRemove(tid); - taskDelete(tid); - } - if((tid = taskSpawn(name,25,VX_SUPERVISOR_MODE|VX_STDIO, - 1000,fp_mon)) == ERROR) return -1; - taskwdInsert(tid,NULL,NULL); - return 0; -} - -int fp_io_report(level) -int level; -{ - int i; - - for(i=0; i<=fp_num; i++){ - printf("BI: AT8-FP-S: card %d\n", i); - } - return(0); -} - -int fp_getioscanpvt(card,scanpvt) -short card; -IOSCANPVT *scanpvt; -{ - if ((card >= bi_num_cards[AT8_FP10S_BI])) return(0); - *scanpvt = fp[card].ioscanpvt; - return(0); -} diff --git a/src/vxWorks/drv/old/drvFpm.c b/src/vxWorks/drv/old/drvFpm.c deleted file mode 100644 index 3c9daca9e..000000000 --- a/src/vxWorks/drv/old/drvFpm.c +++ /dev/null @@ -1,440 +0,0 @@ -/* drvFpm.c */ -/* base/src/drv $Id$ */ - -/* - * control routines for use with the FP10M fast protect master modules - * - * routines which are used to test and interface with the - * FP10S fast protect module - * - * Author: Matthew Stettler - * Date: 6-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 joh 070992 integrated into GTACS & added std header - * .02 joh 070992 merged in include file fpm.h - * .03 joh 070992 converted some symbols to LOCAL so they stay out - * of the vxWorks global symbol table - * .04 joh 070992 took out sysSetBCL() and substituted - * sysIntEnable() so this will not be hkv2f - * specific. - * .05 joh 070992 added INUM_TO_IVEC so this will be less - * 68k dependence (added include of iv.h) - * .06 joh 070992 FP_ILEV passed to call sysIntEnable() so that the - * interrupt level can be easily changed - * .07 joh 071092 now fetches base addr from module_types.h - * .08 joh 071092 added io report routine - * .09 joh 071092 allocate config structure at run time so that - * the users can adjust the number of cards without - * recompilation - * .10 joh 071092 moved ivec allocation to module_types.h - * .11 joh 072792 added soft reboot int disable - * .12 mrk 090292 added DRVET - * .13 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals - * - * - * Routines: - * - * fpm_init Finds and initializes FP10M cards - * fpm_driver System interface to FP10M modules - * fpm_read Carrier control readback - * fpm_reboot clean up before soft reboots - * - * Daignostic Routines - * fpm_en Enables/disables interrupts (diagnostic enable) - * fpm_mode Sets interrupt reporting mode (logs mode - * changes to console) - * fpm_cdis Disables carrier from console - * fpm_fail Sets carrier failure mode - * fpm_srd Reads current carrier status - * fpm_write Command line interface to fpm_driver - * - * Routines return: - * - * -1 Nonexistent card - * -2 Interrupt connection error - * -3 no memory - * -4 VME short IO bus nonexistent - * 0-2 Successfull completion, or # cards found - * - */ - -static char *sccsId = "@(#)drvFpm.c 1.12\t8/4/93"; - -#include -#include -#include -#include -#include -#include -#include -#include /* in h/68k if this is compiling for a 68xxx */ -#include "module_types.h" -#include -#include - -static long report(); -static long init(); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvFpm={ - 2, - report, - init}; - -static long report() -{ - fpm_io_report(); - return(0); -} - -static long init() -{ - fpm_init(0); - return(0); -} - -/* general constants */ -#define FPM_INTLEV 5 /* interrupt level */ - -/* control register bit definitions */ -#define CR_CDIS 0x1 /* software carrier disable */ -#define CR_FS0 0x2 /* fail select 0 */ -#define CR_FS1 0x4 /* fail select 1 */ -#define CR_FS2 0x8 /* fail select 2 */ -#define CR_I0 0x10 /* interrupt level bit 0 */ -#define CR_I1 0x20 /* interrupt level bit 1 */ -#define CR_I2 0x40 /* interrupt level bit 2 */ -#define CR_IEN 0x80 /* interrupt enable */ - -/* control register mask definitions */ -#define CR_IM 0x70 /* interrupt level mask */ - -/* status register bit definitions */ -#define SR_S0 0x1 /* error sequencer state bit 0 */ -#define SR_S1 0x2 /* error sequencer state bit 1 */ -#define SR_S2 0x3 /* error sequencer state bit 2 */ - -/* status register mask definitions */ -#define SR_EM 0x7 /* error state mask */ - -/* operating modes */ -#define FPM_NMSG 0 /* no messages to console */ -#define FPM_TMSG 1 /* terse messages to console */ -#define FPM_FMSG 2 /* full messages to console */ - -/* register address map for FP10M */ -struct fp10m - { - unsigned short cr; /* control register */ - unsigned short sr; /* status register */ - unsigned short ivec; /* interrupt vector */ - char end_pad[0xff-0x6]; /* pad to 256 byte boundary */ - }; - -/* control structure */ -struct fpm_rec - { - struct fp10m *fmptr; /* pointer to device registers */ - short type; /* device type */ - short num; /* board number */ - short vector; /* interrupt vector */ - short mode; /* operating mode */ - unsigned int int_num; /* interrupt number */ - }; - -static struct fpm_rec *fpm; /* fast protect control structure */ - -static int fpm_num; /* # cards found - 1 */ - -static void fpm_reboot(); - -/* - * fpm_int - * - * interrupt service routine - * - */ -int fpm_int(ptr) - register struct fpm_rec *ptr; -{ - register struct fp10m *regptr; - - regptr = ptr->fmptr; - switch (ptr->mode) - { - case FPM_TMSG: - logMsg("fast protect master interrupt!\n"); - break; - case FPM_FMSG: - logMsg("fast protect master interrupt!\n"); - logMsg("cr = %x sr = %x\n",regptr->cr,regptr->sr & 0x7); - break; - } - ptr->int_num++; - return(0); -} -/* - * fpm_init - * - * initialization for fp10m fast protect master modules - * - */ -int fpm_init(addr) - unsigned int addr; -{ - int i; - short junk; - short intvec = AT8FPM_IVEC_BASE; - struct fp10m *ptr; - int status; - - fpm = (struct fpm_rec *) calloc( - bo_num_cards[AT8_FP10M_BO], - sizeof(*fpm)); - if(!fpm){ - return -3; - } - - if(!addr){ - addr = bo_addrs[AT8_FP10M_BO]; - } - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - addr, - &ptr); - if(status<0){ - logMsg("VME shrt IO addr err in the master fast protect driver\n"); - return -4; - } - - status = rebootHookAdd(fpm_reboot); - if(status<0){ - logMsg("%s: reboot hook add failed\n", __FILE__); - } - - for (i = 0; (i < bo_num_cards[AT8_FP10M_BO]) && (vxMemProbe(ptr,READ,2,&junk) == OK); - i++,ptr++) - { - /* - register initialization - */ - ptr->cr = 0x00; /* disable interface */ - fpm[i].fmptr = ptr; /* hardware location */ - fpm[i].vector = intvec++; /* interrupt vector */ - ptr->ivec = fpm[i].vector; /* load vector */ - fpm[i].mode = FPM_NMSG; /* set default mode (no messages) */ - fpm[i].int_num = 0; /* initialize interrupt number */ - fpm[i].type = 2; /* board type */ - fpm[i].num = i; /* board number */ - /* - set up interrupt handler - */ - ptr->cr |= FPM_INTLEV<<4; /* set up board for level 5 interrupt */ - if (intConnect(INUM_TO_IVEC(fpm[i].vector),fpm_int,&fpm[i]) != OK) - return -2; /* abort if can't connect */ - sysIntEnable(FPM_INTLEV); - } - fpm_num = i - 1; /* record last card # */ - return i; /* return # cards found */ -} - - -/* - * - * fpm_reboot() - * - * turn off interrupts to avoid ctrl X reboot problems - */ -LOCAL -void fpm_reboot() -{ - int i; - - if(!fpm){ - return; - } - - for (i = 0; i < bo_num_cards[AT8_FP10M_BO]; i++){ - - if(!fpm[i].fmptr){ - continue; - } - - fpm[i].fmptr->cr &= ~CR_IEN; - } -} - -/* - * fpm_en - * - * interrupt enable/disable - * (toggles the int enable state - joh) - * - */ -int fpm_en(card) - short card; -{ - if (card < 0 || (card > fpm_num)) - return -1; - fpm[card].fmptr->cr ^= CR_IEN; - if (fpm[card].fmptr->cr & CR_IEN) - printf("fast protect master interrupts enabled\n"); - else - printf("fast protect master interrupts disabled\n"); - return 0; -} -/* - * fpm_mode - * - * set interrupt reporting mode - * - */ -int fpm_mode(card,mode) - short card, mode; -{ - if (card < 0 || (card > fpm_num)) - return -1; - fpm[card].mode = mode; - return 0; -} -/* - * fpm_cdis - * - * carrier disable (1), enable (0) - * - */ -int fpm_cdis(card,disable) - short card, disable; -{ - unsigned short temp; - - if (card < 0 || (card > fpm_num)) - return -1; - temp = fpm[card].fmptr->cr; - temp &= 0xfe; - temp |= (disable & 0x01); - fpm[card].fmptr->cr = temp; - return 0; -} -/* - * fpm_fail - * - * set failure mode - * - */ -int fpm_fail(card,mode) - short card, mode; -{ - unsigned short temp; - - if (card < 0 || (card > fpm_num)) - return -1; - temp = fpm[card].fmptr->cr; - temp &= 0xf1; - temp |= (mode & 0x7)<<1; - fpm[card].fmptr->cr = temp; - return 0; -} -/* - * fpm_srd - * - * read status bits - * - */ -int fpm_srd(card) - short card; -{ - if (card < 0 || ( card > fpm_num)) - return -1; - return fpm[card].fmptr->sr & 0x7; -} -/* - * fpm_driver - * - * epics interface to fast protect master - * - */ -int fpm_driver(card,mask,prval) -register unsigned short card; -unsigned int mask; -register unsigned int prval; -{ - register unsigned int temp; - - if (card > fpm_num) - return -1; - temp = fpm[card].fmptr->cr; - fpm[card].fmptr->cr = (temp & (~mask | 0xf0)) | ((prval & mask) & 0xf); - return 0; -} -/* - * fpm_write - * - * command line interface to fpm_driver - * - */ -int fpm_write(card,val) - short card; - unsigned int val; -{ - return fpm_driver(card,0xffffffff,val); -} -/* - * fpm_read - * - * read the current control register contents (readback) - * - */ -int fpm_read(card,mask,pval) -register unsigned short card; -unsigned int mask; -register unsigned int *pval; -{ - if (card > fpm_num) - return -1; - *pval = fpm[card].fmptr->cr & 0x000f; - return 0; -} - - - -/* - * fpm_io_report() - * - */ -int fpm_io_report(level) -int level; -{ - int i; - - for(i=0; i<=fpm_num; i++){ - printf("BO: AT8-FP-M: card %d\n", i); - } - return(0); -} diff --git a/src/vxWorks/drv/old/drvJgvtr1.c b/src/vxWorks/drv/old/drvJgvtr1.c deleted file mode 100644 index 7ae1e6aad..000000000 --- a/src/vxWorks/drv/old/drvJgvtr1.c +++ /dev/null @@ -1,641 +0,0 @@ -/* drvJgvtr1.c */ -/* base/src/drv $Id$ */ -/* - * Author: Jeff Hill - * Date: 5-89 - * - * 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: - * ----------------- - * 110689 joh print mem not full message only once - * 120789 joh temporary removal of memory full check - * 050190 joh clear ptr to callback prior to calling - * it so they can rearm from inside the callback - * 071190 joh check STD address after cycle complete detected - * to avoid erroneous card misaddressed messages - * 071190 joh internal sample rate status is bit reversed on the - * card- I added a lookup table to untwist it. - * 020491 ges Change taskDelay from 20 to 2 in "jgvtr1DoneTask". - * To allow rearm and data reads from succesive - * waveform scans up thru 10Hz rates. - * 031491 lrd move data into a local memory area for each card - * 090591 joh converted to V5 vxWorks - * 110591 lrd initialization of cards other than 0 not - * allocating data buffer correctly - * 013092 bg added sysBusToLocalAdrs. Added levels to io_report - * and the ability to read out the Joerger's raw values - * in io_report if level is > 1. - * 031992 joh Took the vxMemProbe out of each arm and checked - * the card present bit instead. - * 062592 bg Combined drvJgvtr1.c and jgvtr_driver.c - * 062992 joh removed file pointer argument added to io - * report by bg - * 082792 joh added ANSI C function prototypes - * 080293 mrk added call to taskwdInsert - * 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - */ - -static char *sccsID = "@(#)drvJgvtr1.c 1.17\t9/9/93"; - -/* - * Code Portions - * - * jgvtr1_init() - * jgvtr1_driver(card, pcbroutine, parg) - * jgvtr1_int_service() - * jgvtr1DoneTask() - * jgvtr1_io_report() - * jgvtr1_stat(card) - * - */ - -/* drvJgvtr1.c - Driver Support Routines for Jgvtr1 */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -LOCAL jgvtr1Stat jgvtr1_io_report( - unsigned level -); - -LOCAL jgvtr1Stat jgvtr1_init( - void -); - -#ifdef INTERRUPT_HARDWARE_FIXED -LOCAL void jgvtr1_int_service( - void -); -#endif - -LOCAL void jgvtr1DoneTask( - void -); - -LOCAL jgvtr1Stat jgvtr1_dump( - unsigned card, - unsigned n -); - -LOCAL jgvtr1Stat jgvtr1_stat( - unsigned card, - int level -); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvJgvtr1={ - 2, - jgvtr1_io_report, - jgvtr1_init}; - -static volatile char *stdaddr; -static volatile char *shortaddr; - - -#define JGVTR1MAXFREQ 25.0e6 -/* NBBY - the number of bits per byte */ -#define JGVTR1SHORTSIZE (1<<(NBBY*sizeof(uint8_t))) -#define JGVTR1STDSIZE (1<<(NBBY*sizeof(uint16_t))) -#define JGVTR1_INT_LEVEL 5 -#define JGVTR1BASE(CARD)\ -(shortaddr+wf_addrs[JGVTR1]+(CARD)*JGVTR1SHORTSIZE) -#define JGVTR1DATA(CARD)\ -(stdaddr+wf_memaddrs[JGVTR1]+(CARD)*JGVTR1STDSIZE) - - -/* -Joerger fixed hardware bug by switching to an inverting tristate buffer -where these commands are read from the VME bus. As a result these commands -are complemented. -*/ -#define JGVTR1ARM (~1) -#define JGVTR1START (~2) -#define JGVTR1STOP (~4) - - - -/* -!! our compiler allocates bit fields starting from the ms bit !! -*/ -struct jgvtr1_status{ - volatile unsigned pad:8; - volatile unsigned internal_frequency:3; - volatile unsigned internal_clock:1; - volatile unsigned cycle_complete:1; - volatile unsigned interrupt:1; - volatile unsigned active:1; - volatile unsigned memory_full:1; -}; - -struct jgvtr1_config{ - char present; /* card present */ - char std_ok; /* std addr ok on first read */ - void (*psub) /* call back routine */ - (void *pprm, unsigned nbytes, uint16_t *pData); - void *pprm; /* call back parameter */ - FAST_LOCK lock; /* mutual exclusion */ - uint16_t *pdata; /* pointer to the data buffer */ -}; - -/* amount of data to make available from the waveform */ -#define JRG_MEM_SIZE 2048 - -LOCAL -struct jgvtr1_config *pjgvtr1_config; - -LOCAL -int jgvtr1_max_card_count; - -#ifdef INTERRUPT_HARDWARE_FIXED -LOCAL -SEM_ID jgvtr1_interrupt; /* interrupt event */ -#endif - - - -/* - * JGVTR1_INIT - * - * intialize the driver for the joerger vtr1 - * - */ -jgvtr1Stat jgvtr1_init(void) -{ - unsigned card; - unsigned card_count = 0; - struct jgvtr1_config *pconfig; - uint16_t readback; - jgvtr1Stat status; - - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - 0, - (char **)&shortaddr); - if (status != OK){ - status = S_dev_badA16; - errMessage(status,NULL); - return status; - } - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - 0, - (char **)&stdaddr); - if (status != OK){ - status = S_dev_badA24; - errMessage(status,NULL); - return status; - } - - jgvtr1_max_card_count = wf_num_cards[JGVTR1]; - - if(pjgvtr1_config){ - if(FASTLOCKFREE(&pjgvtr1_config->lock)<0) - return ERROR; - free(pjgvtr1_config); - } - - pjgvtr1_config = - (struct jgvtr1_config *) - calloc(wf_num_cards[JGVTR1], sizeof(*pjgvtr1_config)); - if(!pjgvtr1_config){ - status = S_dev_noMemory; - errMessage(status,NULL); - return status; - } - - for( card=0, pconfig=pjgvtr1_config; - card < wf_num_cards[JGVTR1]; - pconfig++, card++){ - - FASTLOCKINIT(&pconfig->lock); - - status = vxMemProbe( (char *)JGVTR1BASE(card), - READ, - sizeof(readback), - (char *)&readback); - if(status==ERROR) - continue; - - - pconfig->pdata = - (uint16_t *)malloc(JRG_MEM_SIZE); - /* - not easy to test for correct addressing in - standard address space since the module does - not respond if it has not clocked in data - - - so I check this the first time data is ready - */ - pconfig->std_ok = FALSE; /* presumed guilty before tested */ - pconfig->present = TRUE; - card_count++; - } - - if(!card_count) - return OK; - - -# ifdef INTERRUPT_HARDWARE_FIXED - jgvtr1_interrupt = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - if(!jgvtr1_interrupt) - return ERROR; -# endif - - /* start the waveform readback task */ - status = taskSpawn( WFDONE_NAME, - WFDONE_PRI, - WFDONE_OPT, - WFDONE_STACK, - (FUNCPTR) jgvtr1DoneTask, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - if(status < 0){ - status = S_dev_internal; - errMessage(status, "vxWorks taskSpawn failed"); - return status; - } - - taskwdInsert(status, NULL, NULL); - - -# ifdef INTERRUPT_HARDWARE_FIXED - status = intConnect( INUM_TO_IVEC(JGVTR1_INT_VEC), - jgvtr1_int_service, - NULL); - if(status != OK) - return S_dev_internal; - sysIntEnable(JGVTR_INT_LEVEL); -# endif - - return JGVTR1_SUCCESS; -} - - - -/* - * JGVTR1_DRIVER - * - * initiate waveform read - * - */ -jgvtr1Stat jgvtr1_driver( -unsigned card, -void (*pcbroutine)(void *, unsigned, uint16_t *), -void *parg -) -{ - if(card >= jgvtr1_max_card_count) - return S_dev_badSignalNumber; - - if(!pjgvtr1_config[card].present) - return S_dev_noDevice; - - if(pjgvtr1_config[card].psub) - return S_dev_badRequest; - - FASTLOCK(&pjgvtr1_config[card].lock); - - *(volatile uint16_t *)JGVTR1BASE(card) = JGVTR1ARM; - - pjgvtr1_config[card].pprm = parg; - pjgvtr1_config[card].psub = pcbroutine; - - FASTUNLOCK(&pjgvtr1_config[card].lock); - - return JGVTR1_SUCCESS; -} - - -/* - * JGVTR1_INT_SERVICE - * - * signal via the RTK that an interrupt occured from the joerger vtr1 - * - */ -#ifdef INTERRUPT_HARDWARE_FIXED -LOCAL void jgvtr1_int_service(void) -{ - semGive(jgvtr1_interrupt); -} -#endif - - -/* - * JGVTR1DONETASK - * - * wait for joerger vtr1 waveform record cycle complete - * and call back to the database with the waveform size and address - * - */ -LOCAL void jgvtr1DoneTask(void) -{ - unsigned card; - struct jgvtr1_config *pconfig; - struct jgvtr1_status stat; - static char started = FALSE; - volatile uint16_t *pdata; - volatile uint16_t *pjgdata; - long i; - - /* dont allow two of this task */ - if(started) - exit(0); - started = TRUE; - - while(TRUE){ - -# ifdef INTERRUPT_HARDWARE_FIXED - semTake(jgvtr1_interrupt, WAIT_FOREVER); -# else - /* ges: changed from 20 ticks to 2 ticks 2/4/91 */ - taskDelay(2); -# endif - - for( card=0, pconfig = pjgvtr1_config; - card < jgvtr1_max_card_count; - card++, pconfig++){ - - if(!pconfig->present) - continue; - - if(!pconfig->psub) - continue; - - stat = *(struct jgvtr1_status *) JGVTR1BASE(card); - /* - * Wait for the module to finish filling its memory - * or a stop trigger - */ - if(!stat.cycle_complete) - continue; - - /* - clear ptr to function here so they - can rearm in the callback - */ - pconfig->psub = NULL; - /* - check the first time for module - correctly addressed - - card does not respond at STD address - until it has data - */ - if(!pconfig->std_ok){ - uint16_t readback; - int status; - - status = vxMemProbe( - (char *)JGVTR1DATA(card), - READ, - sizeof(readback), - (char *)&readback); - if(status==ERROR){ - errPrintf( - S_dev_badA24, - __FILE__, - __LINE__, - "jgvtr1 card %d incorrectly addressed- use std addr 0X%X", - card, - JGVTR1DATA(card)); - pconfig->present = FALSE; - continue; - } - pconfig->std_ok = TRUE; - } -/* - Test for full memory - ( card designer does not give a sample count register ) - ( instead a bus error returned when on the last sample - to test every location is a lot of overhead so a test - for memory full is used for now ) -*/ - if(!stat.memory_full){ - errMessage(S_dev_internal, - "jgvtr1 driver: proceeding with partial mem"); - errMessage(S_dev_internal, - "jgvtr1 driver: beware of bus errors"); - } - - /* copy the data into a local memory buffer */ - /* this is to avoid any bus errors */ - for(i = 0, - pdata = pconfig->pdata, - pjgdata = (volatile uint16_t *)JGVTR1DATA(card); - i < JRG_MEM_SIZE/sizeof(uint16_t); - i++, pdata++, pjgdata++){ - *pdata = *pjgdata; - } - -/* - Post waveform to the database - perhaps the size must be the size below+1 ? - (Joerger's documentation is not clear here) -*/ - (*pconfig->psub)(pconfig->pprm,JRG_MEM_SIZE,pconfig->pdata); - } - } -} - - - -/* - * - * JGVTR1_IO_REPORT - * - * print status for all cards in the specified joerger - * vtr1 address range - * - * - */ -LOCAL jgvtr1Stat jgvtr1_io_report(unsigned level) -{ - unsigned card; - unsigned nelements; - jgvtr1Stat status; - - for(card=0; card < wf_num_cards[JGVTR1]; card++){ - status = jgvtr1_stat(card,level); - if(status){ - continue; - } - if (level >= 2){ - printf("enter the number of elements to dump:"); - status = scanf("%d",&nelements); - if(status == 1){ - jgvtr1_dump(card, nelements); - } - } - } - return JGVTR1_SUCCESS; -} - - - -/* - * - * JGVTR1_STAT - * - * print status for a single card in the joerger vtr1 address range - * - * - */ -jgvtr1Stat jgvtr1_stat( -unsigned card, -int level -) -{ - struct jgvtr1_status stat; - jgvtr1Stat status; - - /* - internal freq status is bit reversed so I - use a lookup table - */ - - static float sample_rate[8] = { - JGVTR1MAXFREQ/(1<<7), - JGVTR1MAXFREQ/(1<<3), - JGVTR1MAXFREQ/(1<<5), - JGVTR1MAXFREQ/(1<<1), - JGVTR1MAXFREQ/(1<<6), - JGVTR1MAXFREQ/(1<<2), - JGVTR1MAXFREQ/(1<<4), - JGVTR1MAXFREQ/(1<<0)}; - - static char *clock_status[] = - {"ext-clock", "internal-clk"}; - static char *cycle_status[] = - {"cycling", "done"}; - static char *interrupt_status[] = - {"", "int-pending"}; - static char *activity_status[] = - {"", "active"}; - static char *memory_status[] = - {"", "mem-full"}; - - status = vxMemProbe( (char *)JGVTR1BASE(card), - READ, - sizeof(stat), - (char *)&stat); - if(status != OK) - return ERROR; - if (level == 0) - printf("WF: JGVTR1:\tcard=%d \n",card); - else if (level > 0) - printf( "WF: JGVTR1:\tcard=%d Sample rate=%g %s %s %s %s %s \n", - card, - sample_rate[stat.internal_frequency], - clock_status[ stat.internal_clock ], - cycle_status[ stat.cycle_complete ], - interrupt_status[ stat.interrupt ], - activity_status[ stat.active ], - memory_status[ stat.memory_full ]); - - return JGVTR1_SUCCESS; -} - - -/* - * jgvtr1_dump - * - */ -LOCAL jgvtr1Stat jgvtr1_dump( -unsigned card, -unsigned n -) -{ - volatile uint16_t *pjgdata; - uint16_t *pread; - uint16_t *pdata; - unsigned nread; - jgvtr1Stat status; - - /* Print out the data if user requests it. */ - - n = min(JRG_MEM_SIZE,n); - - pdata = (uint16_t *)malloc(n * (sizeof(*pdata))); - if(!pdata){ - return S_dev_noMemory; - } - - pread = pdata; - nread = 0; - pjgdata = (volatile uint16_t *)JGVTR1DATA(card); - while(nread <= (n>>1)){ - status = vxMemProbe( - (char *)pjgdata, - READ, - sizeof(*pread), - (char *)pread); - if(status<0){ - break; - } - nread++; - pread++; - pjgdata++; - } - - for(pread=pdata; pread<&pdata[nread]; pread++){ - if ((pread-pdata)%8 == 0){ - printf("\n\t"); - } - printf( "%02X %02X ", - (unsigned char) ((*pread)>>8), - (unsigned char) *pread); - } - - printf("\n"); - - free(pdata); - - return JGVTR1_SUCCESS; -} diff --git a/src/vxWorks/drv/old/drvJgvtr1.h b/src/vxWorks/drv/old/drvJgvtr1.h deleted file mode 100644 index f4c3f6454..000000000 --- a/src/vxWorks/drv/old/drvJgvtr1.h +++ /dev/null @@ -1,43 +0,0 @@ -/* drvJgvtr1.h */ -/* base/src/drv $Id$ */ -/* - * Author: Jeff Hill - * Date: 5-89 - * - * 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: - * ----------------- - */ - - - -typedef long jgvtr1Stat; - -#define JGVTR1_SUCCESS 0 - -jgvtr1Stat jgvtr1_driver( -unsigned card, -void (*pcbroutine)(void *, unsigned, uint16_t *), -void *parg -); - diff --git a/src/vxWorks/drv/old/module_types.c b/src/vxWorks/drv/old/module_types.c deleted file mode 100644 index e1be8bcd3..000000000 --- a/src/vxWorks/drv/old/module_types.c +++ /dev/null @@ -1,241 +0,0 @@ -/* module_types.c */ -/* base/src/drv $Id$ */ -/* - * Author: Marty Kraimer - * Date: 08-23-93 - * - * 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-23-93 mrk Initial Version - */ - -#include - -int module_types() -{ - -ai_num_cards[AB1771IL] = 12; -ai_num_cards[AB1771IFE] = 12; -ai_num_cards[AB1771IXE] = 12; -ai_num_cards[XY566SE] = 2; -ai_num_cards[XY566DI] = 2; -ai_num_cards[XY566DIL] = 2; -ai_num_cards[VXI_AT5_AI] = 32; -ai_num_cards[AB1771IFE_SE] = 12; -ai_num_cards[AB1771IFE_4to20MA] = 12; -ai_num_cards[DVX2502] = 1; -ai_num_cards[AB1771IFE_0to5V] = 12; -ai_num_cards[KSCV215] = 32; - -ai_num_channels[AB1771IL] = 8; -ai_num_channels[AB1771IFE] = 8; -ai_num_channels[AB1771IXE] = 8; -ai_num_channels[XY566SE] = 32; -ai_num_channels[XY566DI] = 16; -ai_num_channels[XY566DIL] = 16; -ai_num_channels[VXI_AT5_AI] = 8; -ai_num_channels[AB1771IFE_SE] = 16; -ai_num_channels[AB1771IFE_4to20MA] = 8; -ai_num_channels[DVX2502] = 127; -ai_num_channels[AB1771IFE_0to5V] = 8; -ai_num_channels[KSCV215] = 32; - -ai_addrs[AB1771IL] = 0; -ai_addrs[AB1771IFE] = 0; -ai_addrs[AB1771IXE] = 0; -ai_addrs[XY566SE] = 0x6000; -ai_addrs[XY566DI] = 0x7000; -ai_addrs[XY566DIL] = 0x7800; -ai_addrs[VXI_AT5_AI] = 0xc014; -ai_addrs[AB1771IFE_SE] = 0; -ai_addrs[AB1771IFE_4to20MA] = 0; -ai_addrs[DVX2502] = 0xff00; -ai_addrs[AB1771IFE_0to5V] = 0; -ai_addrs[KSCV215] = 0; - -ai_memaddrs[AB1771IL] = 0; -ai_memaddrs[AB1771IFE] = 0; -ai_memaddrs[AB1771IXE] = 0; -ai_memaddrs[XY566SE] = 0x000000; -ai_memaddrs[XY566DI] = 0x040000; -ai_memaddrs[XY566DIL] = 0x0c0000; -ai_memaddrs[VXI_AT5_AI] = 0; -ai_memaddrs[AB1771IFE_SE] = 0; -ai_memaddrs[AB1771IFE_4to20MA] = 0; -ai_memaddrs[DVX2502] = 0x100000; -ai_memaddrs[AB1771IFE_0to5V] = 0; -ai_memaddrs[KSCV215] = 0; - -ao_num_cards[AB1771OFE] = 12; -ao_num_cards[VMI4100] = 4; -ao_num_cards[ZIO085] = 1; -ao_num_cards[VXI_AT5_AO] = 32; - -ao_num_channels[AB1771OFE] = 4; -ao_num_channels[VMI4100] = 16; -ao_num_channels[ZIO085] = 32; -ao_num_channels[VXI_AT5_AO] = 16; - -ao_addrs[AB1771OFE] = 0; -ao_addrs[VMI4100] = 0x4100; -ao_addrs[ZIO085] = 0x0800; -ao_addrs[VXI_AT5_AO] = 0xc000; - -bi_num_cards[ABBI_08_BIT] = 12; -bi_num_cards[ABBI_16_BIT] = 12; -bi_num_cards[BB910] = 4; -bi_num_cards[XY210] = 2; -bi_num_cards[VXI_AT5_BI] = 32; -bi_num_cards[HPE1368A_BI] = 32; -bi_num_cards[AT8_FP10S_BI] = 8; -bi_num_cards[XY240_BI] = 2; - -bi_num_channels[ABBI_08_BIT] = 8; -bi_num_channels[ABBI_16_BIT] = 16; -bi_num_channels[BB910] = 32; -bi_num_channels[XY210] = 32; -bi_num_channels[VXI_AT5_BI] = 32; -bi_num_channels[HPE1368A_BI] = 16; -bi_num_channels[AT8_FP10S_BI] = 32; -bi_num_channels[XY240_BI] = 32; - -bi_addrs[ABBI_08_BIT] = 0; -bi_addrs[ABBI_16_BIT] = 0; -bi_addrs[BB910] = 0xb800; -bi_addrs[XY210] = 0xa000; -bi_addrs[VXI_AT5_BI] = 0xc000; -bi_addrs[HPE1368A_BI] = 0xc000; -bi_addrs[AT8_FP10S_BI] = 0x0e00; -bi_addrs[XY240_BI] = 0x3000; - -bo_num_cards[ABBO_08_BIT] = 12; -bo_num_cards[ABBO_16_BIT] = 12; -bo_num_cards[BB902] = 4; -bo_num_cards[XY220] = 1; -bo_num_cards[VXI_AT5_BO] = 32; -bo_num_cards[HPE1368A_BO] = 32; -bo_num_cards[AT8_FP10M_BO] = 2; -bo_num_cards[XY240_BO] = 2; - -bo_num_channels[ABBO_08_BIT] = 8; -bo_num_channels[ABBO_16_BIT] = 16; -bo_num_channels[BB902] = 32; -bo_num_channels[XY220] = 32; -bo_num_channels[VXI_AT5_BO] = 32; -bo_num_channels[HPE1368A_BO] = 16; -bo_num_channels[AT8_FP10M_BO] = 32; -bo_num_channels[XY240_BO] = 32; - -bo_addrs[ABBO_08_BIT] = 0; -bo_addrs[ABBO_16_BIT] = 0; -bo_addrs[BB902] = 0x0400; -bo_addrs[XY220] = 0xa800; -bo_addrs[VXI_AT5_BO] = 0xc000; -bo_addrs[HPE1368A_BO] = 0xc000; -bo_addrs[AT8_FP10M_BO] = 0xc000; -bo_addrs[XY240_BO] = 0x3000; - -sm_num_cards[CM57_83E] = 4; -sm_num_cards[OMS_6AXIS] = 4; - -sm_num_channels[CM57_83E] = 1; -sm_num_channels[OMS_6AXIS] = 6; - -sm_addrs[CM57_83E] = 0x8000; -sm_addrs[OMS_6AXIS] = 0x4000; - -wf_num_cards[XY566WF] = 2; -wf_num_cards[CAMAC_THING] = 4; -wf_num_cards[JGVTR1] = 4; -wf_num_cards[COMET] = 4; - -wf_num_channels[XY566WF] = 1; -wf_num_channels[CAMAC_THING] = 1; -wf_num_channels[JGVTR1] = 1; -wf_num_channels[COMET] = 4; - -wf_addrs[XY566WF] = 0x9000; -wf_addrs[CAMAC_THING] = 0; -wf_addrs[JGVTR1] = 0xB000; -wf_addrs[COMET] = 0xbc00; - -wf_armaddrs[XY566WF] = 0x5400; -wf_armaddrs[CAMAC_THING]= 0; -wf_armaddrs[JGVTR1] = 0; -wf_armaddrs[COMET] = 0; - -wf_memaddrs[XY566WF] = 0x080000; -wf_memaddrs[CAMAC_THING]= 0; -wf_memaddrs[JGVTR1] = 0xb80000; -wf_memaddrs[COMET] = 0xe0000000; - -tm_num_cards[MZ8310] = 4; -tm_num_cards[DG535] = 1; -tm_num_cards[VXI_AT5_TIME] = 32; - -tm_num_channels[MZ8310] = 10; -tm_num_channels[DG535] = 1; -tm_num_channels[VXI_AT5_TIME] = 10; - -tm_addrs[MZ8310] = 0x1000; -tm_addrs[DG535] = 0; -tm_addrs[VXI_AT5_TIME] = 0xc000; - -AT830X_1_addrs = 0x0400; -AT830X_1_num_cards = 2; -AT830X_addrs = 0xaa0000; -AT830X_num_cards = 2; - -xy010ScA16Base = 0x0000; - -EPICS_VXI_LA_COUNT = 32; -EPICS_VXI_A24_BASE = (char *) 0x900000; -EPICS_VXI_A24_SIZE = 0x100000; -EPICS_VXI_A32_BASE = (char *) 0x90000000; -EPICS_VXI_A32_SIZE = 0x10000000; - - -AI566_VNUM = 0xf8; -DVX_IVEC0 = 0xd0; -MD_INT_BASE = 0xf0; -MZ8310_INT_VEC_BASE = 0xe8; -AB_VEC_BASE = 0x60; -JGVTR1_INT_VEC = 0xe0; -AT830X_1_IVEC0 = 0xd4; -AT830X_IVEC0 = 0xd6; -AT8FP_IVEC_BASE = 0xa2; -AT8FPM_IVEC_BASE= 0xaa; - -BB_SHORT_OFF = 0x1800; -BB_IVEC_BASE = 0xa0; -BB_IRQ_LEVEL = 5; -PEP_BB_SHORT_OFF= 0x1c00; -PEP_BB_IVEC_BASE= 0xe8; - -NIGPIB_SHORT_OFF = 0x5000; -NIGPIB_IVEC_BASE = 100; -NIGPIB_IRQ_LEVEL = 5; - -return(0); -} diff --git a/src/vxWorks/include/camacLib.h b/src/vxWorks/include/camacLib.h deleted file mode 100644 index 0a523c3f0..000000000 --- a/src/vxWorks/include/camacLib.h +++ /dev/null @@ -1,74 +0,0 @@ -/* camacLib.h -- Prototypes for camacLib.o - * - * Marty Wise - * 10/11/93 - * - * $Log$ - * Revision 1.1 1994/10/20 20:16:16 tang - * Commit adding of Camac Driver h file. - * - * Revision 1.4 94/05/11 13:52:57 13:52:57 wise (Marty Wise) - * Added low-level diagnostics - * - * Revision 1.3 94/03/27 10:52:29 10:52:29 wise (Marty Wise) - * *** empty log message *** - * - * Revision 1.1 93/11/05 06:39:35 06:39:35 wise (Marty Wise) - * Initial revision - * - * Revision 0.3 93/10/19 09:03:45 09:03:45 wise (Marty Wise) - * Added cssa and csmad - * - * Revision 0.2 93/10/12 07:33:01 07:33:01 wise (Marty Wise) - * cfubc working, cfmad working, almost ready for alpha release. - * - * Revision 0.1 93/10/11 10:31:48 10:31:48 wise (Marty Wise) - * Initial revision - * - * - * - */ - -static char ht2992_h_RCSID[] = "$Header$"; - -/********************************/ -/* GLOBAL DATA */ -/********************************/ -extern int debug_hook; - -extern struct glob_dat { - int total; - int read_error[5]; - int write_error[5]; - int cmd_error[5]; - int total_err; - int lam_count[12]; -} debug_dat; - - -/********************************/ -/* FUNCTION PROTOTYPES */ -/********************************/ - -void cdreg(int *ext, int b, int c, int n, int a); -void cfsa(int f, int ext, int *dat, int *q); -void cssa(int f, int ext, short *dat, int *q); -void ccci(int ext, int l); -void cccz(int ext); -void cccc(int ext); -void ccinit(int b); -void ctci(int ext, int *l); -void cgreg(int ext, int *b, int *c, int *n, int *a); -void cfmad(int f, int extb[2], int *intc, int cb[4]); -void cfubc(int f, int ext, int *intc, int cb[4]); -void cfubc(int f, int ext, int *intc, int cb[4]); -void csmad(int f, int extb[2], short *intc, int cb[4]); -void ctcd(int ext, int *l); -void cccd(int ext, int l); -void csga(int fa[], int exta[], unsigned short intc[], int qa[], int cb[4]); -void cfga(int fa[], int exta[], int intc[], int qa[], int cb[4]); -void cfubr(int f, int ext, int intc[], int cb[4]); -void csubc(int f, int ext, unsigned short *intc, int cb[4]); -void csubr(int f, int ext, int intc[], int cb[4]); -void print_reg(int ext); - diff --git a/src/vxWorks/include/fast_lock.h b/src/vxWorks/include/fast_lock.h deleted file mode 100644 index c987daa15..000000000 --- a/src/vxWorks/include/fast_lock.h +++ /dev/null @@ -1,191 +0,0 @@ -/* fast_lock.h */ -/* share/epicsH $Id$ */ - -/* - * Author: Jeff Hill - * Date: 4-11-89 - * - * 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 joh 041189 initial release into middle age - * .02 joh 071989 added fast lock test - * .03 joh 090391 VRTX kernel ifdef for V5 vxWorks - * .04 joh 091091 Now uses V5 vxWorks binary semaphore - * .05 joh 092491 Dont use V5 semaphore on V3 EPICS yet - * .06 jba 030692 added cast to vxTas arg in FASTLOCK vxWorks5 - * .07 jba 081092 added cast to vxTas arg in FASTLOCKNOWAIT - * .08 mgb 082493 Removed V5/V4 conditional defines - * .09 joh 082493 include vxLib.h for vxWorks V5.1 - * .10 joh 082593 made lock char as vxTas expects - * (padded structure to identical size) - * .11 joh 082593 made fast lock structure fields volatile - * .12 joh 091493 added sem and task lock based fast locks - * with ifdefs - removed volatile - */ - -/* - * - * - * Macros and data structures for a much faster (than vrtx semaphore) - * mutual exclusion lock/unlock. - * (semaphore in this case is only used to wait for unlock) - * - * On a 68020 the following times include lock and unlock - * - * FASTLOCK-FASTUNLOCK 8 microsecs - * semTake-semGive(Macro) 80 microsecs - * semTake-semGive 92 microsecs - * - */ - -#ifndef INCLfast_lockh -#define INCLfast_lockh - -#ifndef INCLsemLibh -#include -#endif -#ifndef INCLvxLibh -#include -#endif - -/* - * Macro equivalent of vxWorks glue for better performance - */ -#ifdef VRTX_KERNEL -# define semGive(SEMID)\ - { if ((SEMID)->count == 0)vrtxPost (&((SEMID)->count), 1); } - -# define semTake(SEMID)\ - {int dummy; vrtxPend (&((SEMID)->count), 0, &dummy); } -#endif - -typedef struct{ - SEM_ID ppend; /* wait for lock sem */ - unsigned short count; /* cnt of tasks waiting for lock */ - unsigned char lock; /* test and set lock bit */ - char pad; /* structure alignment */ -}FAST_LOCK; - -#define SEM_FAST_LOCK - -#if defined(SEM_FAST_LOCK) /* no lock test */ - -#define FASTLOCKINIT(PFAST_LOCK)\ - (((FAST_LOCK *)(PFAST_LOCK))->ppend = \ - semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY)) -#define FASTLOCKFREE(PFAST_LOCK)\ - semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend ) -#define FASTLOCK(PFAST_LOCK)\ - semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER); -#define FASTUNLOCK(PFAST_LOCK)\ - semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend); -#define FASTLOCKNOWAIT(PFAST_LOCK) \ - ((semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend,NO_WAIT)==0) ? TRUE : FALSE) -#define FASTLOCKTEST(PFAST_LOCK) \ -(\ - (semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend,NO_WAIT)==0 )\ - ? (semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend),FALSE)\ - : TRUE \ -) - - -#elif defined(TASK_LOCK_FAST_LOCK) - -#define FASTLOCKINIT(PFAST_LOCK)\ - (\ - ((FAST_LOCK *)(PFAST_LOCK))->count =0, \ - ((FAST_LOCK *)(PFAST_LOCK))->lock =0, \ - ((FAST_LOCK *)(PFAST_LOCK))->ppend = \ - semBCreate(SEM_Q_PRIORITY, SEM_EMPTY) \ - ) -#define FASTLOCKFREE(PFAST_LOCK)\ - semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend ) - -#define FASTLOCK(PFAST_LOCK)\ - {\ - TASK_LOCK;\ - while( ((FAST_LOCK *)(PFAST_LOCK))->lock ){\ - ((FAST_LOCK *)(PFAST_LOCK))->count++;\ - TASK_UNLOCK;\ - semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER);\ - TASK_LOCK;\ - (((FAST_LOCK *)(PFAST_LOCK))->count)--;\ - }\ - ((FAST_LOCK *)(PFAST_LOCK))->lock= TRUE; - TASK_UNLOCK; - } - -#define FASTUNLOCK(PFAST_LOCK)\ - {\ - ((FAST_LOCK *)(PFAST_LOCK))->lock = FALSE;\ - if( ((FAST_LOCK *)(PFAST_LOCK))->count )\ - semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend);\ - }; - -#define FASTLOCKTEST(PFAST_LOCK)\ -( ((FAST_LOCK *)(PFAST_LOCK))->lock ) - -#else /* vxTas() fast lock */ - -/* - * extra paren avoids order of ops problems - * (returns what semBCreate returns on v5 vxWorks) - */ -#define FASTLOCKINIT(PFAST_LOCK)\ - (\ - ((FAST_LOCK *)(PFAST_LOCK))->count =0, \ - ((FAST_LOCK *)(PFAST_LOCK))->lock =0, \ - ((FAST_LOCK *)(PFAST_LOCK))->ppend = \ - semBCreate(SEM_Q_PRIORITY, SEM_EMPTY) \ - ) - -/* - * new requirement with v5 vxWorks - */ -#define FASTLOCKFREE(PFAST_LOCK)\ - semDelete( ((FAST_LOCK *)(PFAST_LOCK))->ppend ) - -#define FASTLOCK(PFAST_LOCK)\ - {\ - ((FAST_LOCK *)(PFAST_LOCK))->count++;\ - while(!vxTas( (char *)&( ((FAST_LOCK *)(PFAST_LOCK))->lock ) ))\ - semTake(((FAST_LOCK *)(PFAST_LOCK))->ppend, WAIT_FOREVER);\ - ( ((FAST_LOCK *)(PFAST_LOCK))->count)--;\ - } - -#define FASTUNLOCK(PFAST_LOCK)\ - {\ - ((FAST_LOCK *)(PFAST_LOCK))->lock = FALSE;\ - if( ((FAST_LOCK *)(PFAST_LOCK))->count )\ - semGive(((FAST_LOCK *)(PFAST_LOCK))->ppend);\ - }; - -#define FASTLOCKNOWAIT(PFAST_LOCK) (vxTas((char *)&(((FAST_LOCK *)(PFAST_LOCK))->lock))) - -#define FASTLOCKTEST(PFAST_LOCK)\ -( ((FAST_LOCK *)(PFAST_LOCK))->lock ) - -#endif - -#endif /* Nothing after this endif */ diff --git a/src/vxWorks/include/module_types.h b/src/vxWorks/include/module_types.h deleted file mode 100644 index a1cbe1d12..000000000 --- a/src/vxWorks/include/module_types.h +++ /dev/null @@ -1,586 +0,0 @@ -/* module_types.h */ -/* base/include $Id$ */ -/* - * Author: Bob Dalesio - * Date: 12-07-88 - * - * 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-07-88 lrd moved IO_TYPES.H into here - * added interruptable indicator for each io card - * added arrays of pointers for info on the io cards - * .02 02-01-89 lrd add Allen-Bradley Modules - * rearrange I/O card order - * .03 02-04-89 lrd add bus specification - * - * .04 02-06-89 joh add timing int vec # - * .05 02-09-89 lrd move vectors and I/O card base addresses here - * .06 02-11-89 lrd changed AB num cards to 12 and OFE num chan to 4 - * .04 02-13-89 joh fixed length of timing address array - * .05 04-22-89 lrd changed AB num channels to 8 for ABBI cards - * .06 04-24-89 lrd moved AB 6008SV info here - * .07 05-26-89 joh added Joerger VTR1 transient recorder - * .08 09-13-89 lrd add VXI module specification to each type - * remove unused modules - * .09 09-25-89 lrd AB adapters to 8 cards to 16 and IFE channels to - * 8 - * .10 10-17-89 lrd AB changed number of cards from 12 to 16 for - * binary inputs and outputs - * .11 11-21-89 joh fixed card and chnl count for at5 vxi timing - * .12 11-30-89 lrd add the OMS 6 axis motor driver - * .13 12-12-89 joh moved XY220 base to match changes made by the - * hardware section. - * .14 05-16-90 cr add Single Ended IFE module - * .15 05-24-90 mk add 4-20Ma IFE - * .16 05-23-90 lrd/ms add DVX-2502 - * .17 07-19-90 ms changed the mizar interrupt vector to e8 - * wouldn't work with the CMC ethernet card - * used the same interrupt vector - * .18 12-19-90 lrd add 0-5V IFE - * .19 03-26-91 lrd modified the AT5-VXIBO from 16 to 32 - * .20 07-23-91 ges Add AT830X card base addresses and vectors. - * .21 08-14-91 ges Add AT830X_1 card base addresses and ivectors. - * (These are the new gen 8308B and 8309C cards) - * .22 06-24-92 joh added the hp E1368a VXI video switching module - * .23 06-25-92 bg stripped intitial 1 off the standard addresses - * in AB_BASE_ADDR,ai_memaddrs,wf_memaddrs,AT830X_ - * ADDRS, and AT830X_1_ADDRS so they can be mapped - in sysBusToLocalAdrs - * .24 06-25-92 bg stripped initial ff off all short addresses so - they can be mapped in sysBusToLocalAdrs - * .25 06-25-92 bg Moved SM_BASE_ADDR frin oms_driver.h to sm_addrs - in this file. - * .26 06-25-92 bg Moved dvx addresses,interrupt vectors,channel numbers - and card number definitions from dvx_driver.h to here. - - * .26 06-25-92 bg Moved dvx addresses,interrupt vectors,channel numbers - * .27 06-25-92 bg Added definitions for xy240_driver - * .28 06-25-92 bg Removed all reference to the Zio085 - * .29 06-26-92 bg Temporarily returned all reference to the Zio085 - * .30 06-26-92 joh added binary input capability to the hp E1368a - * VXI video switching module - * .31 06-30-92 joh added constant for the number of VXI LA - * .32 07-06-92 joh added base and size VXIA24 & A32 devices - * .33 07-07-92 joh added KSC V215 VXI AI - * .34 07-09-92 joh added AT8 FP10S master/slave fast - * protect module - * .35 07-10-92 joh added FP int vec base - * .36 07-17-92 bg moved addresses for Comet card from drvComet.c to - * here. - * .37 07-23-92 joh number of AI channels for AT5 VXI should be 8 not 6 - * number of BI channels for AT5 VXI should be 32 not 16 - * number of TI channels for AT5 VXI should be 10 not 5 - * (these changes reflect the AT5 hardware upgrade) - * - * .38 08-04-92 joh fixed COMET A16 base addr - * .39 08-10-92 joh number of xy220 cards now matches the AT8 - * address standard - * .40 08-11-92 joh moved xy010 base to here - * .41 08-11-92 joh took out xycom specific defines - * .42 09-15-92 joh DVX num cards was set allowing the DVX to - * overlap the VXI DC address and continue - * outside of VME A16. DVX num cards is now one - * .43 06-18-93 lrd reduced xy220 number of cards to 1 - mv167 mismatch on short address space - * .44 05-05-94 kornke Changed number of supported OMS cards. - */ - -#ifndef INCLmodule_typesh -#define INCLmodule_typesh - -/* Device module types */ -/* - * all devices have corresponding entries in ~operator/db/src/menus.c - * changes must be made in both areas to keep the database and drivers in sync - */ -/* & in comment indicates tested with card 0 */ -/* % in comment indicates tested with card other than card 0 */ -/* # in comment indicates that the Nth card has been tested */ -/* !! never been tested */ - -/* - * @# If any changes are made to this file, check the procedures - * ab_card, and vme_card in signallist.c, and get_address in sigmenu.c. - */ - -#ifdef MODULE_TYPES_INIT -#define MODULE_TYPES_DEF(MT_DEF_PARM) MT_DEF_PARM -#else -#define MODULE_TYPES_DEF(MT_DEF_PARM) extern MT_DEF_PARM; -#endif - -/* Number of columns used in io_report. */ -#define IOR_MAX_COLS 4 - -/* I/O types */ -#define IO_AI 0 -#define IO_AO 1 -#define IO_BI 2 -#define IO_BO 3 -#define IO_SM 4 -#define IO_WF 5 -#define IO_TIMER 6 -#define MAX_IO_TYPE IO_TIMER - -/* bus types */ -/* must correspond to the values in link types */ -/* these defines are in ~gta/dbcon/h/link.h */ - - -/* equates for the Allen-Bradley cards. */ -#define AB_BASE_ADDR 0xc00000 /* base addr of first AB6008SV */ -#define AB_MAX_LINKS 2 /* number of serial links from VME */ -#define AB_MAX_ADAPTERS 8 /* number of physical adapters on a link */ -#define AB_MAX_CARDS 16 /* max number of IO cards per adapter */ -#define AB_CARD_ADAPTER 16 /* cards per logical adapter */ -#define AB_CHAN_CARD 16 /* max channels per card */ - -/* analog inputs */ -#define AB1771IL 0 /* &% Allen-Bradley low level analog input */ -#define AB1771IFE 1 /* &% Allen-Bradley low level analog input */ -#define AB1771IXE 2 /* &% Allen-Bradley millivolt input */ -#define XY566SE 3 /* & Xycom 12-bit Single Ended Scanned*/ -#define XY566DI 4 /* &% Xycom 12-bit Differential Scanned */ -#define XY566DIL 5 /* &% Xycom 12-bit Differential Latched */ -#define VXI_AT5_AI 6 /* % AT-5 VXI module's Analog Inputs */ -#define AB1771IFE_SE 7 /* % A-B IFE in 16 single-ended input mode */ -#define AB1771IFE_4to20MA 8 /* % A-B IFE in 8 double-ended 4to20Ma */ -#define DVX2502 9 /* &% DVX_2502 128 chan 16 bit differential */ -#define AB1771IFE_0to5V 10 /* % A-B IFE in 8 double-ended 4to20Ma */ -#define KSCV215 11 /* % KSC V215 VXI 16 bit differential */ -#define AB1771IrPlatinum 12 /* % A-B RTD Platinum */ -#define AB1771IrCopper 13 /* % A-B RTD Copper */ -#define MAX_AI_TYPES AB1771IrCopper -MODULE_TYPES_DEF(short ai_num_cards[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={12,12,12, 4, 4, 6,32,12,12, 1, 12, 32, 12,12}; -#endif -MODULE_TYPES_DEF(short ai_num_channels[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 8, 8, 8,32,16,16, 8,16, 8, 127, 8, 32,6,6}; -#endif -MODULE_TYPES_DEF(short ai_interruptable[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,0,0}; -#endif -MODULE_TYPES_DEF(short ai_bus[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 4, 2, 2, 2, 2, 4, 4, 2, 4, 2,4,4}; -#endif -MODULE_TYPES_DEF(unsigned short ai_addrs[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0,0x6000,0x7000,0xe000, 0xc014,0,0, 0xff00, 0, 0,0,0}; -#endif -MODULE_TYPES_DEF(long ai_memaddrs[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0,0,0,0x000000,0x040000,0x0c0000, 0,0,0, 0x100000, 0, 0,0,0}; -#endif - -/* analog outputs */ -#define AB1771OFE 0 /* &% Allen-Bradley 12 bit Analog Output */ -#define VMI4100 1 /* & VMIC VMIVME 4100 */ -#define ZIO085 2 /* & Ziomek 085 */ -#define VXI_AT5_AO 3 /* !! AT-5 VXI modules analog outputs */ -#define MAX_AO_TYPES VXI_AT5_AO -MODULE_TYPES_DEF(short ao_num_cards[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = {12, 4, 1, 32}; -#endif -MODULE_TYPES_DEF(short ao_num_channels[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = { 4, 16, 32, 16}; -#endif -MODULE_TYPES_DEF(short ao_interruptable[MAX_AO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 0, 0, 0, 1}; -#endif -MODULE_TYPES_DEF(short ao_bus[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 2, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short ao_addrs[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0x4100,0x0800, 0xc000}; -#endif - -/* binary inputs */ -#define ABBI_08_BIT 0 /* &% Allen-Bradley generic Binary In 8 bit */ -#define ABBI_16_BIT 1 /* &% Allen-Bradley generic Binary In 16 bit */ -#define BB910 2 /* & BURR BROWN MPV 910 (relay) */ -#define XY210 3 /* &% XYcom 32 bit binary in */ -#define VXI_AT5_BI 4 /* !! AT-5 VXI modules binary inputs */ -#define HPE1368A_BI 5 /* !! HP E1368A video switch */ -#define AT8_FP10S_BI 6 /* !! AT8 FP10 slave fast protect */ -#define XY240_BI 7 /* !! Xycom 32 bit binary in / 32 bit binary out */ -#define MAX_BI_TYPES XY240_BI -MODULE_TYPES_DEF(short bi_num_cards[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 12, 12, 4, 4, 32, 32, 8, 2}; -#endif -MODULE_TYPES_DEF(short bi_num_channels[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 16, 32, 32, 32, 16, 32, 32}; -#endif -MODULE_TYPES_DEF(short bi_interruptable[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 1, 1, 0, 0, 1, 1, 1, 1}; -#endif -MODULE_TYPES_DEF(short bi_bus[MAX_BI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 2, 2, 2, 2, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short bi_addrs[MAX_BI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0xb800,0xa000, 0xc000, 0xc000, 0x0e00, 0xd000}; -#endif - -/* binary outputs */ -#define ABBO_08_BIT 0 /* &% Allen-Bradley 8 bit binary out */ -#define ABBO_16_BIT 1 /* &% Allen-Bradley 16 bit binary out */ -#define BB902 2 /* &% BURR BROWN MPV 902 (relay) */ -#define XY220 3 /* &% XYcom 32 bit binary out */ -#define VXI_AT5_BO 4 /* !! AT-5 VXI modules binary outputs */ -#define HPE1368A_BO 5 /* !! HP E1368A video switch */ -#define AT8_FP10M_BO 6 /* !! AT8 FP10 master fast protect */ -#define XY240_BO 7 /* !! Xycom 32 bit binary in / 32 bit binary out */ -#define MAX_BO_TYPES XY240_BO -MODULE_TYPES_DEF(short bo_num_cards[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={12, 12, 4, 1, 32, 32, 2, 2}; -#endif -MODULE_TYPES_DEF(short bo_num_channels[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 16, 32, 32, 32, 16, 32, 32}; -#endif -MODULE_TYPES_DEF(short bo_interruptable[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 0, 0, 0, 0, 1, 0, 0, 1 }; -#endif -MODULE_TYPES_DEF(short bo_bus[MAX_BO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 2, 2, 2, 2, 2, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short bo_addrs[MAX_BO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0xd800,0xc800, 0xc000, 0xc000, 0x0c00, 0xd000}; -#endif - -/* stepper motor drivers */ -#define CM57_83E 0 /* & Compumotor 57-83E motor controller */ -#define OMS_6AXIS 1 /* & OMS six axis motor controller */ -#define MAX_SM_TYPES OMS_6AXIS -MODULE_TYPES_DEF(short sm_num_cards[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 8 }; -#endif -MODULE_TYPES_DEF(short sm_num_channels[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 1, 8}; -#endif -MODULE_TYPES_DEF(short sm_interruptable[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 0, 0 }; -#endif -MODULE_TYPES_DEF(short sm_bus[MAX_SM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 2, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short sm_addrs[MAX_SM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0x8000, 0xfc00 }; -#endif - -/* waveforms */ -#define XY566WF 0 /* & Xycom 566 as a waveform */ -#define CAMAC_THING 1 /* !! CAMAC waveform digitizer */ -#define JGVTR1 2 /* & Joerger transient recorder */ -#define COMET 3 /* !! COMET transient recorder */ -#define MAX_WF_TYPES COMET -MODULE_TYPES_DEF(short wf_num_cards[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={4, 4, 8, 4}; -#endif -MODULE_TYPES_DEF(short wf_num_channels[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={1, 1, 1, 4}; -#endif -MODULE_TYPES_DEF(short wf_interruptable[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = {0, 0, 0, 0}; -#endif -MODULE_TYPES_DEF(short wf_bus[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={2, 3, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short wf_addrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0x9000, 0, 0xB000, 0xbc00}; -#endif -MODULE_TYPES_DEF(unsigned short wf_armaddrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = {0x5400, 0, 0, 0}; -#endif -MODULE_TYPES_DEF(long wf_memaddrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0x080000, 0, 0xb80000, 0xe0000000}; -#endif - - -/* timing cards */ -#define MZ8310 0 /* &% Mizar Timing Module */ -#define DG535 1 /* !! GPIB timing instrument */ -#define VXI_AT5_TIME 2 /* !! AT-5 VXI modules timing channels */ -#define MAX_TM_TYPES VXI_AT5_TIME -MODULE_TYPES_DEF(short tm_num_cards[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 4, 1, 32 }; -#endif -MODULE_TYPES_DEF(short tm_num_channels[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={10, 1, 10}; -#endif -MODULE_TYPES_DEF(short tm_interruptable[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 1, 0, 1 }; -#endif -MODULE_TYPES_DEF(short tm_bus[MAX_TM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 2, 5, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short tm_addrs[MAX_TM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0xf800, 0, 0xc000 }; -#endif - -/* AT830X clock cards */ -MODULE_TYPES_DEF(long AT830X_1_addrs ) -#ifdef MODULE_TYPES_INIT - = 0x0400; -#endif -MODULE_TYPES_DEF(short AT830X_1_num_cards ) -#ifdef MODULE_TYPES_INIT - = 2; -#endif -MODULE_TYPES_DEF(long AT830X_addrs ) -#ifdef MODULE_TYPES_INIT - = 0xaa0000; -#endif -MODULE_TYPES_DEF(short AT830X_num_cards ) -#ifdef MODULE_TYPES_INIT - = 2; -#endif - -/* - * system controller cards. - * (driver looks for only one card) - */ -MODULE_TYPES_DEF(long xy010ScA16Base) -#ifdef MODULE_TYPES_INIT - = 0x0000; -#endif -/* - * limit the size of the VXI logical address space - * - * = + 0xc000 - * - * LA VME address - * 0 - * EPICS_VXI_LA_COUNT + (EPICS_VXI_LA_COUNT-1)*64 - */ -MODULE_TYPES_DEF(unsigned char EPICS_VXI_LA_COUNT) -#ifdef MODULE_TYPES_INIT - = 32; -#endif - -/* - * - * address ranges for VXI A24 and A32 devices - * - */ -MODULE_TYPES_DEF(char *EPICS_VXI_A24_BASE) -#ifdef MODULE_TYPES_INIT - = (char *) 0x900000; -#endif -MODULE_TYPES_DEF(unsigned long EPICS_VXI_A24_SIZE) -#ifdef MODULE_TYPES_INIT - = 0x100000; -#endif -MODULE_TYPES_DEF(char *EPICS_VXI_A32_BASE) -#ifdef MODULE_TYPES_INIT - = (char *) 0x90000000; -#endif -MODULE_TYPES_DEF(unsigned long EPICS_VXI_A32_SIZE) -#ifdef MODULE_TYPES_INIT - = 0x10000000; -#endif - - -/****************************************************************************** - * - * Interrupt vector locations used by the MV167 CPU board. - * These are defined in mv167.h - * - * PCC2_INT_VEC_BASE 0x40 PCC interrupt vector base number - * any multiple of 0x10 - * UTIL_INT_VEC_BASE0 0x50 VMEchip2 utility interrupt - * vector base number - * any multiple of 0x10 - * UTIL_INT_VEC_BASE1 0x60 VMEchip2 utility interrupt - * vector base number - * any multiple of 0x10 - * - * INT_VEC_CD2400_A 0x90 int vec for channel A - * INT_VEC_CD2400_B 0x94 int vec for channel B - * INT_VEC_CD2400_C 0x98 int vec for channel C - * INT_VEC_CD2400_D 0x9c int vec for channel D - * - * LANC_IRQ_LEVEL 3 LNANC IRQ level - * MPCC_IRQ_LEVEL 4 serial comm IRQ level - * SYS_CLK_LEVEL 6 interrupt level for sysClk - * AUX_CLK_LEVEL 5 interrupt level for auxClk - * SCSI_IRQ_LEVEL 2 scsi interrupt level - * - ******************************************************************************/ - -/* interrupt vector allocation - one for each XY566 DIL card */ -MODULE_TYPES_DEF(int AI566_VNUM) -#ifdef MODULE_TYPES_INIT - =0xf8; /* Xycom 566 Differential Latched */ -#endif - -/* interrupt vector allocation - one for each DVX card */ -MODULE_TYPES_DEF(int DVX_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd0; -#endif - -/* stepper motor interrupt vector - one for each motor */ -MODULE_TYPES_DEF(int MD_INT_BASE) -#ifdef MODULE_TYPES_INIT - =0xf0; /* base of the motor int vector */ -#endif - -/* I reserve from here up to num_cards * 4 interrupting chans/card - joh */ -MODULE_TYPES_DEF(int MZ8310_INT_VEC_BASE) -#ifdef MODULE_TYPES_INIT - =0xe8; -#endif - -/* Allen-Bradley Serial Driver - MAX_AB_LINKS number of vectors */ -MODULE_TYPES_DEF(int AB_VEC_BASE) -#ifdef MODULE_TYPES_INIT - =0x60; -#endif - -/* only one interrupt vector allocated for all Joerger VTR1 boards joh */ -MODULE_TYPES_DEF(int JGVTR1_INT_VEC) -#ifdef MODULE_TYPES_INIT - =0xe0; -#endif - -/* AT830X_1 cards have 1 intr vector for each AT830X_1_num_cards (presently 2) */ -MODULE_TYPES_DEF(int AT830X_1_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd4; -#endif - -/* AT830X cards have 1 intr vector for each AT830X_num_cards (presently 2) */ -MODULE_TYPES_DEF(int AT830X_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd6; -#endif - -/* AT8 fast protect interrupt vector base */ -MODULE_TYPES_DEF(int AT8FP_IVEC_BASE) -#ifdef MODULE_TYPES_INIT - =0xa2; -#endif - - -MODULE_TYPES_DEF(int AT8FPM_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - =0xaa; -#endif - - -/****************************************************************************** - * - * Addresses and IRQ information used by the XVME402 bitbus cards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short BB_SHORT_OFF ) -#ifdef MODULE_TYPES_INIT - = 0x1800; /* the first address of link 0's region */ -#endif -#define BB_NUM_LINKS 4 /* max number of BB ports allowed */ -MODULE_TYPES_DEF(int BB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 0xa0; /* vectored interrupts (2 used for each link) */ -#endif -MODULE_TYPES_DEF(int BB_IRQ_LEVEL ) -#ifdef MODULE_TYPES_INIT - = 5; /* IRQ level */ -#endif - -/****************************************************************************** - * - * Information for the PEP modular Bitbus boards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short PEP_BB_SHORT_OFF ) -#ifdef MODULE_TYPES_INIT - = 0x1c00; -#endif -MODULE_TYPES_DEF(int PEP_BB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 0xe8; -#endif - -/****************************************************************************** - * - * Addresses and IRQ information used by the NI1014 and NI1014D bitbus cards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short NIGPIB_SHORT_OFF) -#ifdef MODULE_TYPES_INIT - = 0x5000;/* First address of link 0's region */ -#endif - /* Each link uses 0x0200 bytes */ -#define NIGPIB_NUM_LINKS 4 /* Max number of NI GPIB ports allowed */ -MODULE_TYPES_DEF(int NIGPIB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 100; /* Vectored interrupts (2 used for each link) */ -#endif -MODULE_TYPES_DEF(int NIGPIB_IRQ_LEVEL ) -#ifdef MODULE_TYPES_INIT - =5; /* IRQ level */ -#endif - -#if 0 /* JRW */ -#define NI1014_LINK_NUM_BASE 0 -#endif - -/* - * nothing after this endif - */ -#endif /*INCLmodule_typesh*/ diff --git a/src/vxWorks/include/task_params.h b/src/vxWorks/include/task_params.h deleted file mode 100644 index b8002bb78..000000000 --- a/src/vxWorks/include/task_params.h +++ /dev/null @@ -1,267 +0,0 @@ -/* $Id$ */ - -/* Parameters for tasks on IOC */ -/* - * Authors: Andy Kozubal, Jeff Hill, and Bob Dalesio - * Date: 2-24-89 - * - * 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 07-23-91 ges Add time-stamp task. - * .02 09-12-91 joh stack sizes increased for v5 vxWorks. - * .03 10-24-91 lrd Increased stack sizes for scan tasks - * .04 12-12-91 joh Increased stack size for the - * wfDoneTask - * .05 12-18-91 mrk Added callback task priorities - * Changed def of PERIODSCAN_PRI and SEQUENCER_PRI - * Shortened length of task names - * .06 12-18-91 jba Global change of WDSCAN to TASKWD - * .07 01-21-92 rcz Increased all stack sizes by 1000 for V5 - * .08 01-21-92 jrw added the GPIB & BB driver task info - * .09 01-04-92 jba Added callback task priorities - * .10 03-16-92 jrw added BB rx and tx specific task info - * .11 05-22-92 lrd added the allen-bradley binary input Change of State scanner - * .12 08-26-92 joh added xy 240 stuff - * .13 08-26-92 joh added FP to CA repeater and on line to be safe - * .14 02-16-92 joh removed historical items - * .15 11-19-93 joh moved CA client priority up by one notch - * .16 09-13-93 joh incresed CA on line beacon maximum delay - * to 60 sec - * .17 03-18-94 mcn added entries for breakpoint tasks - * $Log$ - * Revision 1.3 1998/05/20 21:00:43 mrk - * raised DB_CA_PRI to just higher than sequencer - * - * Revision 1.2 1998/01/20 21:49:54 mrk - * added the arch_stack_factor for 64 bit architectures; changes for errlog - * - * Revision 1.1 1996/11/22 20:49:43 jhill - * installed - * - * Revision 1.1 1996/06/24 13:32:35 mrk - * added task_params.h - * - * Revision 1.3 1996/06/19 20:48:44 jhill - * dounled ca stack for each ca cleint in the server - * - * Revision 1.2 1996/04/22 14:31:08 mrk - * Changes for dynamic link modification - * - * Revision 1.1 1996/01/25 21:13:29 mrk - * moved includes; .ascii=> .db; path changes - * - * Revision 1.27 1995/11/29 19:27:59 jhill - * added $Log$ - * added Revision 1.3 1998/05/20 21:00:43 mrk - * added raised DB_CA_PRI to just higher than sequencer - * added - * added Revision 1.2 1998/01/20 21:49:54 mrk - * added added the arch_stack_factor for 64 bit architectures; changes for errlog - * added - * added Revision 1.1 1996/11/22 20:49:43 jhill - * added installed - * added - * added Revision 1.1 1996/06/24 13:32:35 mrk - * added added task_params.h - * added - * added Revision 1.3 1996/06/19 20:48:44 jhill - * added dounled ca stack for each ca cleint in the server - * added - * added Revision 1.2 1996/04/22 14:31:08 mrk - * added Changes for dynamic link modification - * added - * added Revision 1.1 1996/01/25 21:13:29 mrk - * added moved includes; .ascii=> .db; path changes - * added - * - */ - -#ifndef INCtaskLibh -#include -#endif - -#define VXTASKIDSELF 0 - -/* Task Names */ -#define EVENTSCAN_NAME "scanEvent" -#define SCANONCE_NAME "scanOnce" -#define SMCMD_NAME "smCommand" -#define SMRESP_NAME "smResponse" -#define ABDONE_NAME "abDone" -#define ABSCAN_NAME "abScan" -#define ABCOS_NAME "abBiCosScanner" -#define MOMENTARY_NAME "momentary" -#define WFDONE_NAME "wfDone" -#define SEQUENCER_NAME "sequencer" -#define BKPT_CONT_NAME "bkptCont" -#define SCANNER_NAME "scanner" -#define REQ_SRVR_NAME "CA TCP" -#define CA_CLIENT_NAME "CA client" -#define CA_EVENT_NAME "CA event" -#define CAST_SRVR_NAME "CA UDP" -#define CA_REPEATER_NAME "CA repeater" -#define CA_ONLINE_NAME "CA online" -#define TASKWD_NAME "taskwd" -#define SMIOTEST_NAME "smInout" -#define SMROTTEST_NAME "smRotate" -#define EVENT_PEND_NAME "event task" -#define XY240_NAME "xy 240 scan" -#define GPIBLINK_NAME "gpibLink" -#define BBLINK_NAME "bbLinkTask" -#define BBTXLINK_NAME "bbTx" -#define BBRXLINK_NAME "bbRx" -#define BBWDTASK_NAME "bbwd" -#define ERRLOG_NAME "errlog" -#define LOG_RESTART_NAME "logRestart" - -/* Task priorities */ -#define SCANONCE_PRI 85 /* scan one time */ -/*DO NOT RUN ANY RECORD PROCESSING TASKS AT HIGHER PRIORITY THAN _netTask=50*/ -#define CALLBACK_PRI_LOW 85 /* callback task - generall callback task */ -#define CALLBACK_PRI_MEDIUM 75 /* callback task - generall callback task */ -#define CALLBACK_PRI_HIGH 71 /* callback task - generall callback task */ -#define EVENTSCAN_PRI 72 /* Event Scanner - Runs on a global event */ -#define SMCMD_PRI 62 /* Stepper Motor Command Task - Waits for cmds */ -#define SMRESP_PRI 63 /* Stepper Motor Resp Task - Waits for resps */ -#define ABCOS_PRI 63 /* Allen-Bradley Binary Input COS io_event wakeup */ -#define ABDONE_PRI 64 /* Allen-Bradley Resp Task - Interrupt Driven */ -#define ABSCAN_PRI 65 /* Allen-Bradley Scan Task - Base Rate .1 secs */ -#define BBLINK_PRI 66 -#define BBWDTASK_PRI 65 /* BitBus watchdog task */ -#define BBRXLINK_PRI 66 /* BitBus link task */ -#define BBTXLINK_PRI 67 /* BitBus link task */ -#define GPIBLINK_PRI 67 /* GPIB link task */ -#define MOMENTARY_PRI 68 /* Momentary output - posted from watchdog */ -#define WFDONE_PRI 69 /* Waveform Task - Base Rate of .1 second */ -#define PERIODSCAN_PRI 78 /* Periodic Scanners - Slowest rate */ -#define DB_CA_PRI 88 /*database to channel access*/ -#define SEQUENCER_PRI 90 -#define XY240_PRI 111 /* xy 240 dio scanner */ -#define SCANNER_PRI 150 -#define REQ_SRVR_PRI 181 /* Channel Access TCP request server*/ -#define CA_CLIENT_PRI 180 /* Channel Access clients */ -#define CA_REPEATER_PRI 181 /* Channel Access repeater */ -#define ERRLOG_PRI CA_REPEATER_PRI /*error logger task*/ -#define CAST_SRVR_PRI 182 /* Channel Access broadcast server */ -#define CA_ONLINE_PRI 183 /* Channel Access server online notify */ -#define TASKWD_PRI 200 /* Watchdog Scan Task - runs every 6 seconds */ -#define SMIOTEST_PRI 205 /* Stepper Mtr in/out test - runs every .1 sec */ -#define SMROTTEST_PRI 205 /* Stepper Mtr rotate test - runs every .1 sec */ -#define LOG_RESTART_PRI 200 /* Log server connection watch dog */ - -/* Task delay times (seconds) */ -#define TASKWD_DELAY 6 - -/* Task delay times (tics) */ -#define ABSCAN_RATE (sysClkRateGet()/6) -#define SEQUENCER_DELAY (sysClkRateGet()/5) -#define SCANNER_DELAY (sysClkRateGet()/5) -#define CA_ONLINE_DELAY (sysClkRateGet()*15) -#define LOG_RESTART_DELAY (sysClkRateGet()*30) - -/* Task creation options */ -#define ERRLOG_OPT VX_FP_TASK -#define EVENTSCAN_OPT VX_FP_TASK -#define SCANONCE_OPT VX_FP_TASK -#define CALLBACK_OPT VX_FP_TASK -#define SMCMD_OPT VX_FP_TASK -#define SMRESP_OPT VX_FP_TASK -#define ABDONE_OPT VX_FP_TASK -#define ABCOS_OPT VX_FP_TASK -#define ABSCAN_OPT VX_FP_TASK -#define MOMENTARY_OPT VX_FP_TASK -#define PERIODSCAN_OPT VX_FP_TASK -#define WFDONE_OPT VX_FP_TASK -#define SEQUENCER_OPT VX_FP_TASK | VX_STDIO -#define BKPT_CONT_OPT VX_FP_TASK -#define SCANNER_OPT VX_FP_TASK -#define REQ_SRVR_OPT VX_FP_TASK -#define CAST_SRVR_OPT VX_FP_TASK -#define CA_CLIENT_OPT VX_FP_TASK -#define CA_REPEATER_OPT VX_FP_TASK -#define CA_ONLINE_OPT VX_FP_TASK -#define TASKWD_OPT VX_FP_TASK -#define SMIOTEST_OPT VX_FP_TASK -#define SMROTTEST_OPT VX_FP_TASK -#define EVENT_PEND_OPT VX_FP_TASK -#define GPIBLINK_OPT VX_FP_TASK|VX_STDIO -#define BBLINK_OPT VX_FP_TASK|VX_STDIO -#define BBTXLINK_OPT VX_FP_TASK|VX_STDIO -#define BBRXLINK_OPT VX_FP_TASK|VX_STDIO -#define BBWDTASK_OPT VX_FP_TASK|VX_STDIO -#define DB_CA_OPT (VX_FP_TASK | VX_STDIO) -#define XY_240_OPT (0) /* none */ -#define LOG_RESTART_OPT (VX_FP_TASK) - - -/* - * Task stack sizes - * - * (original stack sizes are appropriate for the 68k) - * ARCH_STACK_FACTOR allows scaling the stacks on particular - * processor architectures - */ -#if CPU_FAMILY == MC680X0 -#define ARCH_STACK_FACTOR 1 -#elif CPU_FAMILY == SPARC -#define ARCH_STACK_FACTOR 2 -#else -#define ARCH_STACK_FACTOR 2 -#endif - -#define ERRLOG_STACK (4000*ARCH_STACK_FACTOR) -#define EVENTSCAN_STACK (11000*ARCH_STACK_FACTOR) -#define SCANONCE_STACK (11000*ARCH_STACK_FACTOR) -#define CALLBACK_STACK (11000*ARCH_STACK_FACTOR) -#define SMCMD_STACK (3000*ARCH_STACK_FACTOR) -#define SMRESP_STACK (3000*ARCH_STACK_FACTOR) -#define ABCOS_STACK (3000*ARCH_STACK_FACTOR) -#define ABDONE_STACK (3000*ARCH_STACK_FACTOR) -#define ABSCAN_STACK (3000*ARCH_STACK_FACTOR) -#define MOMENTARY_STACK (2000*ARCH_STACK_FACTOR) -#define PERIODSCAN_STACK (11000*ARCH_STACK_FACTOR) -#define WFDONE_STACK (9000*ARCH_STACK_FACTOR) -#define SEQUENCER_STACK (5500*ARCH_STACK_FACTOR) -#define BKPT_CONT_STACK (11000*ARCH_STACK_FACTOR) -#define SCANNER_STACK (3048*ARCH_STACK_FACTOR) -#define RSP_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define REQ_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define CAST_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define CA_CLIENT_STACK (11000*ARCH_STACK_FACTOR) -#define CA_REPEATER_STACK (5096*ARCH_STACK_FACTOR) -#define CA_ONLINE_STACK (3048*ARCH_STACK_FACTOR) -#define TASKWD_STACK (2000*ARCH_STACK_FACTOR) -#define SMIOTEST_STACK (2000*ARCH_STACK_FACTOR) -#define SMROTTEST_STACK (2000*ARCH_STACK_FACTOR) -#define EVENT_PEND_STACK (5096*ARCH_STACK_FACTOR) -#define TIMESTAMP_STACK (4000*ARCH_STACK_FACTOR) -#define GPIBLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBRXLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBTXLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBWDTASK_STACK (5000*ARCH_STACK_FACTOR) -#define DB_CA_STACK (11000*ARCH_STACK_FACTOR) -#define XY_240_STACK (4096*ARCH_STACK_FACTOR) -#define LOG_RESTART_STACK (0x1000*ARCH_STACK_FACTOR) - diff --git a/src/vxWorks/libvxWorks/epicsDynLink.c b/src/vxWorks/libvxWorks/epicsDynLink.c deleted file mode 100644 index af7f12aa2..000000000 --- a/src/vxWorks/libvxWorks/epicsDynLink.c +++ /dev/null @@ -1,53 +0,0 @@ -/* $Id $ - * - * Comments from original version: - * On the MIPS processor, all symbols do not have the prepended underscore. - * Here we redefine symFindByName to look at the second character of the - * name string. - * - * On various RISC processors (at least MIPS and PPC), symbols do not have - * the prepended underscore. Here we redefine symFindByName so that, if the - * name lookup fails and if the first character of the name is "_", the - * lookup is repeated starting at the second character of the name string. - * - * 01a,08apr97,bdg created. - * 02a,03apr97,npr changed from mips.h into symFindByNameMips.c - * 03a,03jun98,wfl changed Mips -> EPICS and avoid architecture knowledge - */ - -#include "epicsDynLink.h" - -STATUS symFindByNameEPICS( SYMTAB_ID symTblId, - char *name, - char **pvalue, - SYM_TYPE *pType ) -{ - STATUS status; - - status = symFindByName( symTblId, name, pvalue, pType ); - - if ( status == ERROR && name[0] == '_' ) - status = symFindByName( symTblId, (name+1), pvalue, pType ); - - return status; -} - -STATUS symFindByNameAndTypeEPICS( - SYMTAB_ID symTblId, - char *name, - char **pvalue, - SYM_TYPE *pType, - SYM_TYPE sType, - SYM_TYPE mask ) -{ - STATUS status; - - status = symFindByNameAndType( symTblId, name, pvalue, - pType, sType, mask ); - - if ( status == ERROR && name[0] == '_' ) - status = symFindByNameAndType( symTblId, (name+1), pvalue, - pType, sType, mask ); - - return status; -} \ No newline at end of file diff --git a/src/vxWorks/libvxWorks/epicsDynLink.h b/src/vxWorks/libvxWorks/epicsDynLink.h deleted file mode 100644 index 77ed6b40b..000000000 --- a/src/vxWorks/libvxWorks/epicsDynLink.h +++ /dev/null @@ -1,33 +0,0 @@ - -/* - * These routines will eventually need to be made OS independent - * (currently this is vxWorks specific) - */ - -#ifndef epicsDynLinkh -#define epicsDynLinkh - -#ifdef symFindByName -#undef symFindByName -#endif - -#include "vxWorks.h" -#include "symLib.h" -#include "sysSymTbl.h" - -STATUS symFindByNameEPICS( - SYMTAB_ID symTblId, - char *name, - char **pvalue, - SYM_TYPE *pType); - -STATUS symFindByNameAndTypeEPICS( - SYMTAB_ID symTblId, - char *name, - char **pvalue, - SYM_TYPE *pType, - SYM_TYPE sType, - SYM_TYPE mask); - -#endif /* ifdef epicsDynLinkh */ - diff --git a/src/vxWorks/libvxWorks/veclist.c b/src/vxWorks/libvxWorks/veclist.c deleted file mode 100644 index 9eed2b36e..000000000 --- a/src/vxWorks/libvxWorks/veclist.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * $Id$ - * @(#)veclist.c 1.10 - * - * list fuctions attached to the interrupt vector table - * - * Created 28Mar89 Jeffrey O. Hill - * johill@lanl.gov - * (505) 665 1831 - * - * .01 010393 Applied fix for zero C ISR param causes incorrect - * identification as MACRO ISR problem. - * .02 022195 Compiler warnings fixed - * $Log$ - * Revision 1.15 1998/03/16 17:01:27 mrk - * include string.h - * - * Revision 1.14 1996/09/04 22:08:50 jhill - * fixed gcc warnings - * - * Revision 1.13 1995/08/12 01:12:37 jhill - * doc - * - */ - -/* - * - * makefile - * - * - * V5VW = /.../vx/v502b - * - * veclist.o: - * cc68k -c -DCPU_FAMILY=MC680X0 -I$(V5VW)/h veclist.c - * - * - */ - -#include "vxWorks.h" -#include "stdio.h" -#include "string.h" -#include "intLib.h" -#include "vxLib.h" -#include "iv.h" -#include "ctype.h" -#include "sysSymTbl.h" - -static char *sccsID = - "@(#) $Id$"; - -/* - * - * VME bus dependent - * - */ -#define NVEC 0x100 - -static char *ignore_list[] = {"_excStub","_excIntStub"}; - -int veclist(int); -int cISRTest(FUNCPTR proutine, FUNCPTR *ppisr, void **pparam); -static void *fetch_pointer(unsigned char *); - - -/* - * - * veclist() - * - */ -int veclist(int all) -{ - int vec; - int value; - SYM_TYPE type; - char name[MAX_SYS_SYM_LEN]; - char function_type[10]; - FUNCPTR proutine; - FUNCPTR pCISR; - int cRoutine; - void *pparam; - int status; - unsigned i; - - for(vec=0; vec