/****************************************************************************/
/* Copyright 1990 to 1995 MBARI                                             */
/****************************************************************************/
/* Summary  : AC Can Microcontroller Board Software                         */
/* Filename : ac_micro.c                                                    */
/* Author   : Andrew Pearce                                                 */
/* Project  : Tiburon ROV                                                   */
/* Version  : 1.0                                                           */
/* Created  : 03/13/95                                                      */
/* Modified : 03/24/95                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: /usr/tiburon/.cvsroot/micro/ac_micro/ac_micro.c,v 1.3 1997/05/07 15:23:34 pean Exp $
 * $Log: ac_micro.c,v $
 * Revision 1.3  1997/05/07 15:23:34  pean
 * Cleaned up Include files and makefile for new directory structure.
 *
 * Revision 1.1.1.1  1997/05/02 17:15:43  pean
 * Initial release of the microcontroller software after Tiburon
 * Moolpool Dive to test IView, Lapboxes, modified Power can
 * GF/5V using bus capacitance mode.
 *
 * Revision 1.3  95/09/13  11:31:29  11:31:29  pean (Andrew Pearce)
 * Final release for Tiburon
 *
 * Revision 1.2  95/04/25  09:45:13  09:45:13  pean (Andrew Pearce)
 * Pressure sensor resolution changed to 0.01 PSIA
 *
 * Revision 1.1  95/03/28  10:45:41  10:45:41  pean (Andrew Pearce)
 * Initial revision
 *
 */
/****************************************************************************/

#pragma model(196)
#pragma nosignedchar

#include "C:/C96/include/80C196.h"      /* 80196 Register mapping           */
#include "C:/C96/INCLUDE/string.h"      /* string function library          */

#include "const.h"                      /* Misc. constants - TRUE/FALSE etc */
#include "types.h"                      /* MBARI style guide declarations   */
#include "applic.h"                     /* Microcontroller applications     */
#include "microasm.h"                   /* Assembly language functions      */
#include "malloc.h"                     /* Malloc support routines          */

#include "microdef.h"                   /* Microcontroller Definitions      */
#include "microlib.h"                   /* Microcontroller Library decls.   */
#include "applay.h"                     /* Application layer funcitions     */
#include "serial.h"                     /* Serial layer functions           */
#include "microcmd.h"                   /* microcontroller commands         */

#include "timer.h"                      /* Timer library definitions        */
#include "ring.h"                       /* Ring buffer support routines     */
#include "syslib.h"                     /* Hardware support library decls   */

#include "../ibc/filter/filter.h"       /* General Filter Routines          */
#include "ac_micro.h"

const  Char  micro_id[] = "87C196KD Microcontroller Board";
const  Char  softwareRev[] = "$Revision: 1.3 $";
const  Char serialNumber[] = "AC MICRO 01";
const  Char *microSerialNo;

MLocal Boolean microEnabled;        /* Enables processing of serial commands*/

MLocal alarmParam tempAlarm;        /* Temperature Alarm Monitor            */
MLocal alarmParam humidityAlarm;    /* Humidity Alarm Monitor               */
MLocal alarmParam pressureAlarm;    /* Pressure Alarm Monitor               */

MLocal filterParam tempFilter;      /* Temperature sensor filter            */
MLocal filterParam pressureFilter;  /* Pressure sensor filter               */

                                    /* Coolant level alarms and levels      */
MLocal alarmParam outbdTankLevelAlarm;
MLocal alarmParam inbdTankLevelAlarm;
MLocal Int16 outbdSumpLevel;
MLocal Int16 inbdSumpLevel;
                                    /* Coolant level sensor filters         */
MLocal filterParam outbdTankLevelFilter;
MLocal filterParam outbdSumpLevelFilter;
MLocal filterParam inbdTankLevelFilter;
MLocal filterParam inbdSumpLevelFilter;


MBool  waterAlarmDetected;          /* Water alarm status flags             */
MLocal Boolean tetherCanWaterAlarmDetected;

