/***************************************************************************/
/*
*/
/* int Mode07(int Last)
*/
/*
*/
/* Purpose: Process all
of the Dose Modes
*/
/*
*/
/* Calls: ClearMode
*/
/*
ClearModePars
*/
/*
DelayMsg
*/
/*
DoseCalc
*/
/*
GetOptPar
*/
/*
KS_delay
*/
/*
KS_signal
*/
/*
TestParms
*/
/*
WaitMsg
*/
/*
*/
/* Macros: ALARM_OFF
*/
/*
ALARM_ON
*/
/*
ALTERNATE
*/
/*
FOREVER
*/
/*
HISTLOG
*/
/*
SHOWMSG
*/
/*
STUFFMSG
*/
/*
WAITCHAR
*/
/*
*/
/* Inputs: extern
int mode flags
*/
/*
Last: Last key struck
*/
/*
*/
/* Outputs: int: Last key
struck
*/
/*
*/
/* Dependencies: none.
*/
/* Err Conditions: none.
*/
/*
*/
/* Notes: This
function gets control when the user enters a Dose */
/*
Mode Option number to enter a Dose Mode.
*/
/*
*/
/* History: 09/27/94 -
JSS: Stub-Routine.
*/
/*
07/28/95 - J W: Beginning with only handling ugkm in */
/*
this function, add the Mcg/Kg/Min Dose */
/*
Mode in Mode07().
*/
/*
31/10/95 - J W: Dump it all and start over --
*/
/*
Copy code from Mode04, Piggyback. */
/*
11/02/95 - J W: Add developed DoseCalc function.
*/
/*
11/03/95 - J W: Get clean compile and link.
*/
/*
11/09/95 - J W: Put in infusion schedule index 0.
*/
/*
Remove test loop.
*/
/*
11/15/95 - J W: Replace !DPFLAG with DPFLAGMASK
*/
/*
Add RATE ERR / PUSH ENTR and ALL CLR */
/*
if the calculated rate is out of range */
/*
11/16/95 - J W: Make sure that Dose Calc gets its data */
/*
set up where it is called.
*/
/*
11/17/95 - J W: Do not reset runvol if mode was already */
/*
present.
*/
/*
11/17/95 - J W: Check in for preliminary version, 2.44, */
/*
and check out again to continue work. */
/*
11/21/95 - J W: Change PPigPar to POptPar and
*/
/*
PShowPigMsg to PShowParMsg. Change */
/*
the name of GetPigPar() to GetOptPar */
/*
and add the *Ch function parameter to */
/*
it. Add int ParCh in Mode07 for it. */
/*
11/22/95 - J W: Rewrite processing to provide the
*/
/*
illusion to the user of being in a */
/*
continuous loop even if RATE ERR occurs */
/*
Primary values get overwritten upon */
/*
successful Dose Mode setup.
*/
/*
11/22/95 - LSO: Clear running seconds and running
*/
/*
volume
*/
/*
counters when runvol is set
*/
/*
11/27/95 - J W: Update rate.value before it needs to be */
/*
displayed.
*/
/*
11/27/95 - J W: Move subroutines to after main function */
/*
11/28/95 - J W: Require ENTER or CLEAR after RATE ERR, */
/*
not just any key.
*/
/*
Just do modeflag = NORMAL to clear opt */
/*
Move clearing operations to a function */
/*
11/29/95 - J W: Beep in case of RATE ERR.
*/
/*
Turn alarm off after RATE ERR 2 min */
/*
wait
*/
/*
if any C_ message is received.
*/
/*
Do not echo rate if user pressed RUN to */
/*
go directly to run.
*/
/*
Removed #if-ed out block for VolCh. */
/*
Make sure Dose Mode doesn't linger with */
/*
unexpected settings if non-normal exit. */
/*
Move SHOWMSGs to here in case of
*/
/*
ClearMode call, to allow more general */
/*
use of ClearMode. Use ClearMode in case */
/*
of non-key messages during access here- */
/*
only when modifiable.
*/
/*
11/30/95 - J W: Do not push any KeyCode if returning */
/*
with IGNORE.
*/
/*
RUN must now exit OK, not IGNORE. */
/*
12/01/95 - J W: Primary mode must be handled correctly */
/*
returning OK with RUN.
*/
/*
Keep user in here if RUN was pressed, */
/*
even if no parameters are set.
*/
/*
12/04/95 - J W: At valid rate echo, do not update rate */
/*
.value if the calculation was not done, */
/*
which is when Notmodifiable. This */
/*
prevents a rate of zero from being */
/*
displayed when review is done when pump */
/*
is running or in Keylock.
*/
/*
Do not even display any rate when not */
/*
modifiable and not even in Dose Mode */
/*
yet, because there is no meaning to it */
/*
then.
*/
/*
12/07/95 - J W: Make sure that normal battery and power */
/*
related messages do not cause kick-out. */
/*
Change concept of volume updating so */
/*
that it only happens when there was no */
/*
previous volume. Must also copy over */
/*
pflags in that case.
*/
/*
Do ClearMode in final mode setup to */
/*
properly clear Dose Mode and Primary */
/*
Mode if there was a valid Dose Mode */
/*
previously set.
*/
/*
Let Options key gain access to the */
/*
parameter list in case of RATE ERR. */
/*
Change volume error message to ERR ml */
/*
Add blip in case CLEAR is pushed during */
/*
or after RATE ERR. Allow power off */
/*
after RATE ERR.
*/
/*
Let Options take user back to top of */
/*
the list.
*/
/*
12/08/95 - J W: Swap concentration volume and drug mass */
/*
(mg) in the order of parameters so that */
/*
you see mg first, as you would expect */
/*
for concentration.
*/
/*
12/15/95 - J W: Put Dose prompt first, per Kathy's
*/
/*
suggestion, then put concentration and */
/*
then patient mass.
*/
/*
12/15/95 - J W: Put specific MAX_RATE range checking */
/*
external to DoseCalc to make it general.*/
/*
Add declaration of the DoseCalc
*/
/*
function
*/
/*
12/19/95 - J W: Add setting of parmflag for parameter */
/*
value tracking.
*/
/*
01/09/96 - J W: Add setting of pflags for the
*/
/*
calculated rate. Why didn't this bug */
/*
appear before?
*/
/*
01/22/96 - J W: Change the infusion volume setting so */
/*
that it is cleared if setting up a */
/*
Dose Mode for the first time.
*/
/*
01/24/96 - J W: Delete some unused code. Use the
*/
/*
GOTRATE flag if a non-normal exit makes */
/*
the rate invalid, and go back to the */
/*
parameter user was on before the non- */
/*
normal exit occurred -- or the first */
/*
zero one.
*/
/*
01/25/96 - J W: Restore the option.value for error
*/
/*
display in case power-off happened. */
/*
01/29/96 - J W: Add MODEWASOK flag to make sure that */
/*
the status of Dose Mode will be
*/
/*
remembered in the case of abnormal */
/*
events. Re-set option.value in case */
/*
power-off happened.
*/
/*
Add an OPT CLRD display if exiting due */
/*
to having all of the parameters cleared */
/*
01/31/96 - J W: Add the ability to calculate the Dose */
/*
from the rate if called using C_RATE. */
/*
02/06/96 - J W: Fix bug in clearing MODEWASOK at the */
/*
beginning of the program -- must use */
/*
MODEWASOKMASK to avoid clearing the */
/*
whole statusflag. This fixed a FIX 99 */
/*
that appeared when the pump was running */
/*
under Primary Mode and this module was */
/*
accessed.
*/
/*
Make sure that the calculated dose is */
/*
still updated to the display if RUN is */
/*
pressed right after rate is changed. */
/*
02/07/96 - J W: Add message that we are not in the
*/
/*
mode selected and that the user should */
/*
push stop to set up this option mode. */
/*
02/08/96 - J W: Make OPTIONS key stay in during the
*/
/*
STOP PUMP / TO SET message.
*/
/*
Add DelayMsg calls at every D_OPT_CLRD */
/*
to replace the KS_Delays, to allow the */
/*
user the ability to press a key rather */
/*
than waiting.
*/
/*
02/14/96 - J W: Display resulting Ml/h rather than RATE */
/*
after calculation.
*/
/*
02/15/96 - J W: Added OPT CODE at end of STOP PUMP / TO */
/*
SET. Removed the initial clearing block */
/*
because it's not used anymore.
*/
/*
Removed the display of rate or dose */
/*
because it's not needed anymore. That */
/*
saves many lines of code.
*/
/*
02/21/96 - J W: Put the initial clearing block back in */
/*
because it is indeed used.
*/
/*
02/26/96 - J W: Add "blip" (short blank-out) after each */
/*
parameter, in order to clearly separate */
/*
them and indicate to the user that */
/*
deliberate steps are being made.
*/
/*
Use Ch to help indicate whether or not */
/*
to display the PUSH ENTR prompt.
*/
/*
Display RATE HIGH or RATE LOW, or DOSE */
/*
HIGH, or DOSE LOW, if the calculation */
/*
yields an out of range value. Display */
/*
DOSE ERR or RATE ERR if Dose Calc can't */
/*
handle the inputs.
*/
/*
03/04/96 - J W: Internal change: replace lengthy if
*/
/*
tests of parameters with ParmTest(). */
/*
03/05/96 - J W: Fix and streamline return conditions; */
/*
incorporate WaitMsg().
*/
/*
03/06/96 - J W: Use STUFFMSG and make the VOLUME
*/
/*
key accepted to set the vtbi
*/
/*
03/07/96 - J W: Clear MODEWASOK whenever setting
*/
/*
DOSEMODE1 in modeflag for the first */
/*
time.
*/
/*
03/12/96 - J W: Move clear of Volume to the beginning */
/*
of the function, because Dose Mode has */
/*
been set to stay even if abnormal cond- */
/*
itions occur and if the user decides to */
/*
back out, too bad -- he's lost his pri */
/*
volume.
*/
/*
03/13/96 - J W: Fix having to push CLEAR twice if
*/
/*
accessing fully set-up mode by pushing */
/*
OPTIONS, 5,0, then CLEAR, by excepting */
/*
the CLEAR key for redisplay of title */
/*
bar on first time in.
*/
/*
Fix problem in which GOTRATE needs to */
/*
be reasserted if we got in here during */
/*
Keylock by clearing GOTRATE from the */
/*
volume limit.
*/
/*
03/14/96 - J W: Allow RUN to work right away from the */
/*
OPT 50 display if OPTIONS 5,0 typed. */
/*
03/25/96 - J W: Clear review statusflag when returning */
/*
Set REVIEW and Review following the */
/*
internal PUSH ENTR prompt so that it */
/*
doesn't get repeated incorrectly. */
/*
Make the wait sent to WaitMsg for the */
/*
local PUSH RUN prompt 100ms shorter. */
/*
05/13/96 - J W: Correct statusflag &= MODEWASOK to
*/
/*
statusflag &= MODEWASOKMASK where we */
/*
are clearing it when *first* setting */
/*
the dose mode flag.
*/
/*
05/16/96 - LSO: Added support for history log
*/
/*
06/05/96 - LSO: Removed handling of power-status msgs */
/*
07/29/96 - J W: Move clearing of parameters from Clear */
/*
Mode to here
*/
/*
08/01/96 - J W: Allow RUN to prompt for parameters if */
/*
pressed following a calculation error. */
/*
08/07/96 - J W: Integrate support for the history log. */
/*
08/15/96 - J W: ClearMode() now no longer takes any
*/
/*
parameter.
*/
/*
09/18/96 - J W: Determine more thoroughly whether to */
/*
set the DPFLAG.
*/
/*
09/20/96 - J W: Always clear the rate when selecting */
/*
this Mode while the pump is in another. */
/*
09/25/96 - J W: Replace the handling of the power
*/
/*
status messages to keep the non-cata- */
/*
-strophic power changes transparent to */
/*
the user.
*/
/*
10/04/96 - J W: Change dosemodeugkm to dosemodedose, */
/*
preparatory to adding the rest of the */
/*
Dose Modes.
*/
/*
10/07/96 - J W: Convert value in PARAMs to a pointer to */
/*
the value.
*/
/*
10/14/96 - J W: Break all chains of two ='s involving */
/*
structure items in arrays to ward off */
/*
compiler bugs.
*/
/*
11/08/96 - CMA: First, stubbed-out Mode07 and made
*/
/*
Mode08 a test routine to test the new */
/*
structures (see top of file) for all */
/*
the Dose Modes.
*/
/*
11/10/96 - J W: Then, re-stub Mode08 and restore Mode07 */
/*
with the display codes changed to */
/*
reflect the new Dose Mode display msg */
/*
code naming scheme.
*/
/*
11/14/96 - J W: Changed DOSEMODE1 to DOSEMODE.
*/
/*
11/16/96 - J W: Incorporated the general Mode07 routine */
/*
under development since Nov. 6th, for */
/*
all Dose Modes and continued rewriting */
/*
and generalizing it.
*/
/*
11/17/96 - J W: Incorporated D_set_msg and D_val_msg; */
/*
no longer using PShowParMsg.
*/
/*
11/18/96 - J W: Built it up and filled it in using the */
/*
previous version as a guide.
*/
/*
11/19/96 - J W: Continued building it up and filling it */
/*
in referring also to pprogram.c.
*/
/*
11/20/96 - J W: Go over it and make it work.
*/
/*
11/21/96 - J W: Continue going over it.
*/
/*
11/22/96 - J W: Set the current Dose Mode upon success; */
/*
continue going over the whole function. */
/*
11/23/96 - J W: Went over it again in continuing to
*/
/*
develop it, for OPTIONS pressed and */
/*
Titration. Exit Rate-to-dose if Dose is */
/*
out of range.
*/
/*
11/25/96 - J W: Revised the description of Titration */
/*
(comments only)
*/
/*
11/26/96 - J W: Made sure to maintain the correct
*/
/*
disp_val_msg in the current parameter */
/*
while in the parameter acquisition and */
/*
display loop.
*/
/*
Oops, forgot to copy over the Option */
/*
Clear block.
*/
/*
Have to update pdmspecs when doing an */
/*
abnormal exit, so that the pump doesn't */
/*
just wake up back in DOSE ugkm.
*/
/*
11/27/96 - J W: Send OPTIONS out under "IGNORE" in
*/
/*
order to be able to more easily give it */
/*
priority in the calling function over */
/*
the parmflags and prevent infinite */
/*
loops. Added some action under
*/
/*
"SOMESET" at the exit to properly set */
/*
the pump if OPTIONS pressed for the OPT */
/*
# / DOSE <type> / PUSH ENTR prompt. */
/*
12/02/96 - J W: Debugged the appearance of the error */
/*
msg, which wasn't showing up; needed to */
/*
use only the DMRetCode != OK condition. */
/*
12/03/96 - J W: Because we're no longer clearing
*/
/*
GOTRATE to proceed from the vtbi
*/
/*
display to the PUSH ENTR prompt, we */
/*
don't need to restore the rate if in */
/*
Keylock, and so most cases of !Pumprun */
/*
can be changed back to Notmodifiable. */
/*
Only need to set ratetodose in one */
/*
place now.
*/
/*
12/04/96 - J W: Continue optionspressedinsetup back
*/
/*
into here so that GoThru can be set if */
/*
the OPT # / DOSE <name> / PUSH ENTR */
/*
prompt was induced -- and clear it */
/*
at every abnormal exit before then, */
/*
now. Don't need a ClearModePars if all */
/*
are clear at exit.
*/
/*
12/04/96 - J W: Removed the temporary clearing of the */
/*
minimum rate setting. Restore the rate */
/*
value message for the Primary Mode. */
/*
12/05/96 - J W: Clear ratetodose following each exit */
/*
from the list of parameters. Add VOL */
/*
and OFF as keys accepted when <calc> */
/*
<err> message is displayed.
*/
/*
12/06/96 - J W: Make a small move to set GoThru true if */
/*
ratetodose is true, rather than setting */
/*
it only if setting ratetodose, because */
/*
ratetodose might be previously set, by */
/*
routines in Pnormal1.
*/
/*
Break out of the param acq. loop if */
/*
Titrating so as to look at only the */
/*
rate or dose.
*/
/*
12/08/96 - J W: Keep user in FOREVER loop if Titrating; */
/*
don't just break out if Notmodifiable. */
/*
This fixes a bug in which an out-of- */
/*
range calculation was being ignored and */
/*
the incorrect Dose spec being accepted */
/*
while the pump continued to run at the */
/*
same rate.
*/
/*
12/09/96 - J W: Clear secondssofar and volumesofar if */
/*
Titrating successfully in order to keep */
/*
track of the pumped volume correctly. */
/*
12/12/96 - J W: Removed MODEWASOK from the software. It */
/*
is not needed now that the pump returns */
/*
to the Primary Mode when exiting from */
/*
an Option Mode.
*/
/*
12/12/96 - J W: Added restoration of the rate if doing */
/*
rate-to-dose with all parameters set up */
/*
and the calculation goes out of range. */
/*
12/16/96 - J W: Must clear secondssofar and volumesofar */
/*
upon total success unconditionally. */
/*
12/17/96 - J W: Re-show the parameter value after the */
/*
brief blank-out in case the pump goes */
/*
to some unexpected timeout like when */
/*
the roller clamp is placed in the */
/*
between position, without doing another */
/*
SHOWMSG. Do not stuff ENTER upon
*/
/*
exiting.
*/
/*
12/18/96 - J W: Rather, stuff an ENTER key if it was */
/*
received while showing the calculated */
/*
result / PUSH RUN prompt. Do this */
/*
display even if the pump is in Keylock. */
/*
12/18/96 - LSO: Moved display "blip" to after the
*/
/*
priority exit (don't delay exit)
*/
/*
12/20/96 - J W: Don't need to restore any display after */
/*
the "blip", now. (See 12/17 above) */
/*
Skip the calculation while Titrating if */
/*
no change was made to the parameter. */
/*
Fixed bug in which RUN wasn't stopping */
/*
the pump when pressed at the Opt # / */
/*
DOSE <type> / PUSH ENTR prompt, by */
/*
always stuffing the KeyCode, even when */
/*
the pump is running - removed the */
/*
!Pumprun condition from the OK KeyCode */
/*
stuffing at the exit at the end of this */
/*
routine.
*/
/*
12/29/96 - J W: Maintain option no to show if cleared */
/*
01/03/97 - J W: Fix bug in which pressing OPTIONS
*/
/*
during the setup of other option modes */
/*
causes the user to get stuck in "SET / */
/*
OPT CODE".
*/
/*
01/04/97 - J W: Continued developing the fix for that */
/*
bug.
*/
/*
01/29/97 - J W: Moved setting of GetOptPar - specific */
/*
variables into the case in which Get- */
/*
OptPar is actually going to be called. */
/*
02/05/97 - J W: Made a comment change; added FALSE
*/
/*
maintenance of ShowInfoMsg.
*/
/*
02/05/97 - LSO: Revised WAITCHAR and WaitMsg calls to */
/*
add / CLKTICK
*/
/*
02/11/97 - J W: Added rejection of pre-existing bad
*/
/*
parms.
*/
/*
02/12/97 - J W: Continued modifying for rejection of */
/*
pre-existing bad parameters. No longer */
/*
clear the dose parameter if the list */
/*
does not compute.
*/
/*
02/13/97 - J W: ...continued
*/
/*
02/18/97 - J W: Removed unnecessary setting of DPFLAGs */
/*
02/21/97 - J W: Fixed bug of missing initial setting of */
/*
DMRetCode = OK; fixed bug in which the */
/*
pump was not remaining in Dose Mode if */
/*
after first time setup, there was a */
/*
calculation out-of-range error (and all */
/*
of the parameters were being cleared at */
/*
reentry.
*/
/*
02/25/97 - J W: Added a warning double beep if the rate */
/*
has not been changed following
*/
/*
Titration being selected.
*/
/*
Fixed a potential bug in which saved_- */
/*
while_titrating would not have gotten */
/*
set properly if RATE was pressed while */
/*
Titrating during the error or unchanged */
/*
message display. Used Ch in the final */
/*
total success decision because it is */
/*
easier, smaller, and more consistent, */
/*
fixing a bug caused by relying on */
/*
ratetodose being set after an unchanged */
/*
while Titrating error message. Added */
/*
some parentheses to the priority exit */
/*
there. Changed Temp to CalcResult for */
/*
better readibility.
*/
/*
02/26/97 - J W: Revised the error and no-change-in-
*/
/*
titration beep-pause code to stream- */
/*
line it.
*/
/*
03/03/97 - J W: Revised to use the special new Titr- */
/*
ation alarm code. Fixed a bug in which */
/*
the x ml/h / PUSH RUN message was being */
/*
displayed twice following a dose error */
/*
message in a rate-to-dose operation */
/*
when the pump was previously all set up */
/*
and in a Dose Mode at the PUSH RUN */
/*
prompt.
*/
/*
03/04/97 - J W: Fixed a bug in which the RUN key was */
/*
failing to stop the pump if pressed */
/*
during Titration.
*/
/*
03/06/97 - J W: Moved generation of the Titration no-go */
/*
alarm if the typed-in value didn't */
/*
change, to GetOptPar, where the alarm */
/*
can easily be generated in all req'd */
/*
places.
*/
/*
03/10/97 - LSO: Replaced C_LEVNOTOPEN in limit tests */
/*
with C_LASTMSG.
*/
/*
03/14/97 - J W: Comment change only, to the Titration */
/*
explanation.
*/
/*
04/09/97 - J W: Moved in the definition of GoThru
*/
/*
04/25/97 - J W: New format of DelayMsg.
*/
/*
05/02/97 - J W: Added directional error messages for */
/*
parameters.
*/
/*
06/04/97 - J W: Used separate two-second specification */
/*
instead of BLINKON for one-time info */
/*
messages; added a slight shortening of */
/*
alternation pauses to prevent re- */
/*
flashing.
*/
/*
06/09/97 - J W: Don't need ALTREDUC in TWOSEC, esp. w. */
/*
only the single display.
*/
/*
06/17/97 - J W: Added support for variable Dose param */
/*
decimal places.
*/
/*
06/18/97 - J W: Revised max bound check on previously */
/*
existing parameters (won't be any for */
/*
now) to use CheckMax, which tests the */
/*
variable number of decimal places; */
/*
added clear of the Dose param's s.f. */
/*
and other support for the sfexp.
*/
/*
06/19/97 - J W: Added history logging of the variable */
/*
number of decimal places, for the Dose */
/*
parameter only.
*/
/*
06/24/97 - J W: Revised history logging of the varscale */
/*
parameter (currently only the dose) to */
/*
encode the scale factor in the same log */
/*
entry as the mantissa.
*/
/*
06/25/97 - J W: Revised to add varscale history-logging */
/*
of patient mass and IV solute amount in */
/*
kilounits.
*/
/*
07/01/97 - J W: Included all sfexps in clearing of the */
/*
parameters of new Dose Modes.
*/
/*
07/07/97 - J W: Added History-logging of the calculated */
/*
Dose parameter value in rate-to-dose. */
/*
Now the History log will show a Dose */
/*
and a rate, one after the other, after */
/*
a rate was logged at user entry (other */
/*
parameters are not entered in rate-to- */
/*
dose unless they are missing).
*/
/*
07/09/97 - LSO: Revised history log value calculations */
/*
to use more efficient shift instead of */
/*
long multiply.
*/
/*
07/14/97 - J W: Added the required History message type */
/*
for the History-logging of the calcu- */
/*
lated dose amount and moved logging of */
/*
the new running rate to only be in the */
/*
case of dose-to-rate.
*/
/*
07/21/97 - J W: Revised to clear the ENTER key if
*/
/*
pressed during "STOP PUMP / TO SET / */
/*
OPT CODE", which will prevent unwanted */
/*
titrations if the pump is running in a */
/*
dose mode.
*/
/*
07/22/97 - J W: Revised to maintain the correct scale */
/*
factor for most of the parameters. */
/*
Removed incorrect placement of clearing */
/*
of ratetodose if OPTIONS pressed to go */
/*
to the OPT # / DOSE <name> / PUSH ENTR */
/*
prompt.
*/
/*
09/11/97 - J W: Added EightCharDispAllowed in case of */
/*
units.
*/
/*
09/15/97 - J W: Added setting of the D_units_msg.
*/
/*
09/23/97 - J W: Removed checking for kuns when history */
/*
logging, since kuns will not be used */
/*
any more.
*/
/*
12/12/97 - J W: Added support for Delayed Start.
*/
/*
12/29/97 - J W: Revised to exit the Delayed Run mode if */
/*
only in Delayed End and a Dose Mode is */
/*
set up or changed.
*/
/*
12/30/97 - J W: Revised to use ClrDlydEnd to exit Dlyd */
/*
End.
*/
/*
01/13/98 - J W: Revised not to clear runvol at entry */
/*
to this function when clearing
*/
/*
volumevalue and the GOTVOL parmflag; */
/*
clearing those latter two should be */
/*
sufficient to make the pump request a */
/*
new volume; runvol=1 is needed to */
/*
determine if pump is in Delayed End. */
/*
Revised to do ClrDlydEnd if clearing */
/*
out of the mode because parameters */
/*
were left zero, even if in Primary Mode */
/*
still.
*/
/*
01/28/98 - J W: Revised for the new separate Delayed */
/*
Start and End modeflags.
*/
/*
11/03/98 - CMA: Revised to send a message to the
*/
/*
history log stating that the option has */
/*
been cleared when the user passes thru */
/*
the setup without entering values or if */
/*
the CLEAR key is pressed explicitly to */
/*
clear the mode.
*/
/*
11/20/98 - CMA: Removed the work of the previous entry. */
/*
ClearModeCore now handles this.
*/
/*
11/30/98 - CMA: Added code to record the rate and dose */
/*
calculations in the history log, as */
/*
well as the rate value at which the */
/*
pump has been set to run.
*/
/*
12/03/98 - CMA: Fixed a bug in logging the calculated */
/*
dose amount that ignored decimal point */
/*
placement.
*/
/*
05/31/99 - J W: Revised to detect optionugot in order */
/*
to set GoThru; deleted clearing of */
/*
optionspressedinsetup at the beginning, */
/*
because GetUOptions has been revised */
/*
not to set that any more.
*/
/*
*/
/***************************************************************************/
int Mode07(int Last)
{
/* VARIABLES:
*/
static MSG CtrlMsg;
/* main ctrl mbox msg element */
static HLE_MSG HistMsg;
/* message for History Log Entry */
unsigned long CalcResult = 0;
/* Hold result of DoseCalc until OK */
char CalcQFracDigs = 0;
/* Hold result of Dose SF until OK */
int DMRetCode;
/* Error return for sub functions */
int GoThru;
/* eliminates nested Get functions */
/* -causes stop at each parameter */
int ParNum;
/* which parm in Mode's parm list */
int Ch;
/* whether a parm has changed */
int Ii;
/* loop counter
*/
/* Whether any parameter was changed while going through
the list of */
/* parameters.
*/
int ParCh = FALSE;
/* Hold previous rate until good new rate
*/
unsigned long SavedRate = 0;
/* CODE:
*/
KeyCode = Last;
/* Switch to global variable */
ShowInfoMsg = FALSE;
/* No extra info msgs in Dose Modes */
/* Detect the current Dose Mode being looked at
*/
/* Find the Option Number that was typed in or that
is being looked at */
if (optionugot == 0)
/* If zero, we only could have gotten in here if a Dose
Mode was set */
/* up. Restore info from NVRAM (see Mode19() for a similar
approach) */
{
pdmspecsm07 = pdmspecs;
/* Which is it?
*/
localoptno = (long)pdmspecs->OptCode;
}
else
/* Came from GetUOptions
*/
{
localoptno = optionugot;
/* pdmspecsm07 set in GetUOptions */
}
/* Otherwise, if it was set, pdmspecsm07 was set in
GetUOptions (qv) */
Pumprun = statusflag & PUMPRUN;
/* set up the convenient booleans */
Keylock = statusflag & KEYBDLOCK;
Notmodifiable = Pumprun || Keylock;
Modifiable = !Notmodifiable;
Review = statusflag & REVIEW;
/* Exit with message to user if pump already running
in another mode */
if (
(Pumprun)
&&
/* But not if Titrating
*/
!Titrating
&&
/* Not in Dose Mode or in Dose
Mode and not in this Dose Mode */
/* ie DM' + (DM.S') = (DM'+DM).(DM'+S')
= DM'+S' =
*/
(
!(modeflag & DOSEMODE)
||
(pdmspecsm07 != pdmspecs)
)
)
{
ALTERNATE(3);
SHOWMSG(D_STOP_PUMP);
SHOWMSG(D_TO_SET);
SHOWMSG(D_SET_OPT2);
/* "OPT CODE"
*/
WAITCHAR((3*BLINKON-ALTREDUC)
/ CLKTICK);
/* does not push KeyCode */
/* IGNORE in GetUOptions causes
look at KeyCode, and if returning */
/* to Running, which it won't,
because it can't be called from */
/* Running, because it is not
running in this mode in the first */
/* place, KeyCode will be pushed.
*/
if (KeyCode == C_ENTER)
/* Might cause probs if in Dose */
KeyCode
= C_NULL;
/* ENTER not needed externally */
if (KeyCode != C_OPTIONS)
{
/* If
OPTIONS pressed during STOP PUMP / TO SET, still "review" */
statusflag
&= REVIEWMASK;
return(IGNORE);
}
}
/* The volumevalue (not runvol) must always be cleared
when setting up */
/* a Dose Mode for the first time.
*/
/* The current DoseMode is being set up for the first
time if DOSEMODE */
/* not set or if pdmspecs differs from pdmspecsm07.
*/
if (
(
!(modeflag & DOSEMODE)
||
(pdmspecs != pdmspecsm07)
)
&&
(KeyCode != C_CLEAR)
/* Don't clr vol if just clrng mode */
&&
(Modifiable)
/* Not if Titrating
*/
)
{
/* Clear out the territory,
man
*/
for (Ii=0; Ii <= (pdmspecsm07->Q)-1;
Ii++)
{
*(((pdmspecsm07->Pomfp)+Ii)->P->pvalue)
= 0;
/* Get the param sf exp too
*/
*(((pdmspecsm07->Pomfp)+Ii)->P->sfexp)
= 0;
}
/* This is the key value upon
which most PARAMs depend, through */
/* their sfexp pointer. The
sfexp is used in ParmMsg() in optmsg.c */
/* where if the value pointed
to is 1, its parameter is treated as */
/* the regularly scaled, otherwise
the parameter is considered to */
/* be scaled according to the
value pointed to by sfexp.
*/
/* This has to be maintained
here because it might have been
*/
/* cleared just now and then
a lot of other parameters will look */
/* like their values aren't
scaled.
*/
regsfexpon = 1;
/* We must set the rate to zero
here because the Primary Rate is */
/* supposed to be cleared as
soon as a Dose Mode is attempted. */
/* Do separately to ward off
compiler bugs:
*/
runrate = 0;
schedlist[1].SchedRate
= 0;
ratevalue = 0;
parmflag &= GOTRATEMASK;
/* Do separately to ward off
compiler bugs:
*/
schedlist[1].SchedVol = 0;
volumevalue = 0;
/* Don't clear runvol. It's
needed at this time for the Delayed End */
/* test.
*/
parmflag &= GOTVOLMASK;
parmflag &= PARMMEMMASK;
secondssofar = 0;
/* clear running seconds count */
volumesofar = 0;
/* clear running volume counter */
}
if (
(KeyCode == C_CLEAR)
&&
Modifiable
/* Just in case not handled in main */
)
/* This is here in case CLEAR was pressed after this
option was */
/* selected by pressing OPTIONS and typing the options
number, or, in a */
/* recent addition, by just pressing OPTIONS while in
the following */
/* setup routine, and then pressing CLEAR while the
OPT # prompt was */
/* being displayed in the previous block.
*/
{
/* Will already have exited
Delayed End if the pump was in a
*/
/* different Option Mode; if
so, ClrDlydEnd won't do it again. */
ClrDlydEnd(TRUE);
/* Clear the values from permanent
memory
*/
ClearModePars(DOSEMODE);
/* Call the ClearMode function
to return to Primary Mode
*/
ClearModeCore();
/* Clears optionvalue
*/
/* Make a blip against continuous
display of the Option number */
SHOWMSG(D_BLANK);
KS_delay(SELFTASK, IMMEDWAIT/CLKTICK);
ALTERNATE(2);
/* option value set in GetUOption */
SHOWMSG(D_OPT_LOCAL);
/* OPT nn / OPT CLRD
*/
/* DelayMsg Pushes KeyCode;
all calling routines check mailbox. */
/* Note that the quantity in
ALTERNATE includes DelayMsg
*/
DelayMsg(D_OPT_CLRD, 2*BLINKON-ALTREDUC,
DLYMSG_IGMPS);
statusflag &= REVIEWMASK;
/* Defend against any call
*/
return(OK);
}
/* Push Enter handled in GetUOptions, except during
pump stop review */
/* KeyCode will be either C_NULL or C_CLEAR, or C_ENTER
if from pump */
/* stop review. Swallow a possible C_ENTER just before
the FOREVER loop */
/* DOSEMODE is only set when leaving this function to
indicate to the */
/* rest of the software that Dose Mode should be set
up. The current */
/* DOSEMODE is indicated by pdmspecs. The parmflag word,
using GOTRATE */
/* and PARMMEM, is used to indicate that the mode is
all set up */
/* successfully.
*/
/* GOTRATE is used to indicate whether Dose Mode is
currently good */
/* Swallowing of ENTER is done in GetOptPar
*/
/* Very clever algorithm using this Boolean, GoThru,
that causes one */
/* guaranteed pass through the parameter list and then
gets set on the */
/* next go-around only for the parameter that needed
to be set. When */
/* that happens, the rest of the list gets reviewed.
A review cycle is */
/* simulated through ReadyToRun or RunDisplay, as ENTER
is pressed. */
if (
(modeflag & DOSEMODE)
&&
!(parmflag & GOTRATE)
/* if reentering to finish job */
)
GoThru = FALSE;
else
GoThru = TRUE;
/* first-time setting
*/
/* Must look at each parameter if accessed via the OPT
# / Mode<name> / */
/* PUSH ENTR prompt.
*/
if (optionugot != 0)
{
GoThru = TRUE;
}
if (KeyCode == C_VOLUME)
{
STUFFMSG;
/* React to volume key if was Last */
}
/* Titrating : set in Running() (qv)
*/
/* Explanation of Titration: "TITRDIS" is an optionflag
in NVRAM that */
/* disables Titration, which means changing the running
rate "on the */
/* fly".
*/
/*
*/
/* "Titrating", visible only to pnormal3 and pdose,
(and pnormal1 for */
/* titrating in the Primary Mode) is turned on only
when the current */
/* run-through of this function is a Titration operation.
*/
/*
*/
/* "Titrate", visible only to here and GetOptPar, is
a low-level */
/* indication to GetOptPar to tell it to apply the special
Titration */
/* time delays to the parameter acquisition, which only
ever applies to */
/* Rate or Dose amount acquisition.
*/
FOREVER
{
if (KeyCode == C_RUN)
{
GoThru
= FALSE;
}
/* If the RATE key was pressed,
we are doing ratetodose.
*/
/* If doing ratetodose, remember
that. Don't reset it just because */
/* of re-entry to this routine.
Only set it, and only if the RATE */
/* key was pressed. It will
be cleared to FALSE at power-up (see */
/* rtxcmain.c), and every time
a calculation is attempted.
*/
if (KeyCode == C_RATE)
ratetodose
= TRUE;
/* ratetodose set by RequestValues()
or by GetVol() in Pnormal1 */
if (ratetodose)
{
GoThru
= TRUE;
/* look at even a non-zero rate */
/* Be
able to restore the rate if we were already all set up in */
/* Dose
Mode and we just want to change the rate in rate - to - */
/* dose.
Then we don't want to lose the rate if there was a
*/
/* calculation
error.
*/
/* In
this case, we know that if the calculation goes out of
*/
/* range,
that it will be totally the fault of the rate, and */
/* nothing
else -- the for loop breaks out in that case, and */
/* we
can simply restore the rate.
*/
if (
!Titrating
/* Titrating already taken care of */
&&
(TestParms(DOSEMODE) == ALLSET)
&&
(modeflag & DOSEMODE)
&&
(parmflag & GOTRATE)
&&
(Modifiable)
&&
(ratevalue != 0) /* For what more
can I ask? */
&&
/* For an uncorrupted ratevalue: */
(SavedRate == 0) /* --might have
pressed RATE below */
)
SavedRate = ratevalue; /* Otherwise remains 0 as declared */
}
if (Titrating)
{
Titrate
= TRUE;
/* In 1st par only, ie rate or dose */
GoThru
= TRUE;
/* In case ENTER pressed to Titrate */
}
DMRetCode = OK;
/* The parameter acquisition
and display loop:
*/
for(ParNum = 1; ParNum <=
(pdmspecsm07->Q); ParNum++)
{
/* Use
Pointer Arithmetic to point to the current parameter
*/
Pworkomfp
= (pdmspecsm07->Pomfp) + ParNum-1;
if (
/* on the dose amt
*/
(ParNum == 1)
&&
(ratetodose == TRUE) /* doing rate-to-dose
*/
)
/* replace dose setting with rate */
Pworkomfp = &Rate_Function_Par;
/* There
is no longer any point in continuing with ratetodose */
/* if
the dose won't be recalculated or displayed.
*/
if (
Notmodifiable
&&
!Titrating
)
ratetodose = FALSE;
/* Get
the data for the current parameter:
*/
/* Get
the set messages for ShowOMP_Msg():
*/
POptPar
= Pworkomfp->P;
if (
GoThru
||
(*(POptPar->pvalue) == 0)
||
(*(POptPar->pvalue) < POptPar->min_value)
||
(CheckMax(POptPar) == TOOHI)
)
{
D_set_msg = Pworkomfp->Setmsg;
D_val_msg = Pworkomfp->Valmsg;
/* So far, only in case of "units" */
D_units_msg = D_UNS_NONUM;
if (POptPar->param_type == DOSEMODEUNS)
EightCharDispAllowed = TRUE;
else
EightCharDispAllowed = FALSE;
ParLoErrMsg = Pworkomfp->LoErrmsg;
ParErrMsg = Pworkomfp->Errmsg;
ParHiErrMsg = Pworkomfp->HiErrmsg;
HistMsg.msgtype = Pworkomfp->histmsg;
if (*(POptPar->pvalue) == 0)
GoThru = TRUE;
/* Ch must be initialized if it is used, since GetOptPar
*/
/* only sets it TRUE if it changes.
*/
/* use to help indicate whether to display PUSH ENTR
*/
Ch = FALSE;
/* EnterParam uses disp_val_msg in the PARAM structure, so */
/* it has to be maintained to that of the current Valmsg: */
Pworkomfp->P->disp_val_msg = Pworkomfp->Valmsg;
/* HERE IS THE CORE OF IT ALL, the parameter acquisition: */
if (GetOptPar(&Ch) != OK)
/* This will stay stuck on Not OK for one pass through */
/* the parameter list:
*/
DMRetCode = IGNORE;
/* Done with any possible Unit disp */
EightCharDispAllowed = FALSE;
Titrate = FALSE; /* Done GetOptPar;
done "Titrate" */
/* Change the rate value message back for Primary Mode
*/
rate.disp_val_msg = D_RATE;
/* Decide whether to exit; set flags
*/
if (Ch)
/* Record value in history log */
{
ParCh = TRUE; /* Remember if any param
changed */
/* Do variably scaled parameters differently
*/
if (
(POptPar->param_type == DOSEMODEDOSE)
||
(POptPar->param_type == DOSEMODEMASS)
)
{
/* If the parameter type is "DOSEMODEDOSE", then */
/* the log reader will understand that the number */
/* is scaled by ten.
*/
/* The history log reader will have to strip the */
/* scale factor information out of the high order */
/* nibble.
*/
HISTLOG(
((long)*(POptPar->sfexp) << 28)
+
*(POptPar->pvalue)
);
/* All wrapped up in one History Log entry, because */
/* having subsequent entries present in the limited */
/* and reused History log space cannot be relied */
/* upon. (NB: Prepositions are not words to end
*/
/* sentences with)
*/
}
else
{
HISTLOG(*(POptPar->pvalue));
}
}
/* Priority exit, in case of an urgent event:
*/
if (
(
(KeyCode != C_NULL)
&&
(KeyCode != C_RUN) /* must pass gauntlet for reg keys */
&&
(KeyCode != C_ENTER)
/* Attempt to set up the option in the background
*/
/* while going to the OPT no. / PUSH ENTR prompt.
*/
&&
(KeyCode != C_OPTIONS)
)
||
(KeyCode == C_VOLUME)
)
{
if (KeyCode == C_RATE)
{
/* If Titrating, saved_while_titrating was updated */
/* in GetOptPar
*/
ratetodose = TRUE;
break; /* exit and
restart
*/
}
statusflag &= REVIEWMASK;
/* Stay in the mode, but signal that the rate will be */
/* needed, for this is a non-normal exit and the rate */
/* will not be calculated.
*/
if (Modifiable)
/* User wants to stay in Dose Mode
*/
{
ClrDlydEnd(ParCh);
/* But exit Delayed End
*/
modeflag = DOSEMODE | (modeflag & DELAYEDRUN);
/* Keep any Delayed Mode setting */
/* Must remember which Dose Mode to come back to */
pdmspecs = pdmspecsm07;
parmflag &= GOTRATEMASK;
parmflag &= PARMMEMMASK;
optionvalue = localoptno;
}
if (KeyCode != C_VOLUME)
/* Still considered to be in the parm list:
*/
ratetodose = FALSE;
return(IGNORE); /* GetOptPar cleared the parameter
*/
}
/* Add "blip" before going to the next display
*/
/* Including going to the ReadyToRun prompt
*/
SHOWMSG(D_BLANK);
KS_delay(SELFTASK, IMMEDWAIT/CLKTICK);
/* This is kept following the priority exit in case that
*/
/* exit gets taken, which could otherwise lead to an
*/
/* extended blank display.
*/
if (
(ratetodose)
&&
/* Do any zero parameters
*/
(TestParms(DOSEMODE) == ALLSET)
)
break;
/* Return straight away if adj rate */
if (Titrating) /*
Only do rate or dose
*/
break;
if (
/* Must exit or check for any 0 parameters if beeping */
(RetCode == RC_TIMEOUT)
||
(KeyCode == C_RUN) /* or if RUN was pressed
*/
)
{
GoThru = FALSE;
/* || value==0 of this loop must be bypassed
*/
break;
}
GoThru = TRUE;
if (KeyCode == C_OPTIONS)
break;
/* GoThru is set TRUE now
*/
} /*
End of if block that displays or gets the Opt Par
*/
/* Ensure
that Titrate gets cleared consistently after the
*/
/* first
ParNum.
*/
Titrate
= FALSE;
} /* End of for loop to go thru
each par for the Dose Mode, once. */
/* (The parameter acquisition
and display loop)
*/
if (
/* If
RATE pressed during parameter entry
*/
(KeyCode
== C_RATE) /* Go right to
rate-to-dose */
||
/* "Bad
Parms": found parms in NVRAM that violate their current */
/* limits:
*/
(
/* Bad parms - redo list
*/
(DMRetCode != OK)
/* Zero values not counted
*/
&&
(KeyCode != C_OPTIONS) /* -unless user wants OPT
# prompt */
&&
Modifiable
/* Can't keep user in otherwise */
)
)
/* Go
back to first, or first bad parameter, depending upon
*/
/* GoThru
*/
continue;
/* Skip rest of FOREVER loop */
if (Notmodifiable)
/* ... &in case of bad pars, say OK */
DMRetCode
= OK;
/* NB Broke out from the previous
for loop if OPTIONS pressed. Will */
/* still do calc, however:
*/
/* If the calculation can be
done, do it
*/
if (
(DMRetCode
== OK)
&&
(TestParms(DOSEMODE)
== ALLSET)
&&
(
Modifiable
||
/* Set in Running() if RATE or ENTER pressed, also if
*/
/* doing "titration"
*/
(
Titrating
&&
/* Skip calc if no change
*/
Ch
)
)
)
{
/* The
calculation function sees the global ratetodose, and the */
/* pointer
pdmspecsm07 which is a global. It returns as its
*/
/* return
code, a value that is here assigned to DMRetCode.
*/
/* Everything
needed to do the calculation is found in the
*/
/* structure
pointed to by pdmspecsm07.
*/
DMRetCode
= DoseCalc(&CalcResult, &CalcQFracDigs);
}
/* Decision block as to whether
to exit this forever loop -- this */
/* is the condition that forces
the user to supply all or none of */
/* the parameters.
*/
if (
/* Can leave if all parms zero */
(
(TestParms(DOSEMODE) == NONESET)
&&
(KeyCode != C_RUN) /* RUN
stays in if nothing yet */
)
||
/* or, exit if all set up
*/
/* Break
out if all the parameters are there and the calc
*/
/* succeeded
OK, as long as we are not Titrating, in which
*/
/* case
the "Titrating" group of &&'s in this if statement
*/
/* apply
in the decision whether to break.
*/
(
(TestParms(DOSEMODE) == ALLSET)
&&
/* See the MultDiv function, invoked above
*/
(DMRetCode == OK)
&&
!Titrating
)
||
/* Let
him out; only reviewing; not fair to keep him in if he */
/* can't
set anything.
*/
(
Notmodifiable
&&
!Titrating
)
||
/* No
error in Titrating; otherwise, stay and show err msg
*/
(
Titrating
&&
(DMRetCode == OK)
&&
/* Stay in if Titrating, but nothing changed, in order to
*/
/* sound a warning tone.
*/
Ch
)
)
/* That was
a big IF
*/
break;
/* That was a small statement */
/* Any OPTIONS
keypress in this case will be handled after the */
/* end of
the FOREVER loop.
*/
/* This was the place to clear
changed parameters so that the set */
/* prompt will always reappear
-- before breaking out due to
*/
/* OPTIONS, but now, parameters
are not cleared, but left in place */
/* to allow the user to refer
back to them.
*/
if (DMRetCode != OK)
{
/* Don't
need to clear anything anymore because the pump will */
/* now
go to the OPT # / <mode name> / PUSH ENTR prompt unless */
/* Titrating
or there was a SavedRate.
*/
if (Titrating)
{
/* If titrating, restore the saved value and ignore the
*/
/* attempt.
*/
if (ratetodose)
{
ratevalue = *(saved_while_titrating.pvalue);
*(rate.sfexp) = 1;
}
else
{
*(pdmspecsm07->Pomfp->P->pvalue)
= *(saved_while_titrating.pvalue);
*(pdmspecsm07->Pomfp->P->sfexp)
= *(saved_while_titrating.sfexp);
}
}
else
if (SavedRate != 0)
{
ratevalue = SavedRate;
}
/* Was
using Temp to restore the DPFLAGS; don't need to mess
*/
/* with
DPFLAGS all over the place anymore because the display */
/* routine,
ParmMsg() in Optmsg.c takes care of it auto-
*/
/* matically.
*/
}
/* OPTIONS pressed while Titrating?
Still go to OPT # / PUSH ENTR */
/* prompt; nothing would be
changed, because ENTER had to be
*/
/* pressed in order to accept
the changed value.
*/
if (KeyCode == C_OPTIONS)
/* OPTIONS
did not break out above -- must set up or not
*/
break;
/* If Block to handle out of
range results, which may also occur if */
/* Titrating, or a display in
case the no change in Titration */
/* alarm has been sounded
*/
if (
(DMRetCode
!= OK)
||
(
(Titrating)
/* Take out this condition later */
&&
(!Ch)
)
)
{
if (
Titrating
&&
/* Rate not going to change
*/
Ch
/* User-attempted change remembered */
/* (Otherwise Titr Alm on was done in GetOptPar)
*/
)
{
/* Titr a No-Go: out-of-range */
ALARM_ON(A_TITR_NOGO); /* Turns itself off (a "one-shot") */
}
else
if (!Titrating)
{
ALARM_ON(A_PARM_ERR); /* A slow alarm
*/
}
if (!
(
Titrating
&&
(KeyCode == C_RUN) /* Need to go stop the pump,
if so. */
/* (NB. Recall that important pump events get handled by */
/* priority exits from this function)
*/
)
)
{
if (ratetodose)
{
if (
(Titrating)
&&
/* As well as the audible alarm, */
(!Ch) /*
visually demo the unchngd Dose */
)
{
SHOWMSG(pdmspecsm07->Pomfp->Valmsg);
}
else if (DMRetCode == CANTDO)
{
SHOWMSG(D_DOSE_ERR);
}
else if (DMRetCode == TOOHI)
{
SHOWMSG(D_DOSE_HIGH);
}
else
/* It is less than 0.1
*/
{
SHOWMSG(D_DOSE_LOW);
}
}
else
{
if (
(Titrating)
&&
(!Ch) /* Visually
demo the unchngd rate */
)
{
SHOWMSG(D_RATE_IN_MLH);
}
else if (DMRetCode == CANTDO)
{ /* Shows RATE ERR; D_RATE_ERR gives ERR RATE
*/
SHOWMSG(D_CALC_ERR);
}
/* DMRetCode set for rate above */
else if (DMRetCode == TOOHI)
{
SHOWMSG(D_RATE_HIGH);
}
else
/* It is less than 0.1
*/
{
SHOWMSG(D_RATE_LOW);
}
}
/* Pause
*/
/* Discard all normal power and battery related messages
*/
/* so that they won't cause kick-out.
*/
/* i.e., ignore C_ACIN C_ACOUT C_BATTLOW C_BATTOK
*/
/* The beep will now stop after BLINKON or if a non-ignored */
/* message is received.
*/
WaitMsg(TWOSEC/CLKTICK, 4, ignorekeys);
/* The Titration alarm finishes by itself over a 2.5 s
*/
/* period; ALARM status flag not set.
*/
if (statusflag & ALARM)
{
ALARM_OFF;
}
/* End of code for the error display pause
*/
} /*
End of if block to skip the display if STOP was pressed
*/
/* while titrating
*/
/* Clear
ratetodose, because the calculation failed. Let our */
/* users
go!
*/
/* In
the case of Titration, nothing changed, or else the old */
/* values
have been restored, so it is not needed anymore.
*/
ratetodose
= FALSE;
/* React
to any system message that occurred during the pause: */
if (
/* User should be able to select VOL LIMIT or OFF from here */
/* even if Titrating, because by now if Titrating, nothing */
/* else needs to be done in this function
*/
(KeyCode == C_VOLUME)
||
(KeyCode == C_POWEROFF)
||
(
(KeyCode >= C_RCINST)
&&
(KeyCode <= C_LASTMSG)
)
)
/* Handle
strange messages. All keystrokes but CLEAR get kept */
/* in
the current loop. Non-keystroke messages cause kick-out. */
{
statusflag &= REVIEWMASK;
/* Stay in the mode, but signal that the rate will be
*/
/* needed, for this is a non-normal exit and the rate
*/
/* will not be calculated.
*/
if (Modifiable)
/* User wants to stay in Dose Mode
*/
{
ClrDlydEnd(ParCh);
modeflag = DOSEMODE | (modeflag & DELAYEDRUN);
/* Keep any Delayed Mode setting */
/* Must remember which Dose Mode to come back to:
*/
pdmspecs = pdmspecsm07;
parmflag &= GOTRATEMASK;
parmflag &= PARMMEMMASK;
optionvalue = localoptno;
}
return(IGNORE);
}
if (KeyCode
== C_RATE)
{
/* Must now update saved_while_titrating in order to be
*/
/* able to restore the rate, now, in case we are Titrating. */
/* If we are not, it doesn't hurt.
*/
*(saved_while_titrating.pvalue) = ratevalue;
*(saved_while_titrating.sfexp) = 1;
ratetodose = TRUE;
continue;
}
if (
(Titrating)
||
(SavedRate != 0)
)
break;
/* Input restored above; just exit */
/* Respond
to all other valid KeyCodes (none at this time)
*/
switch
(KeyCode)
{
default:
/* Fake-up
an OPTIONS keypress in order to go to the OPT #
*/
/* /
DOSE <type> / PUSH ENTR prompt now.
*/
KeyCode = C_OPTIONS;
}
} /* End of out-of-range result
(Modifiable or Titrating in there) */
if (
(RetCode
== RC_TIMEOUT)
&&
(DMRetCode
== OK)
)
/* Go
on to next SET prompt if timeout while viewing a param. */
GoThru
= FALSE;
else
GoThru
= TRUE;
/* OPTIONS causes a return to
the OPT # prompt
*/
if (KeyCode == C_OPTIONS)
break;
} /* End of FOREVER loop to force the user to enter
all the parms */
/* Do not update rate value if calculation was not done
above. */
/* Do not do calculation above if not modifiable because
the whole Dose */
/* Mode might not even previously exist.
*/
if (
(TestParms(DOSEMODE) == ALLSET)
&&
(DMRetCode == OK)
/* Don't do if need SavedRate here */
&&
/* Rather, restore was done above */
(
Modifiable
||
(
Titrating
&&
Ch
)
)
)
{
/* DOSEMODE and pdmspecs are
guaranteed to be set up below, now, */
/* because the next WAITCHAR
is the last, and will be sent out the */
/* normal exit of this function.
*/
if (ratetodose)
{
*(pdmspecsm07->Pomfp->P->pvalue)
= CalcResult;
*(pdmspecsm07->Pomfp->P->sfexp)
= CalcQFracDigs;
/* History
log the calculated dose value
*/
HistMsg.msgtype
= DOSECALC_TYPE;
/* The
history log reader will have to strip the scale factor */
/*
information out of the high order nibble.
*/
HISTLOG(
((long)CalcQFracDigs << 28)
+
((long)CalcResult)
);
}
else
{
ratevalue
= CalcResult;
/* History
log the calculated rate value
*/
HistMsg.msgtype
= RATECALC_TYPE;
HISTLOG((long)CalcResult);
}
}
/* The updates to the variables that control the running
of the pump */
/* are done below, under "Total Success"
*/
/* Display the calculated result or the restored SavedRate...
*/
if (
/* ...but first, go to the PUSH
ENTR prompt if OPTIONS pressed, or */
/* simulated by the error block
above
*/
(KeyCode != C_OPTIONS)
&&
(TestParms(DOSEMODE) == ALLSET)
)
/* Display the calculated rate or dose
*/
/* Now, DMRetCode is OK, because OPTIONS was simulated
in that case. */
{
/* Should run right away so
user doesn't "skip a heartbeat" when he */
/* pushes RUN, and sees the
rate echoed and only then hears the */
/* pump begin to run.
*/
if (
(KeyCode
!= C_RUN) /* Pause
to display result */
&&
/* Should
not display a meaningless rate while not modifiable */
/* and
when not even set up yet; ie display when the pump is
*/
/* not
running already, even if it is in Keylock.
*/
!Pumprun
/* Not Titrating
*/
)
{
/* Show
a PUSH RUN prompt in here to separate the display of */
/* the
calculation result from the display shown in ReadyToRun, */
/* so
that the same thing isn't shown twice in a row. This is */
/* done
for looks in the case in which rate-to-dose is done. */
/* For
example, in ratetodose, this code will show "x ugkm /
*/
/* PUSH
RUN" and then ReadyToRun shows "x ugkm / y ml/h / PUSH */
/* RUN".
Otherwise, it would show the user "x ugkm / x ugkm / */
/* y
ml/h / PUSH RUN" which wouldn't look good.
*/
if (
/* We know pump is not running */
(modeflag & DOSEMODE)
&&
(volumevalue != 0)
)
{
if (infusionincomplete) /* Show "IN STOP" as well
*/
{
ALTERNATE(3);
}
else
{
ALTERNATE(2);
}
}
if (ratetodose)
{
/* Show the Dose Amount
*/
SHOWMSG(pdmspecsm07->Pomfp->Valmsg);
}
else
{
SHOWMSG(D_RATE_IN_MLH); /* macros expand; needs braces
*/
}
Ii =
1;
if (
/* NB: Pump is not running
*/
(modeflag & DOSEMODE)
&&
(volumevalue != 0)
)
{
Ii = 2;
if (infusionincomplete)
{
Ii = 3;
SHOWMSG(D_IN_STOP);
}
SHOWMSG(D_PUSH_RUN);
}
/* Display
the calculated rate or dose with PUSH RUN, as
*/
/* applicable.
*/
/* Ii
* BLINKON in WAITCHAR is miserably messed-up by the
*/
/* compiler,
so we must use a switch or if block, or get around */
/* the
problem using WaitMsg().
*/
WaitMsg(((Ii*BLINKON)
- ALTREDUC) / CLKTICK, 4, ignorekeys);
/* (Subtract
100ms to prevent any extra confusing flash)
*/
/* Possible
strange messages with success can still set
*/
/* everything
up, and be responded to.
*/
/* If
return(OK), we must push any codes we want considered
*/
/* back
in the control mailbox.
*/
/* Simulate
the effect of ENTER in ReadyToRun
*/
if (KeyCode
== C_ENTER)
{
STUFFMSG;
}
} /* End of if block to display
the calculated rate
*/
} /* End of if block to display the calculated rate.
*/
if (KeyCode == C_OPTIONS)
{
/* Don't do STUFFMSG; rather
return "IGNORE"
*/
optionspressedinsetup = TRUE;
}
/* Block to exit the mode if all of the parameters got
cleared */
if (
(Modifiable)
&&
/* If all parameters are zero */
(TestParms(DOSEMODE) == NONESET)
)
{
ClrDlydEnd(ParCh);
/* Even if user diddled the 0 key */
/* Clearing all parameters manually
must cause correct clearing of */
/* Primary Mode if there was
previously a valid Dose Mode. See */
/* ClearMode() for details.
*/
if (!(modeflag & NORMAL))
/* Don't bother falling off floor */
{
ClearModeCore();
/* Parms already clear in here */
}
if (!optionspressedinsetup)
/* if TRUE, don't pause for display */
{
ALTERNATE(2);
/* Display OPT nn / OPT CLRD */
SHOWMSG(D_OPT_LOCAL);
/* Pushes
KeyCode; all calling routines check mailbox
*/
/* Note
that the quantity in ALTERNATE includes DelayMsg
*/
DelayMsg(D_OPT_CLRD,
2*BLINKON-ALTREDUC, DLYMSG_IGMPS);
}
}
/* Default block to ensure that the pump stays in the
current Dose Mode */
/* If only some parms set, set the pump to the Dose
Mode being looked */
/* at. This might apply if OPTIONS pressed partway through
the list of */
/* parameters.
*/
if (
Modifiable
&&
(
(TestParms(DOSEMODE) ==
SOMESET)
||
/* Set modeflag here if
going out via OPTIONS because DMRetCode */
/* was not OK, because
we are not clearing the Dose parm upon exit */
/* now, but we are leaving
all parameters set, and we need to have */
/* the modeflag set unconditionally
so that a clear won't be done */
/* upon reentry from pnormal4.
*/
(TestParms(DOSEMODE) ==
ALLSET)
)
&&
/* If SavedRate was set, then
we either had a good CalcResult, or */
/* we restored SavedRate to
ratevalue, and we shouldn't clear */
/* the GOTRATE flag. Adding
this condition fixes a bug in which the */
/* pump exited and re-entered
through GetRate, ending up displaying */
/* the rate with PUMP STOP /
PUSH RUN twice. If SavedRate is set, */
/* then modeflag and pdmspecs
are already correct.
*/
(SavedRate == 0)
)
{
ClrDlydEnd(ParCh);
/* Changes may have been made */
modeflag = DOSEMODE | (modeflag
& DELAYEDRUN);
/* Keep any Delayed Mode setting */
/* Must remember which Dose
Mode to come back to
*/
pdmspecs = pdmspecsm07;
parmflag &= GOTRATEMASK;
parmflag &= PARMMEMMASK;
optionvalue = localoptno;
}
/* Total success block to update the rate and volume
(not if needed */
/* SavedRate):
*/
if (
(
(
(TestParms(DOSEMODE)
== ALLSET)
&&
Modifiable
)
||
/* Titration decision
portion
*/
(
Titrating
&&
Ch
/* ratetodose cleared if no change */
)
)
&&
(DMRetCode == OK)
)
/* Prompted by the possibility of clearing GOTRATE in
order to push */
/* ENTER and do review (see GetVol and RequestValues):
*/
/* Restore the GOTRATE flag if we are in Keylock, in
this mode, and all */
/* parameters are set and valid. Requires execution
of calculation if */
/* pump is in Keylock (see above)
*/
/* This should cause you to be able to be in the middle
of setting up */
/* parameters, set Keylock and get the GOTRATE flag
back by continuing */
/* to review. Won't set GOTRATE if somehow the parameters
got changed */
/* and are no longer valid.
*/
{
/* Total success
*/
ClrDlydEnd(ParCh);
/* Changes may have been made */
/* Change the running rate on
the fly
*/
if (Titrating)
{
KS_signal(STOPSEMA);
/* In
order to do Titration, we have changed motorctl() so that */
/* it
will always stop on a tick, in order to permit motorctl */
/* to
maintain the volumevalue accurately. (If the user presses */
/* STOP,
this will cause a barely-perceptible delay of as much */
/* as
0.1 secs)
*/
/* This
means that clearing volumesofar and secondssofar here */
/* will
not cause any runtime to be unaccounted for in the
*/
/* reduction
of "volumevalue".
*/
/* Said
clearing is necessary in order for the secondssofar to */
/* be
multiplied only by its applicable runrate so that it will */
/* produce
the correct volumesofar and the correct Volume Incr */
/* for
the purpose of reducing the volumevalue. See TICKSEMA
*/
/* and
STOPSEMA in motorctl().
*/
}
/* The same argument applies
to changing the rate when the pump is */
/* stopped:
*/
secondssofar = 0;
volumesofar = 0;
/* dosemodevol is not reduced
while running because user might stop */
/* and do a review and MultDiv
must still give the same rate
*/
/* result. Now it is used only
for concentration purposes.
*/
/* Moved clearing of vtbi to
top of function
*/
/* CalcResult should already
have set rate value when all pars were */
/* set above, but just to be
safe, and if Titrating,
*/
if (!(ratetodose))
/* if ratetodose, rate was already
typed in
*/
/* Do separately to ward off
compiler bugs:
*/
{
runrate
= CalcResult;
schedlist[1].SchedRate
= CalcResult;
ratevalue
= CalcResult;
}
/* but the runrate and schedlist
must still be updated; otherwise, */
/* out-of-date values might
remain there.
*/
else
/* Is ratetodose
*/
{
runrate
= ratevalue;
schedlist[1].SchedRate
= ratevalue;
}
/* History log the rate value
the pump is set to run with
*/
HistMsg.msgtype = RUNRATEVALUESET_TYPE;
HISTLOG(runrate);
parmflag |= GOTRATE;
if (
(parmflag
& GOTRATE)
&&
(parmflag
& GOTVOL)
)
{
parmflag
|= PARMMEM; /* Make sure mode
is all set */
}
modeflag = DOSEMODE | (modeflag
& DELAYEDRUN);
/* Keep any Delayed Mode setting */
pdmspecs = pdmspecsm07;
/* Set the current Dose Mode */
optionvalue = localoptno;
infcounter = 1;
/* Replace the Primary Mode
*/
infmax = 1;
if (Titrating)
KS_signal(STRTSEMA);
}
/* Default operation is Dose to Rate unless Dose Mode
first set up, */
/* then RATE key pressed.
*/
/* Exit ratetodose if OPTIONS, or anything
*/
ratetodose = FALSE;
statusflag &= REVIEWMASK;
/* Clear any possible review status */
/* Shouldn't be necessary to set KeyCode = NULL. If
we had an ENTER or */
/* a RUN, we don't want beeping, right?
*/
/* Return to pnormal4, pnormal3 -- ReadyToRun or Running,
or pnormal1 */
/* -- RequestValues:
*/
if (
(
(KeyCode >= C_RCINST)
&&
(KeyCode <= C_LASTMSG)
)
||
(KeyCode == C_POWEROFF)
||
(KeyCode == C_VOLUME)
||
(KeyCode == C_RATE)
||
(KeyCode == C_OPTIONS)
)
{ /* Not really "IGNORE", just react to
the strange message
*/
return(IGNORE);
}
else
{
/* Doing return OK - KeyCodes
need to be stuffed in order to be */
/* responded to, whether the
pump is running or not
*/
if (
(KeyCode
!= C_NULL)
&&
(KeyCode
!= C_ENTER)
)
{
STUFFMSG;
/* Restore received code
*/
}
return(OK);
}
} /* End of Mode07. Subroutines follow.
*/
back
First posted Oct 13, 2003