 
/*  calib.c
    For use with tm40.c
    Stephen D. Anderson --- January 6, 1995

    Function to calibrate field instrument.

    Checks initially to see whether field instrument exists.  If not a
    search is done.

    An infinite while loop is entered, which does the following.
    A menu is presented with 5 choices:
    1.  Set Primary Variable Lower Range Value.
    2.  Set Primary Variable Upper Range Value.
    3.  D/A Zero Trim.
    4.  D/A Full Scale Trim.
    5.  Quit.

    The choice is executed using a switch statement with 5 cases.

    If the user selects item 5, the function is ended.  This breaks
    out of the infinite while loop.

    If item 1 is selected the user is given a message about what is
    required and then asked if he wants to continue.  If not, there is a
    break out of the switch loop and back into the while loop.  If yes,
    the user is told to apply process and to hit any key when ready.
    Once the keystroke is detected, HART command 37 is sent.  Various
    error conditions are checked.  These may result in calls to functions
    err1 or err.

    If item 2 is selected, the same things happen as for item 1 except
    that the HART command sent is 36 instead of 37.

    If item 3 is selected the user is told to enter a current value in
    mA.  The value is then sent using HART command 40 (enter fixed
    current mode).  Various error conditions are checked.  These may 
    result in calls to functions err1 or err.  If no errors, the user 
    is asked to enter the measured current.  This is sent to the field 
    instrument using HART command 45 (zero trim).  Various error
    conditions are checked.  The field instrument is then taken out of
    fixed current mode with another command 40.

    If item 4 is selected, the same things happen as for item 3 except
    that HART command 46 (gain trim) is sent instead of 45.


    ON ENTRY:   Has no arguments.

    ON EXIT:    Returns nothing.

    REVISION LOG:


*/

#include "tm40.h"
#include "ieee.h"

void calib()