MLocal struct                       /* Coolant pump control line timing     */
{
    Nat16 ticker;                   /* System ticker for 1 second timebase  */
    Nat16 timer;                    /* timer counts down to event at 1Hz    */
    MBool state;                    /* Present state of pump control line   */
} acPumpControl;

                                /* Forward Declarations for Locals          */
MLocal Void executeCommand( Void );
MLocal Void checkACWaterAlarms( Void );
MLocal Void checkTempAlarm( Void );
MLocal Void checkHumidityAlarm( Void );
MLocal Void checkPressureAlarm( Void );
MLocal Void initializeACPump( Void );
MLocal Void checkAcCanPumpTimer( Void );
MLocal Void checkCoolantLevels( Void );

/****************************************************************************/
/* Function    : processSRQPacket                                           */
/* Purpose     : proceses Service Request Packets                           */
/* Inputs      : received packet buffer                                     */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
processSRQPacket(Byte *command_buf)
{
} /* processSRQPacket() */

/****************************************************************************/
/* Function    : initializeAlarms                                           */
/* Purpose     : Initializes various alarm status and thresholds            */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
initializeAlarms( Void )
{
    tempAlarm.value                = 0;
    tempAlarm.warnThresh           = TEMP_WARN_THRESH;
    tempAlarm.alarmThresh          = TEMP_ALARM_THRESH;
    tempAlarm.alarmStatus          = MICRO_ALARM_OK;

    humidityAlarm.value            = 0;
    humidityAlarm.warnThresh       = HUMIDITY_WARN_THRESH;
    humidityAlarm.alarmThresh      = HUMIDITY_ALARM_THRESH;
    humidityAlarm.alarmStatus      = MICRO_ALARM_OK;

    pressureAlarm.value            = 0;
    pressureAlarm.warnThresh       = PRESSURE_WARN_THRESH;
    pressureAlarm.alarmThresh      = PRESSURE_ALARM_THRESH;
    pressureAlarm.alarmStatus      = MICRO_ALARM_OK;

    outbdTankLevelAlarm.value       = 0;
    outbdTankLevelAlarm.warnThresh  = 0;     /* Not used */
    outbdTankLevelAlarm.alarmThresh = TANK_LEVEL_ALARM_THRESH;
    outbdTankLevelAlarm.alarmStatus = MICRO_ALARM_OK;

    inbdTankLevelAlarm.value       = 0;
    inbdTankLevelAlarm.warnThresh  = 0;    /* Not used  */
    inbdTankLevelAlarm.alarmThresh = TANK_LEVEL_ALARM_THRESH;
    inbdTankLevelAlarm.alarmStatus = MICRO_ALARM_OK;

                                    /* Clear water alarm status flags      */
    waterAlarmDetected = FALSE;
    tetherCanWaterAlarmDetected = FALSE;
} /* initializeAlarms() */

/****************************************************************************/
/* Function    : mainLoop                                                   */
/* Purpose     : C main program called from assembler startup routine       */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
mainLoop( Void )
{
    initIoport1();              /* Initialize Input/Output Port 1           */
    initIoport2();              /* Initialize Input/Output Port 2           */

    initMalloc();               /* Initialize Memory allocator              */
    initBoardStatus();          /* Initialize board status word             */

    microSerialNo = serialNumber;

    initializeAlarms();         /* Initialize application specific alarms   */
    initializeACPump();         /* Initialize AC Pump Control               */

    microEnabled = FALSE;       /* Disabled processing of serial commands   */
    initSerialProtocol(NULL);   /* Initialize serial protocol               */

                                /* Initialize temperature filter            */
    initIIRFilter(&tempFilter,          MAX_TEMP_VALUE);
    initIIRFilter(&pressureFilter,      MAX_PRESSURE_VALUE);

    initIIRFilter(&outbdTankLevelFilter, MAX_LEVEL_VALUE);
    initIIRFilter(&inbdTankLevelFilter, MAX_LEVEL_VALUE);
    initIIRFilter(&outbdSumpLevelFilter, MAX_LEVEL_VALUE);
    initIIRFilter(&inbdSumpLevelFilter, MAX_LEVEL_VALUE);

                                /* Send Micro Reset SRQ                     */
    writeServiceRequest(1, MICRO_RESET_SRQ);

    FOREVER
    {                           /* Repeat forever                           */
        executeCommand();       /* Process any commands from the VME CPU    */

        checkACWaterAlarms();   /* Check water alarms                       */
        checkTempAlarm();       /* Check temperature alarm                  */
        checkHumidityAlarm();   /* Check humidity alarm                 */
        checkPressureAlarm();   /* Check pressure alarm                     */
        checkCoolantLevels();   /* Check tank and sump coolant levels       */
        checkAcCanPumpTimer();  /* Check timer for AC pump On/Off Control   */
    } /* FOREVER */
} /* mainLoop */

