/****************************************************************************/
/* Copyright 1994 MBARI                                                     */
/****************************************************************************/
/* Summary  : Lighting Data Concetrator - Main C Source file                */
/* Filename : lighting.c                                                    */
/* Author   : Andrew Pearce                                                 */
/* Project  : Tiburon ROV IBC Based Data Concentrator                       */
/* Version  : 1.0                                                           */
/* Created  : 11/09/94                                                      */
/* Modified : 11/11/94                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: /usr/tiburon/.cvsroot/micro/ibc/lighting/lighting.c,v 1.2 1997/05/07 15:43:41 pean Exp $
 * $Log: lighting.c,v $
 * Revision 1.2  1997/05/07 15:43:41  pean
 * Cleaned up Include files and makefile for new directory structure.
 *
 * Revision 1.1.1.1  1997/05/02 18:51:42  pean
 * Initial check in of IBC microcontroller software
 *
 * Revision 1.3  96/11/07  14:16:34  14:16:34  audo (Douglas Au)
 * Changed Dual Vicor Board config from One to Two Mini Mods for Lasers
 * 
 * Revision 1.2  96/02/20  14:59:55  14:59:55  pean (Andrew Pearce)
 * Fixed clearing of Quad Serial Board UART overrun error reporting
 * Fixed timer_cancel problem, stacksize too big problem
 * Revised GF/5V Selftest, scan update features
 * 
 * Revision 1.1  95/09/22  16:02:03  16:02:03  pean (Andrew Pearce)
 * Initial revision
 * 
*/
/****************************************************************************/

#pragma model(196)
#pragma nosignedchar

#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 "microasm.h"                   /* Assembly language functions      */
#include "applic.h"                     /* Microcontroller applications     */
#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 "proto.h"                      /* Serial Protocol layer functions  */
#include "microcmd.h"                   /* microcontroller commands         */

#include "timer.h"                      /* Timer library definitions        */
#include "ring.h"                       /* Ring buffer support routines     */
#include "syslib.h"                     /* Board Support library decls.     */

#include "ibc_card.h"                   /* IBC Board Types and Addresses    */
#include "ibc_cmd.h"                    /* Core IBC application definitions */
#include "ibc.h"                        /* IBC Function Library Definitions */
#include "filter.h"                     /* IBC General IIR Filter Routines  */

#include "cpu196.h"                     /* IBC 80C196 CPU Board functions   */
#include "pic.h"                        /* Intel 82C59 Interrupt Controller */

#include "gf_board.h"                   /* Ground Fault Board Definitions   */
#include "high_pwr.h"                   /* High Power Switch Board Defs     */
#include "vicor.h"                      /* Dual Vicor Board Definitions     */
#include "iso_io.h"                     /* Isolated IO Board Definitions    */
#include "quad_serial.h"                /* Quad Serial Board Definitions    */
#include "scc2698.h"                    /* Signetics SCC2698 UART Definition*/

#include "lighting.h"                   /* Application specific definitions */

/****************************************************************************/

const Char micro_id[] = "87C196KC Lighting Data Concentrator";
const Char softwareRev[] = "$Revision: 1.2 $";
const Char serialNumber[] = "LIGHTING 01";
const Char *microSerialNo;

MLocal Boolean microEnabled;            /* Enables serial command processing*/

MLocal Boolean canWaterAlarm;           /* Housing Water Alarm Status       */
MLocal Boolean jboxWaterAlarm;          /* J-Box Water Alarm Status         */
MLocal Nat16   waterAlarmThresh;        /* Water alarm threshold            */

                                        /* Array of IBC boards in backplane */
IBC_BoardEntry *(IBC_CardTable[IBC_MAX_CARDS]);
Int16   IBC_CardCount;                  /* IBC cards found in backplane     */

                                        /* Forward declarations             */

/****************************************************************************/
/* Function    : getWaterAlarmThreshCmd                                     */
/* Purpose     : Send water alarm threshold to serial port                  */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
getWaterAlarmThreshCmd( Void )
{
                                /* send water alarm threshold to serial port*/
    replyToCommand(2, CMD_OK, (Word) waterAlarmThresh );
} /* getWaterAlarmThreshCmd() */

/****************************************************************************/
/* Function    : setWaterAlarmThreshCmd                                     */
/* Purpose     : Process command to set water alarm threshold               */
/* Inputs      : Serial command buffer                                      */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
setWaterAlarmThreshCmd(Byte *commandBuf)
{
    Word    command;                /* Command from serial port             */

                                    /* Read threshold from command buf      */
    wordsFromBuf( commandBuf, 2, &command, (Word *) &waterAlarmThresh );
    replyToCommand(1, CMD_OK);      /* Send command OK to serial port       */
} /* setWaterAlarmThreshCmd() */