{
    extern byte status1,status2;
    extern byte addr[];
    extern byte found;
    extern byte search(void);
    extern void err(byte);
    extern void err1(byte);
    extern void ieee(byte, byte *, float *);
    extern int hartcmd(byte *, byte, byte *, byte, byte *, byte);

    int i;
    byte s[20];
    float cur_val;
    byte old_status1;

    /*  need field instr info?  */
    if (!found) found = search();
    if (!found) return;

    Wopen(5,10,15,70,2,WHITE|_BLUE,WHITE|_BLUE);

    while (1)   /*  do calibrate until quit. */
    {
        Wclear();
        WputCen("<<   Select Function   >>");
        delay(500); KeyClear();
        MnuAct(5);
        MnuItm(3,5,"Set Primary Variable Lower Range Value",
            'A',1,ITM_BEF,NULL,NULL,NULL);
        MnuItm(4,5,"Set Primary Variable Upper Range Value",
            'A',2,ITM_BEF,NULL,NULL,NULL);
        MnuItm(5,5,"D/A Zero Trim",'A',3,ITM_BEF,NULL,NULL,NULL);
        MnuItm(6,5,"D/A Full Scale Trim",'A',4,ITM_BEF,NULL,NULL,NULL);
        MnuItm(7,5,"Quit Calibration",'A',5,ITM_BEF,NULL,NULL,NULL);
        MnuEnd(1,MNU_VER,20,1,WHITE|_BLACK,WHITE|_BLACK,
            WHITE|_BLACK,BLUE|_CYAN);
        i = MnuGet();

        /*  check for ESC key.  */
        if (TcxlErr == W_ESCPRESS) i = 5;

        switch(i)
        {
            case 1: /*  Primary Variable Lower Range Value. */
            {
                Wopen(2,15,14,65,2,WHITE|_BLACK,WHITE|_BLACK);
                Wputs("\n\n    This command requires that you apply");
                Wputs("\n    process (i.e., pressure, flow, etc.)");
                Wputs("\n    to the Field Instrument.  The value you");
                Wputs("\n    apply becomes the lower range value.");
                Wputs("\n    Do you wish to continue?");
                if (KwGetYn('N') != 'Y')
                {
                    Wclose(); break;
                }

                Wclear();
                Wputs("\n\n    Apply process to the Field");
                Wputs("\n    Instrument now.  Hit any key");
                Wputs("\n    when ready or ESC key to quit.");

                /*  quit?  */
                if (KeyGetc() == Key_Esc)   /*  check for ESC key.  */
                {
                    Wclose(); break;
                }

                /*  send the command.  */
                Wclear();
                Wputs("\n\n    Sending Command");
                Wputs("\n    To Calibrate.");
                delay(1000);
                i = hartcmd(s, 0, s, 0, addr, 37);

                /*  did it work?  */
                if ((i & 1) != 0)
                {
                    /*  no, it didn't. */
                    err1(37); Wclose(); break;
                }

                /*  byte count correct?  */
                if ((i/256) != 0)
                {
                    /*  no, not correct. */
                    err(37); Wclose(); break;
                }

                /*  report success or error.  */
                Wclear();
                if (status1 != 0)
                {
                    /*  error.  */
                    err(37);
                    WputCen("\n\nLower Range Value");
                    WputCen("\nmay not have been");
                    WputCen("\ncalibrated.");
                }
                else
                {
                    WputCen("\n\nLower Range Value");
                    WputCen("\nCalibrate Complete");
                }
                WputCen("\n\nHit any key to resume");
                KeyWait(); Wclose(); break;
            }

            case 2: /*  Primary Variable Upper Range Value. */
            {
                Wopen(2,15,14,65,2,WHITE|_BLACK,WHITE|_BLACK);
                Wputs("\n\n    This command requires that you apply");
                Wputs("\n    process (i.e., pressure, flow, etc.)");
                Wputs("\n    to the Field Instrument.  The value you");
                Wputs("\n    apply becomes the lower range value.");
                Wputs("\n    Do you wish to continue?");
                if (KwGetYn('N') != 'Y')
                {
                    Wclose(); break;
                }

                Wclear();
                Wputs("\n\n    Apply process to the Field");
                Wputs("\n    Instrument now.  Hit any key");
                Wputs("\n    when ready or ESC key to quit.");

                /*  quit?  */
                if (KeyGetc() == Key_Esc)   /*  check for ESC key.  */
                {
                    Wclose(); break;
                }

                /*  send the command.  */
                Wclear();
                Wputs("\n\n    Sending Command");
                Wputs("\n    To Calibrate.");
                delay(1000);
                i = hartcmd(s, 0, s, 0, addr, 36);

                /*  did it work?  */
                if ((i & 1) != 0)
                {
                    /*  no, it didn't. */
                    err1(36); Wclose(); break;
                }

                /*  byte count correct?  */
                if ((i/256) != 0)
                {
                    /*  no, not correct. */
                    err(36); Wclose(); break;
                }

                /*  report success or error.  */
                Wclear();
                if (status1 != 0)
                {
                    /*  error.  */
                    err(36);
                    WputCen("\n\nUpper Range Value");
                    WputCen("\nmay not have been");
                    WputCen("\ncalibrated.");
                }
                else
                {
                    WputCen("\n\nUpper Range Value");
                    WputCen("\nCalibrate Complete");
                }
                WputCen("\n\nHit any key to resume");
                KeyWait(); Wclose(); break;
            }

            case 3: /*  D/A Zero Trim.  */
            {
                /*  Tell field instrument to output user's
                    min scale.  */
                Wopen(2,15,14,65,2,WHITE|_BLACK,WHITE|_BLACK);
                Wputs("\n\n    Enter the Current (in mA)");
                Wputs("\n    that you expect to measure for");
                Wputs("\n    minimum process value (usually");
                Wputs("\n    4 mA)");
                Wputs("\n\n        : ");
                KwScanf("%e", &cur_val);

                /*  quit?  */
                if (TcxlErr == W_ESCPRESS)
                {
                    Wclose(); break;
                }

                CONVERT_TO_IEEE(s, &cur_val);     /*  convert it. */

                /*  send it to field instrument. */
                delay(1000); Wclear();
                Wputs("\n\n    Value Entered");
                i = hartcmd(s, 4, s, 4, addr, 40);

                /*  command accepted? */
                if ((i & 1) != 0)
                {
                    /*  no, didn't work. */
                    delay(1000); err1(40); Wclose(); break;
                }

                /*  byte count error?  */
                if ((i/256) != 4)
                {
                    /*  error.  */
                    err(40); Wclose(); break;
                }

                /*  report error if any.  */
                if (status1 != 0) err(40);
                old_status1 = status1;

                /*  ask user for measured current. */
                Wclear();
                Wputs("\n\n    Enter Measured Current (in mA)");
                Wputs("\n    From Field Instrument.");
                Wputs("\n          : ");
                KwScanf("%e", &cur_val);

                /*  quit?  */
                if (TcxlErr == W_ESCPRESS)
                {
                    /*  try to turn off fixed current and then quit.  */
                    cur_val = 0.0;
                    CONVERT_TO_IEEE(s, &cur_val);
                    hartcmd(s, 4, s, 4, addr, 40);
                    Wclose(); break;
                }

                CONVERT_TO_IEEE(s, &cur_val);

                /*  send it.  */
                i = hartcmd(s, 4, s, 4, addr, 45);
                delay(1000); Wclear();
                Wputs("\n\n    Value Entered");

                /*  command OK?  */
                if ((i & 1) != 0)
                {
                    /*  error. */
                    delay(1000); err1(45); 
                    /*  try to turn off fixed current before quitting.  */
                    cur_val = 0.0;
                    CONVERT_TO_IEEE(s, &cur_val);
                    hartcmd(s, 4, s, 4, addr, 40);
                    Wclose(); break;
                }

                /*  correct number received bytes?  */
                if ((i/256) != 4)
                {
                    /*  error. */
                    err(45); 
                    cur_val = 0.0;
                    CONVERT_TO_IEEE(s, &cur_val);
                    hartcmd(s, 4, s, 4, addr, 40);
                    Wclose(); break;
                }

                /*  report success or error.  */
                if (status1 != 0) err(45);
                Wclear();
                if ( (status1 != 0) || (old_status1 != 0) )
                {
                    /*  error.  */
                    WputCen("\n\nD/A Zero Trim may");
                    WputCen("\nnot have worked.");
                }
                else
                {
                    /*  success.  */
                    WputCen("\n\nD/A Zero Trim Complete");
                }
                WputCen("\n\nHit any key to resume");
                KeyWait(); Wclear();

                /*  exit the fixed current mode.  */
                WputCen("\n\nExiting Fixed Current Mode");
                cur_val = 0.0;
                CONVERT_TO_IEEE(s, &cur_val);
                i = hartcmd(s, 4, s, 4, addr, 40);
                delay(1000);
                if ((i & 1) != 0)
                {
                    err1(40); Wclear();
                    WputCen("\n\nCan't Exit Fixed Current Mode");
                    WputCen("\n\nHit any key to resume");
                    KeyWait();
                }
                Wclose();
            }

            case 4: /*  D/A Gain Trim.  */
            {
                /*  Tell field instrument to output user's
                    full scale.  */
                Wopen(2,15,14,65,2,WHITE|_BLACK,WHITE|_BLACK);
                Wputs("\n\n    Enter the Current (in mA)");
                Wputs("\n    that you expect to measure for");
                Wputs("\n    maximum process value (usually");
                Wputs("\n    20 mA)");
                Wputs("\n\n        : ");
                KwScanf("%e", &cur_val);

                /*  quit?  */
                if (TcxlErr == W_ESCPRESS)
                {
                    Wclose(); break;
                }

                CONVERT_TO_IEEE(s, &cur_val);     /*  convert it. */

                /*  send it to field instrument. */
                delay(1000); Wclear();
                Wputs("\n\n    Value Entered");
                i = hartcmd(s, 4, s, 4, addr, 40);

                /*  command accepted? */
                if ((i & 1) != 0)
                {
                    /*  no, didn't work. */
                    delay(1000); err1(40); Wclose(); break;
                }

                /*  byte count error?  */
                if ((i/256) != 4)
                {
                    /*  error.  */
                    err(40); Wclose(); break;
                }

                /*  report any error. */
                if (status1 != 0) err(40);
                old_status1 = status1;

                /*  ask user for measured current. */
                Wclear();
                Wputs("\n\n    Enter Measured Current (in mA)");
                Wputs("\n    From Field Instrument.");
                Wputs("\n          : ");
                KwScanf("%e", &cur_val);

                /*  quit?  */
                if (TcxlErr == W_ESCPRESS)
                {
                    /*  try to turn off fixed current and then quit.  */
                    cur_val = 0.0;
                    CONVERT_TO_IEEE(s, &cur_val);
                    hartcmd(s, 4, s, 4, addr, 40);
                    Wclose(); break;
                }

                CONVERT_TO_IEEE(s, &cur_val);

                /*  send it.  */
                i = hartcmd(s, 4, s, 4, addr, 46);
                delay(1000); Wclear();
                Wputs("\n\n    Value Entered");

                /*  command OK?  */
                if ((i & 1) != 0)
                {
                    /*  error. */
                    delay(1000); err1(46);
                    /*  try to turn off fixed current before quitting.  */
                    cur_val = 0.0;
                    CONVERT_TO_IEEE(s, &cur_val);
                    hartcmd(s, 4, s, 4, addr, 40);
                    Wclose(); break;
                }

                /*  correct number received bytes?  */
                if ((i/256) != 4)
                {
                    /*  error. */
                    err(46);
                    cur_val = 0.0;
                    CONVERT_TO_IEEE(s, &cur_val);
                    hartcmd(s, 4, s, 4, addr, 40);
                    Wclose(); break;
                }

                /*  report any error. */
                if (status1 != 0) err(46);
                Wclear();
                if ( (status1 != 0) || (old_status1 != 0) )
                {
                    /*  error.  */
                    WputCen("\n\nD/A Gain Trim may");
                    WputCen("\nnot have worked.");
                }
                else
                {
                    WputCen("\n\nD/A Gain Trim Complete");
                }
                WputCen("\n\nHit any key to resume");
                KeyWait(); Wclear();

                /*  exit fixed current mode.  */
                WputCen("\n\nExiting Fixed Current Mode");
                cur_val = 0.0;
                CONVERT_TO_IEEE(s, &cur_val);
                i = hartcmd(s, 4, s, 4, addr, 40);
                if ((i & 1) != 0)
                {
                    delay(1000); err1(40); Wclear();
                    WputCen("\n\nCan't Exit Fixed Current Mode");
                    WputCen("\n\nHit any key to resume");
                    KeyWait();
                }
                Wclose();
            }

            case 5: /*  Quit.  */
            {
                Wclose(); return;
            }
        }
    }
}