/****************************************************************************/
/* Function    : microGetTemperature                                        */
/* Purpose     : Send temperature value to serial port                      */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
microGetTemperature( Void )
{                                        /* Send temperature to serial port  */
    replyToCommand(2, CMD_OK, tempAlarm.value);
} /* microGetTemperature() */

/****************************************************************************/
/* Function    : microGetTempAlarm                                          */
/* Purpose     : Process command to read temperature alarm status           */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
microGetTempAlarm( Void )
{
    replyToCommand(2, CMD_OK, tempAlarm.alarmStatus);
                                        /* send temperature alarm status    */
                                        /* to the serial port               */
} /* microGetTempAlarm() */

/****************************************************************************/
/* Function    : microGetTempThresh                                         */
/* Purpose     : Send temeprature alarm threshold to serial port            */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
microGetTempThresh( Void )
{                                    /* send temp alarm thresh to serial port*/
    replyToCommand(3, CMD_OK, tempAlarm.warnThresh, tempAlarm.alarmThresh);
} /* microGetTempThresh() */

/****************************************************************************/
/* Function    : microSetTempThresh                                         */
/* Purpose     : Process command to set temperature alarm thresholds        */
/* Inputs      : Serial command buffer                                      */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
microSetTempThresh(Byte *commandBuf)
{
    Word    command;                /* Serial command word - ignored        */
                                    /* Read threshold from command buf      */
    wordsFromBuf(commandBuf, 3, &command,
        (Word*) &tempAlarm.warnThresh, (Word*) &tempAlarm.alarmThresh);

    replyToCommand(1, CMD_OK);      /* Send command OK                      */
} /* microSetTempThresh() */

/****************************************************************************/
/* Function    : readTemperature                                            */
/* Purpose     : Read and scale on board temperature sensor                 */
/* Inputs      : Temperature sensor A/D Channel number                      */
/* Outputs     : Returns temperature in degrees C                           */
/****************************************************************************/
    MLocal Int16
readTemperature( Nat16 channel )
{                               /* Assuming a 4.2K Resistor                 */
    Nat16   rawTemp;
    Int16   degrees;            /* Converted to degrees Centigrade          */
                                /* 1 count = 5.12v/1024 = 5.00 mV           */
                                /* 1 count = 0.376 degrees C                */

                                /* Read raw value from sensor               */
    rawTemp = readAnalogChannel(channel) + 512;

                                /* subtract 0 deg offset and multiply by    */
                                /* 1000 to improve dynamic range for        */
                                /* the conversion to degrees                */
    degrees = (Int16) ((( ((Int32) (rawTemp)) * 376) / 1000) - 273);

    return (degrees);
} /* readTemperature() */

/****************************************************************************/
/* Function    : getHumidity                                                */
/* Purpose     : Send humidity sensor value to serial port                  */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
getHumidityCmd( Void )
{                                        /* send humidity to serial port    */
    replyToCommand(2, CMD_OK, humidityAlarm.value);
} /* getHumidityCmd() */

/****************************************************************************/
/* Function    : getHumidityAlarm                                           */
/* Purpose     : Process command to read humidity alarm status              */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
getHumidityAlarmCmd( Void )
{
    replyToCommand(2, CMD_OK, (Word) humidityAlarm.alarmStatus );
                                        /* send humidity alarm status       */
                                        /* to the serial port               */
} /* getHumidityAlarmCmd() */