/****************************************************************************/
/* Function    : getWaterAlarmCmd                                           */
/* Purpose     : Process command to read water alarm status                 */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
getWaterAlarmCmd( Void )
{
    Word waterAlarmStatus = 0;

    if (canWaterAlarm)  waterAlarmStatus |= HOUSING_WATER_ALARM_BIT;
    if (jboxWaterAlarm) waterAlarmStatus |= JBOX_WATER_ALARM_BIT;

    replyToCommand(2, CMD_OK, (Word) waterAlarmStatus );
} /* getWaterAlarmCmd() */

/****************************************************************************/
/* 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 LIGHTING_IBC_APP | GET_WATER_ALARM:
            getWaterAlarmCmd(); /* Send water alarm status                  */
            break;

        case LIGHTING_IBC_APP | GET_WATER_ALARM_THRESH:
            getWaterAlarmThreshCmd();
            break;

        case LIGHTING_IBC_APP | SET_WATER_ALARM_THRESH:
            setWaterAlarmThreshCmd(commandBuf);
            break;

        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                                                       */
/****************************************************************************/
    Void
executeCommand( Void )
{
    Byte*   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 )

                if ( processIBCCommands ( IBC_CardTable, IBC_CardCount,
                                commandBuf, commandLen ) == FALSE )

                    processMicroCommands ( commandBuf, commandLen );
        } /* if */

        freeRecvdPacket(commandBuf);/* Free up the memory allocated for the */
                                    /* packet by readSerialPacket()         */
    } /* while */
} /* executeCommand() */

/****************************************************************************/
/* 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 )
{
    waterAlarmThresh = WATER_ALARM_THRESHOLD;
    canWaterAlarm    = FALSE;   /* Clear water alarm status flags           */
    jboxWaterAlarm   = FALSE;

} /* initializeAlarms() */

/****************************************************************************/
/* Function    : checkWaterAlarms                                           */
/* Purpose     : Monitor water alarm lines and check against alarm threshold*/
/* Inputs      : None                                                       */
/* Outputs     : None, but sends SRQ packet to serial port                  */
/****************************************************************************/
    MLocal Void
checkWaterAlarms( Void )
{
    if (IBC_ThresholdCheck( readAnalogChannel(HOUSING_WATER_ALARM_CHAN) + 0x200,
         waterAlarmThresh, WATER_ALARM_HYSTERESIS, &canWaterAlarm ) == TRUE)

        writeServiceRequest( 1, canWaterAlarm ? CAN_WATER_ALARM_ON_SRQ
                                              : CAN_WATER_ALARM_OFF_SRQ);

    if (IBC_ThresholdCheck( readAnalogChannel(JBOX_WATER_ALARM_CHAN) + 0x200,
         waterAlarmThresh, WATER_ALARM_HYSTERESIS, &jboxWaterAlarm ) == TRUE)

        writeServiceRequest( 1, jboxWaterAlarm ? JBOX_WATER_ALARM_ON_SRQ
                                               : JBOX_WATER_ALARM_OFF_SRQ );
} /* checkWaterAlarms() */

/****************************************************************************/
/* 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             */

    microEnabled = FALSE;       /* Disabled processing of serial commands   */
    microSerialNo = serialNumber;

                                /* Initialize installed IBC Cards           */
    IBC_CardCount = IBC_initializeCards( &IBC_CardTable, IBC_MAX_CARDS );

                                /* Add entry for one Dual Vicor Card        */
    IBC_CardCount += dualVicorBoardAdd( &IBC_CardTable, IBC_MAX_CARDS,
         IBC_CardCount, DUAL_VICOR_0_ADDR, DUAL_VICOR_TWO_MINI_MODS );

    initializeAlarms();         /* Initialize application specific alarms   */

    initSerialProtocol(NULL);   /* Initialize serial protocol               */

                                /* Send Micro Reset SRQ                     */
    writeServiceRequest(1, MICRO_RESET_SRQ);

    FOREVER
    {                           /* Repeat forever                           */
        executeCommand();       /* Process any commands from the VME CPU    */

        checkWaterAlarms();     /* Check water alarms                       */

                                /* Execute any IBC card specific functions  */
        IBC_CardFunctions( &IBC_CardTable, IBC_CardCount );

    } /* forever */
} /* mainLoop() */


