Files
epics-base/modules/database/src/ioc/db/cvtBpt.c

202 lines
4.9 KiB
C

/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* SPDX-License-Identifier: EPICS
* EPICS Base is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* cvtBpt.c - Convert using breakpoint table
*
* Author: Marty Kraimer
* Date: 04OCT95
* This is adaptation of old bldCvtTable
*/
#include "epicsPrint.h"
#include "cvtTable.h"
#include "dbAccess.h"
#include "dbBase.h"
#include "dbStaticLib.h"
static brkTable *findBrkTable(short linr)
{
dbMenu *pdbMenu;
pdbMenu = dbFindMenu(pdbbase,"menuConvert");
if (!pdbMenu) {
epicsPrintf("findBrkTable: menuConvert not loaded!\n");
return NULL;
}
if (linr < 0 || linr >= pdbMenu->nChoice) {
epicsPrintf("findBrkTable: linr=%d but menuConvert only has %d choices\n",
linr,pdbMenu->nChoice);
return NULL;
}
return dbFindBrkTable(pdbbase,pdbMenu->papChoiceValue[linr]);
}
/* Used by both ao and ai record types */
long cvtRawToEngBpt(double *pval, short linr, short init,
void **ppbrk, short *plbrk)
{
double val = *pval;
long status = 0;
brkTable *pbrkTable;
brkInt *pInt, *nInt;
short lbrk;
int number;
if (linr < 2)
return -1;
if (init || *ppbrk == NULL) {
pbrkTable = findBrkTable(linr);
if (!pbrkTable)
return S_dbLib_badField;
*ppbrk = pbrkTable;
*plbrk = 0;
} else
pbrkTable = (brkTable *)*ppbrk;
number = pbrkTable->number;
lbrk = *plbrk;
/* Limit index to the size of the table */
if (lbrk < 0)
lbrk = 0;
else if (lbrk > number-2)
lbrk = number-2;
pInt = & pbrkTable->paBrkInt[lbrk];
nInt = pInt + 1;
if (nInt->raw > pInt->raw) {
/* raw values increase down the table */
while (val > nInt->raw) {
lbrk++;
pInt = nInt++;
if (lbrk > number-2) {
status = 1;
break;
}
}
while (val < pInt->raw) {
if (lbrk <= 0) {
status = 1;
break;
}
lbrk--;
nInt = pInt--;
}
} else {
/* raw values decrease down the table */
while (val <= nInt->raw) {
lbrk++;
pInt = nInt++;
if (lbrk > number-2) {
status = 1;
break;
}
}
while(val > pInt->raw) {
if (lbrk <= 0) {
status = 1;
break;
}
lbrk--;
nInt = pInt--;
}
}
*plbrk = lbrk;
*pval = pInt->eng + (val - pInt->raw) * pInt->slope;
return status;
}
/* Used by the ao record type */
long cvtEngToRawBpt(double *pval, short linr, short init,
void **ppbrk, short *plbrk)
{
double val = *pval;
long status = 0;
brkTable *pbrkTable;
brkInt *pInt, *nInt;
short lbrk;
int number;
if (linr < 2)
return -1;
if (init || *ppbrk == NULL) { /*must find breakpoint table*/
pbrkTable = findBrkTable(linr);
if (!pbrkTable)
return S_dbLib_badField;
*ppbrk = pbrkTable;
/* start at the beginning */
*plbrk = 0;
} else
pbrkTable = (brkTable *)*ppbrk;
number = pbrkTable->number;
lbrk = *plbrk;
/* Limit index to the size of the table */
if (lbrk < 0)
lbrk = 0;
else if (lbrk > number-2)
lbrk = number-2;
pInt = & pbrkTable->paBrkInt[lbrk];
nInt = pInt + 1;
if (nInt->eng > pInt->eng) {
/* eng values increase down the table */
while (val > nInt->eng) {
lbrk++;
pInt = nInt++;
if (lbrk > number-2) {
status = 1;
break;
}
}
while (val < pInt->eng) {
if (lbrk <= 0) {
status = 1;
break;
}
lbrk--;
nInt = pInt--;
}
} else {
/* eng values decrease down the table */
while (val <= nInt->eng) {
lbrk++;
pInt = nInt++;
if (lbrk > number-2) {
status = 1;
break;
}
}
while (val > pInt->eng) {
if (lbrk <= 0) {
status = 1;
break;
}
lbrk--;
nInt = pInt--;
}
}
*plbrk = lbrk;
*pval = pInt->raw + (val - pInt->eng) / pInt->slope;
return status;
}