/****************************************************************************/
/* Function    : getHumidityThreshCmd                                       */
/* Purpose     : Send humidity alarm threshold to serial port               */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
getHumidityThreshCmd( Void )
{                                /* send humidity alarm thresh to serial port*/
    replyToCommand(3, CMD_OK, (Word) humidityAlarm.warnThresh,
        (Word) humidityAlarm.alarmThresh );
} /* getHumidityThreshCmd() */

/****************************************************************************/
/* Function    : setHumidityThreshCmd                                       */
/* Purpose     : Process command to set humidity alarm threshold            */
/* Inputs      : Serial command buffer                                      */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
setHumidityThreshCmd(Byte *commandBuf)
{
    Word    command;                /* Command from serial port             */

                                    /* Read threshold from command buf      */
    wordsFromBuf( commandBuf, 3, &command, (Word *) &humidityAlarm.warnThresh,
                 (Word *) &humidityAlarm.alarmThresh);

    replyToCommand(1, CMD_OK);      /* Send command OK to serial port       */
} /* setHumidityThreshCmd() */

/****************************************************************************/
/* Function    : acMicroGetPressure                                         */
/* Purpose     : Send pressure value to serial port                         */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroGetPressure( Void )
{                                          /* Send pressure to serial port  */
    replyToCommand(2, CMD_OK, pressureAlarm.value);
} /* acMicroGetPressure() */

/****************************************************************************/
/* Function    : acMicroGetPressureAlarm                                    */
/* Purpose     : Process command to read pressure alarm status              */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroGetPressureAlarm( Void )
{
    replyToCommand(2, CMD_OK, pressureAlarm.alarmStatus);
                                        /* send pressure alarm status       */
                                        /* to the serial port               */
} /* acMicroGetPressureAlarm() */

/****************************************************************************/
/* Function    : acMicroGetPressureThresh                                   */
/* Purpose     : Send pressure alarm threshold to serial port               */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroGetPressureThresh( Void )
{                               /* send pressure alarm thresh to serial port*/
    replyToCommand(3, CMD_OK, pressureAlarm.warnThresh,
             pressureAlarm.alarmThresh);
} /* acMicroGetPressureThresh() */

/****************************************************************************/
/* Function    : acMicroSetPressureThresh                                   */
/* Purpose     : Process command to set pressure alarm thresholds           */
/* Inputs      : Serial command buffer                                      */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroSetPressureThresh(Byte *commandBuf)
{
    Word    command;                /* Serial command word - ignored        */
                                    /* Read threshold from command buf      */
    wordsFromBuf(commandBuf, 3, &command, (Word*) &pressureAlarm.warnThresh,
        (Word*) &pressureAlarm.alarmThresh);

    replyToCommand(1, CMD_OK);      /* Send command OK                      */
} /* acMicroSetPressureThresh() */

/****************************************************************************/
/* Function    : readPressure                                               */
/* Purpose     : Read and scale AC Can pressure sensor                      */
/* Inputs      : Pressure sensor A/D Channel number                         */
/* Outputs     : Returns pressure in PSI * 100                              */
/****************************************************************************/
    MLocal Int16
readPressure( Nat16 channel )
{
    Nat16   rawPressure;
    Int16   psia;
                                /* Read raw value from sensor               */
    rawPressure = readAnalogChannel(channel) + 512;
                                /* 0.25V =  0 PSI, 4.75V = 30 PSI           */
                                /* 0.25/5.0 * 1024 bits = 51 bit offset     */
                                /*(30 * 5V) / ((4.75-0.25) * 1024) = PSI/bit*/
                                /* PSI/bit = 0.03255                        */

                                /* Calculate PSI * 10 from bits             */
    psia = (Int16) (( ((Int32) (rawPressure - 51)) * 3255) / 1000);
    return (max(psia, 0));
} /* readPressure() */

/****************************************************************************/
/* Function    : acMicroGetWaterAlarmCmd                                    */
/* Purpose     : Process command to read water alarm status                 */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroGetWaterAlarmCmd( Void )
{
    replyToCommand(3, CMD_OK, (Word) waterAlarmDetected,
                              (Word) tetherCanWaterAlarmDetected);
} /* acMicroGetWaterAlarmCmd() */

/****************************************************************************/
/* Function    : acMicroGetCoolantLevelsCmd                                 */
/* Purpose     : Send ac can coolant levels to serial port                  */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroGetCoolantLevelsCmd( Void )
{                               /* send coolant levels to serial port       */
    replyToCommand(5, CMD_OK, outbdTankLevelAlarm.value,
        inbdTankLevelAlarm.value, outbdSumpLevel, inbdSumpLevel);
} /* acMicroGetCoolantLevelsCmd() */

/****************************************************************************/
/* Function    : acMicroGetCoolantThresh                                    */
/* Purpose     : Process command to set coolant level alarm thresholds      */
/* Inputs      : Serial command buffer                                      */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroGetCoolantThreshCmd( Void )
{                               /* send coolant level alarms to serial port */
    replyToCommand(3, CMD_OK,
        outbdTankLevelAlarm.alarmThresh, inbdTankLevelAlarm.alarmThresh);
} /* acMicroGetCoolantThreshCmd() */

/****************************************************************************/
/* Function    : acMicroSetCoolantThreshCmd                                 */
/* Purpose     : Process command to set coolant level alarm thresholds      */
/* Inputs      : Serial command buffer                                      */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroSetCoolantThreshCmd(Byte *commandBuf)
{
    Word    command;                /* Serial command word - ignored        */
                                    /* Read threshold from command buf      */
    wordsFromBuf(commandBuf, 3, &command,
        &outbdTankLevelAlarm.alarmThresh, &inbdTankLevelAlarm.alarmThresh);

    replyToCommand(1, CMD_OK);      /* Send command OK                      */
} /* acMicroSetCoolantThreshCmd() */

/****************************************************************************/
/* Function    : acMicroGetCoolantAlarmsCmd                                 */
/* Purpose     : Process command to read coolant alarms status              */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
acMicroGetCoolantAlarmsCmd( Void )
{
    replyToCommand(3, CMD_OK, outbdTankLevelAlarm.alarmStatus,
                              inbdTankLevelAlarm.alarmStatus);
} /* acMicroGetCoolantAlarmsCmd() */

/****************************************************************************/
/* Function    : processApplicCommands                                      */
/* Purpose     : Decode application specific serial port commands           */
/* Inputs      : Command buffer and command buffer length                   */
/* Outputs     : Return TRUE if command recognized and processed, else FALSE*/
/****************************************************************************/
    MLocal Int16
processApplicCommands( Char *commandBuf, Int16 commandLen )
{
                                /* try to recognize the command and call    */
                                /* the appropriate handler                  */
    switch (wordFromBuf(commandBuf, 0))
    {
        case AC_MICRO_APP | GET_TEMPERATURE:
            microGetTemperature();  /* Get Temperature Sensor Value         */
            break;

        case AC_MICRO_APP | GET_TEMP_ALARM_STATUS:
            microGetTempAlarm();    /* Get Temperature Alarm Status         */
            break;

        case AC_MICRO_APP | SET_TEMP_ALARM_THRESH:
            microSetTempThresh(commandBuf);
            break;                  /* Set Temperature Alarm Threshold      */

        case AC_MICRO_APP | GET_TEMP_ALARM_THRESH:
            microGetTempThresh();   /* Get Temperature Alarm Threshold      */
            break;

        case AC_MICRO_APP | GET_HUMIDITY:
            getHumidityCmd();       /* Read Can Humidity Sensor Value       */
            break;

        case AC_MICRO_APP | GET_HUMIDITY_ALARM:
            getHumidityAlarmCmd();  /* Read state of humidity alarm         */
            break;

        case AC_MICRO_APP | GET_HUMIDITY_THRESH:
            getHumidityThreshCmd(); /* Get humidity alarm threshold         */
            break;

        case AC_MICRO_APP | SET_HUMIDITY_THRESH:
            setHumidityThreshCmd(commandBuf);
            break;                  /* Set humidity alarm threshold         */

        case AC_MICRO_APP | GET_PRESSURE:
            acMicroGetPressure();   /* Get Pressure Sensor Value            */
            break;

        case AC_MICRO_APP | GET_PRESSURE_ALARM_STATUS:
            acMicroGetPressureAlarm();
            break;                  /* Get Pressure Alarm Status            */

        case AC_MICRO_APP | SET_PRESSURE_ALARM_THRESH:
            acMicroSetPressureThresh(commandBuf);
            break;                  /* Set Pressure Alarm Threshold         */

        case AC_MICRO_APP | GET_PRESSURE_ALARM_THRESH:
            acMicroGetPressureThresh();
            break;                  /* Get Pressure Alarm Threshold         */

        case AC_MICRO_APP | GET_WATER_ALARM:
            acMicroGetWaterAlarmCmd();
            break;                  /* Send water alarm status              */

        case AC_MICRO_APP | GET_COOLANT_LEVELS:
            acMicroGetCoolantLevelsCmd();
            break;                  /* Send coolant levels                  */

        case AC_MICRO_APP | GET_COOLANT_ALARM_STATUS:
            acMicroGetCoolantAlarmsCmd();
            break;                  /* Send coolant level alarms            */

        case AC_MICRO_APP | GET_COOLANT_ALARM_THRESH:
            acMicroGetCoolantThreshCmd();
            break;                  /* Get coolant level alarms             */

        case AC_MICRO_APP | SET_COOLANT_ALARM_THRESH:
            acMicroSetCoolantThreshCmd(commandBuf);
            break;                  /* Set coolant level alarms             */

        default:
            return (FALSE);         /* Command not recognized return FALSE  */

    } /* switch */

    return (TRUE);                  /* Command recognized & processed       */
} /* processApplicCommands() */

/****************************************************************************/
/* Function    : executeCommand                                             */
/* Purpose     : Check commands received from serial port and call handler  */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
executeCommand( Void )
{
    Char    *commandBuf;            /* Pointer to the command packet data.  */
    Int16   commandLen;             /* Length of the command packet data    */

                                    /* read a command from serial port      */
    while (readRecvdPacket(&commandBuf, &commandLen) == OK)
    {
        if ( wordFromBuf(commandBuf, 0) == (MICRO_APP | CMD_ENABLE) )
        {
            microEnabled = TRUE;
            replyToCommand(1, CMD_OK );
        } /* if */

        else if (microEnabled)
        {                           /* try to recognize the command and call*/
                                    /* the appropriate handler              */
            if ( processApplicCommands( commandBuf, commandLen ) == FALSE )
                processMicroCommands ( commandBuf, commandLen );
        } /* if */

        freeRecvdPacket(commandBuf);/* Free up the memory allocated for the */
                                    /* packet by readSerialPacket()         */
    } /* while */
} /* executeCommand() */

/****************************************************************************/
/* Function    : checkHumidityAlarm                                         */
/* Purpose     : Monitor humidity sensor and check alarm thresholds         */
/* Inputs      : None                                                       */
/* Outputs     : None, but sends SRQ packet to serial port                  */
/****************************************************************************/
    MLocal Void
checkHumidityAlarm( Void )
{                                   /* Read Humidity Sensor                 */
    humidityAlarm.value = readHumidity();

                                    /* Check if humidity has exceeded warn  */
                                    /* or alarm thresholds and send alarm   */
                                    /* SRQ's if necessary                   */
    if (alarmThresholdCheck(humidityAlarm.value,
            humidityAlarm.warnThresh, humidityAlarm.alarmThresh,
            HUMIDITY_HYSTERESIS, &humidityAlarm.alarmStatus ) == TRUE)

        writeServiceRequest(2, HUMIDITY_ALARM_SRQ, humidityAlarm.alarmStatus);
} /* checkHumidityAlarm() */

/****************************************************************************/
/* Function    : checkTempAlarm                                             */
/* Purpose     : Monitor temperature sensor and check alarm thresholds      */
/* Inputs      : None                                                       */
/* Outputs     : None, but sends SRQ packet to serial port                  */
/****************************************************************************/
    MLocal Void
checkTempAlarm( Void )
{                                /* Read & Filter Temperature Sensor        */
    if (IIRFilter(readTemperature(TEMPERATURE_SENSOR_CHAN), &tempAlarm.value,
            &tempFilter) == OK)
    {                               /* Check if temperature has exceeded    */
                                    /* warn or alarm thresholds and send    */
                                    /* alarm SRQ's if necessary             */
        if (alarmThresholdCheck( tempAlarm.value,
            tempAlarm.warnThresh, tempAlarm.alarmThresh,
            TEMPERATURE_HYSTERESIS, &tempAlarm.alarmStatus ) == TRUE)

            writeServiceRequest(2, TEMPERATURE_ALARM_SRQ,
                tempAlarm.alarmStatus);
    } /* if */
} /* checkTempAlarm() */

/****************************************************************************/
/* Function    : checkPressureAlarm                                         */
/* Purpose     : Monitor pressure sensor and check alarm thresholds         */
/* Inputs      : None                                                       */
/* Outputs     : None, but sends SRQ packet to serial port                  */
/****************************************************************************/
    MLocal Void
checkPressureAlarm( Void )
{                                /* Read & Filter Pressure Sensor           */
    if (IIRFilter(readPressure(AC_CAN_PRESSURE_CHAN), &pressureAlarm.value,
            &pressureFilter) == OK)
    {                               /* Check if pressure has exceeded       */
                                    /* warn or alarm thresholds and send    */
                                    /* alarm SRQ's if necessary             */
        if (alarmThresholdCheck( pressureAlarm.value,
            pressureAlarm.warnThresh, pressureAlarm.alarmThresh,
            PRESSURE_HYSTERESIS, &pressureAlarm.alarmStatus ) == TRUE)

           writeServiceRequest(2, PRESSURE_ALARM_SRQ,
              pressureAlarm.alarmStatus);
    } /* if */
} /* checkPressureAlarm() */

/****************************************************************************/
/* Function    : readWaterAlarm                                             */
/* Purpose     : read and debounce water alarm signal                       */
/* Inputs      : None                                                       */
/* Outputs     : Returns water alarm status either TRUE or FALSE            */
/****************************************************************************/
    MLocal Boolean
readWaterAlarm( Nat16 chan )
{
    Nat16 ticks;

    if ((ioport0 & (1 << chan)) == 0)
        return(FALSE);              /* No Water Alarm Detected              */

                                    /* Short delay to debounce foldback     */
    for (ticks = 0; ticks < WATER_ALARM_DEBOUNCE; ticks++);

    if ((ioport0 & (1 << chan)) == 0)
        return(FALSE);              /* No Water Alarm Detected              */

    return(TRUE);                   /* We have a Water Alarm !              */
} /* readWaterAlarm */

/****************************************************************************/
/* Function    : checkACWaterAlarms                                         */
/* Purpose     : Checks AC Can Micro water alarm status & send SRQ Packet   */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
checkACWaterAlarms( Void )
{
    Boolean oldAlarmStatus;             /* Copy of previous alarm status    */

                                        /* Save old state of water alarm    */
    oldAlarmStatus = waterAlarmDetected;

    if ((waterAlarmDetected =
        readWaterAlarm(AC_CAN_WATER_ALARM_CHAN)) != oldAlarmStatus)
        if (waterAlarmDetected == TRUE)
            writeServiceRequest(1, WATER_ALARM_ON_SRQ);
        else
            writeServiceRequest(1, WATER_ALARM_OFF_SRQ);

                                         /* Save old state of water alarm    */
    oldAlarmStatus = tetherCanWaterAlarmDetected;

    if ((tetherCanWaterAlarmDetected =
        readWaterAlarm(TETHER_CAN_WATER_ALARM_CHAN)) != oldAlarmStatus)
        if (tetherCanWaterAlarmDetected == TRUE)
            writeServiceRequest(1, TETHER_CAN_WATER_ALARM_ON_SRQ);
        else
            writeServiceRequest(1, TETHER_CAN_WATER_ALARM_OFF_SRQ);

} /* checkACWaterAlarms() */

    Int16
readCoolantLevel(Int16 channel)
{
    Nat16   rawAtoD;
    Int16   mVolts;
                                /* Read raw value from sensor               */
    rawAtoD = readAnalogChannel(channel) + 512;
                                /* Report as a voltage 0-5000 mV            */
    mVolts = (Int16) ( ( ((Int32) rawAtoD) * 5000L) / 1024);
    return (mVolts);
} /* readCoolantLevel() */

/****************************************************************************/
/* Function    : checkCoolantLevels                                         */
/* Purpose     : Monitor tank & sump coolant levels                         */
/* Inputs      : None                                                       */
/* Outputs     : None, but sends SRQ packet to serial port                  */
/****************************************************************************/
    MLocal Void
checkCoolantLevels( Void )
{                                /* Read & Filter Outboard Tank Level Sensor*/
    if (IIRFilter(readCoolantLevel(OUTBD_TANK_LEVEL_CHAN),
         &outbdTankLevelAlarm.value, &outbdTankLevelFilter) == OK)
    {                               /* Check if level is below alarm level  */
                                    /* and send alarm SRQ if necessary      */
        if (alarmThresholdCheck(outbdTankLevelAlarm.alarmThresh,
           outbdTankLevelAlarm.value, outbdTankLevelAlarm.value,
           TANK_LEVEL_HYSTERESIS, &outbdTankLevelAlarm.alarmStatus) == TRUE)
              writeServiceRequest(2, OUTBD_TANK_LEVEL_ALARM_SRQ,
                  outbdTankLevelAlarm.alarmStatus);

    } /* if */
                                /* Read & Filter Inboard Tank Level Sensor  */
    if (IIRFilter(readCoolantLevel(INBD_TANK_LEVEL_CHAN),
        &inbdTankLevelAlarm.value, &inbdTankLevelFilter) == OK)
    {                               /* Check if level is below alarm level  */
                                    /* and send alarm SRQ if necessary      */
        if (alarmThresholdCheck(inbdTankLevelAlarm.alarmThresh,
            inbdTankLevelAlarm.value, inbdTankLevelAlarm.value,
            TANK_LEVEL_HYSTERESIS, &inbdTankLevelAlarm.alarmStatus) == TRUE)
                writeServiceRequest(2, INBD_TANK_LEVEL_ALARM_SRQ,
                    inbdTankLevelAlarm.alarmStatus);
    } /* if */

                                /* Read & Filter Outboard Sump Level Sensor*/
    IIRFilter(readCoolantLevel(OUTBD_SUMP_LEVEL_CHAN),
        &outbdSumpLevel, &outbdSumpLevelFilter);

                                /* Read & Filter Inboard Sump Level Sensor */
    IIRFilter(readCoolantLevel(INBD_SUMP_LEVEL_CHAN),
        &inbdSumpLevel, &inbdSumpLevelFilter);

    outbdSumpLevel += outbdSumpLevel;     /* Multiply by 2 to scale to 0-10V */
    inbdSumpLevel += inbdSumpLevel;
} /* checkPressureAlarm() */

    MLocal Void
initializeACPump( Void )
{
    acPumpControl.ticker = read_sysclock();
    acPumpControl.timer  = PUMP_ON_TIME;
    acPumpControl.state  = TRUE;
} /* initializeACPump() */

    MLocal Void
checkAcCanPumpTimer()
{
    if ( (read_sysclock() - acPumpControl.ticker) > ONE_SECOND)
    {
        acPumpControl.ticker = read_sysclock();
        if (--acPumpControl.timer == 0)
        {
            if (acPumpControl.state == TRUE)
            {
                acPumpControl.state = FALSE;
                acPumpControl.timer = PUMP_OFF_TIME;
                clrIoport1Bit(PUMP_CONTROL_BIT);
            } /* if */

            else
            {
                acPumpControl.state = TRUE;
                acPumpControl.timer = PUMP_ON_TIME;
                setIoport1Bit(PUMP_CONTROL_BIT);
            } /* else */
        } /* if */
    } /* if */
} /* checkAcCanPumpTimer() */







