/****************************************************************************/
/* Copyright 1992 to 1996, MBARI                                            */
/****************************************************************************/
/* Summary  : IBC GF/5V Board Interface Module for VxWorks                  */
/* Filename : gf_5v.c                                                       */
/* Author   : Andrew Pearce                                                 */
/* Project  : Tiburon Data Concentrator                                     */
/* Version  : Version 1.0                                                   */
/* Created  : 06/09/93                                                      */
/* Modified : 02/12/96                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: gf_5v.c,v 1.1 93/07/01 14:34:23 pean Exp $
 * $Log:        gf_5v.c,v $
 * Revision 1.1  93/07/01  14:34:23  14:34:23  pean (Andrew Pearce)
 * Initial revision
 *
 */
/****************************************************************************/

#include <vxWorks.h>                /* vxWorks system declarations          */
#include <semLib.h>                 /* vxWorks semaphore functions          */
#include <wdLib.h>                  /* vxWorks watch dog timer support decls*/
#include <msgQLib.h>                /* vxWorks Message Queue Library        */

#include <mbariTypes.h>             /* mbari style guide type declarations  */
#include <mbariConst.h>             /* Miscellaneous constants              */

#include "sio32.h"                  /* SIO32 hardware and driver information*/
#include <sio32Server.h>            /* Sio32 server communication services  */
#include <sio32Client.h>            /* Sio32 client communication services  */
#include <microCmd.h>               /* Microcontoller command functions     */

#include "applic.h"                 /* Microcontroller applications         */
#include "microdef.h"               /* Microcontroller definitions          */
#include "microcmd.h"               /* Microcontroller commands             */
#include "timer.h"                  /* IBC Micro Timer Definitions          */

#define Boolean MBool               /* Map microcontroller Boolean to MBool */

#include "ibc_card.h"               /* IBC Card Types                       */
#include "ibc_cmd.h"                /* IBC Card Serial Commands             */
#include "filter.h"                 /* General Filter Routines              */
#include "gf_board.h"               /* IBC GF/5V Card Definitions           */

#include "gf_5v.h"                  /* Function Prototypes for gf_5v.c      */

/****************************************************************************/
/* Function    : IBC_gf5vGetTemperature                                     */
/* Purpose     : Read IBC GF/5V Board Temperature                           */
/* Inputs      : Sio32 channel, Board Address, Vicor Temperature            */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vGetTemperature( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 *vicorTemp )
{
    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[2];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &reply, sizeof(Word) * 2,
         2, IBC_CPU_APP | GF_GET_TEMPERATURE, (Word) boardAddr )
         == ERROR ) return(ERROR);

                                    /* Check if command result is CMD OK    */
    if (wordFromBuf(&reply, 0) != CMD_OK)
        return(ERROR);              /* Command failed so return ERROR       */

                                    /* Command OK so update temperature     */
    wordsFromBuf(reply, 2, &cmdStatus, vicorTemp);

    return (OK);                    /* Return OK                            */
} /* IBC_gf5vGetTemperature() */

/****************************************************************************/
/* Function    : IBC_gf5vSetTempThresh                                      */
/* Purpose     : Sets IBC GF/5V Board Temperature Warning & Alarm Thresholds*/
/* Inputs      : Sio32 channel, Board Address, Temperature Alarm Thresholds */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vSetTempThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 tempWarn, Int16 tempAlarm )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         4, IBC_CPU_APP | GF_SET_TEMP_THRESH, (Word) boardAddr,
         tempWarn, tempAlarm ) == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_gf5vSetTempThresh() */

/****************************************************************************/
/* Function    : IBC_gf5vGetTempThresh                                      */
/* Purpose     : Read IBC GF/5V Board Temperature Warning & Alarm Thresholds*/
/* Inputs      : Sio32 channel, Board Address, Temperature Alarm Thresholds */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vGetTempThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 *tempWarn,  Int16 *tempAlarm )

{
    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &reply, sizeof(Word) * 3,
         2, IBC_CPU_APP | GF_GET_TEMP_THRESH, (Word) boardAddr )
         == ERROR ) return(ERROR);

                                    /* Check if command result is CMD OK    */
    if (wordFromBuf(&reply, 0) != CMD_OK)
        return(ERROR);              /* Command failed so return ERROR       */

                                    /* Command OK so update thresholds      */
    wordsFromBuf(reply, 3, &cmdStatus, tempWarn,  tempAlarm );

    return (OK);                    /* Return OK                            */
} /* IBC_gf5vGetTempThresh() */

/****************************************************************************/
/* Function    : IBC_gf5vSetChargeTimes                                     */
/* Purpose     : Sets IBC GF/5V Board Charge up times                       */
/* Inputs      : Sio32 channel, Board Address, array of charge times        */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vSetChargeTimes( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int32 chargeTimes[GF_MAX_CHANS] )
{
    Word    status;                 /* Command Result from microcontroller  */
    Word    charge_times[GF_MAX_CHANS];

    charge_times[0] = (Word) (chargeTimes[0] / GF_CHARGE_TIME_SCALAR);
    charge_times[1] = (Word) (chargeTimes[1] / GF_CHARGE_TIME_SCALAR);
    charge_times[2] = (Word) (chargeTimes[2] / GF_CHARGE_TIME_SCALAR);
    charge_times[3] = (Word) (chargeTimes[3] / GF_CHARGE_TIME_SCALAR);

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         6, IBC_CPU_APP | GF_SET_CHARGE_TIMES, (Word) boardAddr,
         charge_times[0], charge_times[1], charge_times[2], charge_times[3] )
          == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_gf5vSetChargeTimes() */

/****************************************************************************/
/* Function    : IBC_gf5vGetChargeTimes                                     */
/* Purpose     : Read IBC GF/5V Board Charge up times                       */
/* Inputs      : Sio32 channel, Board Address, array of charge times        */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vGetChargeTimes( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int32 chargeTimes[GF_MAX_CHANS] )

{
    Word    charge_times[GF_MAX_CHANS];
    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[5];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &reply, sizeof(Word) * 5,
         2, IBC_CPU_APP | GF_GET_CHARGE_TIMES, (Word) boardAddr )
         == ERROR ) return(ERROR);

                                    /* Check if command result is CMD OK    */
    if (wordFromBuf(&reply, 0) != CMD_OK)
        return(ERROR);              /* Command failed so return ERROR       */

                                    /* Command OK so update thresholds      */
    wordsFromBuf( reply, 5, &cmdStatus, &charge_times[0], &charge_times[1],
                  &charge_times[2], &charge_times[3] );

    chargeTimes[0] = ((Int32) charge_times[0]) * GF_CHARGE_TIME_SCALAR;
    chargeTimes[1] = ((Int32) charge_times[1]) * GF_CHARGE_TIME_SCALAR;
    chargeTimes[2] = ((Int32) charge_times[2]) * GF_CHARGE_TIME_SCALAR;
    chargeTimes[3] = ((Int32) charge_times[3]) * GF_CHARGE_TIME_SCALAR;

    return (OK);                    /* Return OK                            */
} /* IBC_gf5vGetChargeTimes() */

/****************************************************************************/
/* Function    : IBC_gf5vSetVoltageThresh                                   */
/* Purpose     : Sets IBC GF/5V Board Voltage Warning and Alarm Thresholds  */
/* Inputs      : Sio32 channel, Board Address, Voltage Alarm Thresholds     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vSetVoltageThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 voltageWarn, Int16 voltageAlarm )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         4, IBC_CPU_APP | GF_SET_VOLTAGE_THRESH, (Word) boardAddr,
         voltageWarn, voltageAlarm ) == ERROR )
        return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_gf5vSetVoltageThresh() */

/****************************************************************************/
/* Function    : IBC_gf5vGetVoltageThresh                                   */
/* Purpose     : Read IBC GF/5V Board Voltage Warning and Alarm Thresholds  */
/* Inputs      : Sio32 channel, Board Address, Voltage Alarm Thresholds     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vGetVoltageThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 *voltageWarn, Int16 *voltageAlarm )
{
    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &reply, sizeof(Word) * 3,
         2, IBC_CPU_APP | GF_GET_VOLTAGE_THRESH, (Word) boardAddr )
         == ERROR ) return(ERROR);

                                    /* Check if command result is CMD OK    */
    if (wordFromBuf(&reply, 0) != CMD_OK)
        return(ERROR);              /* Command failed so return ERROR       */

                                    /* Command OK so update thresholds      */
    wordsFromBuf(reply, 3, &cmdStatus, voltageWarn, voltageAlarm );

    return (OK);                    /* Return OK                            */
} /* IBC_gf5vGetVoltageThresh() */

/****************************************************************************/
/* Function    : IBC_gf5vEnableGf                                           */
/* Purpose     : Sets IBC GF/5V Board Enable Ground Fault Monitoring        */
/* Inputs      : Sio32 channel, Board Address                               */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vEnableGf( sio32Chan *IBC_SerialChan, Word boardAddr, MBool enable )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         3, IBC_CPU_APP | GF_SET_FAULT_MONITOR, (Word) boardAddr,
         (Word) enable) == ERROR )
         return(ERROR);
                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_gf5vEnableGF() */

/****************************************************************************/
/* Function    : IBC_gf5vRestartScan                                        */
/* Purpose     : Restart IBC GF/5V Board Ground Fault Measurement           */
/* Inputs      : Sio32 channel, Board Address                               */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vRestartScan( sio32Chan *IBC_SerialChan, Word boardAddr )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         2, IBC_CPU_APP | GF_RESTART_CHAN_CHARGE, (Word) boardAddr) == ERROR )
         return(ERROR);
                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_gf5vRestartScan() */

/****************************************************************************/
/* Function    : IBC_gf5vRunSelftest                                        */
/* Purpose     : Process Data Manger Item request to run GF Board selftest  */
/* Inputs      : Sio32 channel, Board Address                               */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vRunSelftest( sio32Chan *IBC_SerialChan, Word boardAddr )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         2, IBC_CPU_APP | GF_RUN_SELFTEST, (Word) boardAddr) == ERROR )
         return(ERROR);
                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_gf5vRunSelftest() */

/****************************************************************************/
/* Function    : IBC_gf5vGetFaultCurrents                                   */
/* Purpose     : Read IBC GF/5V Board Ground Fault Current Measurements     */
/* Inputs      : Sio32 channel, Board Address, measured parameters          */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vGetFaultCurrents( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 faultCurrents[GF_MAX_CHANS], Int16 *offsetCurrent,
    Int16 *vicorVoltage)
{
    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[7];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &reply, sizeof(Word) * 7,
         2, IBC_CPU_APP | GF_GET_CURRENTS, (Word) boardAddr )
         == ERROR ) return(ERROR);

                                    /* Check if command result is CMD OK    */
    if (wordFromBuf(&reply, 0) != CMD_OK)
        return(ERROR);              /* Command failed so return ERROR       */

                                    /* Command OK so update thresholds      */
    wordsFromBuf( reply, 7, &cmdStatus, &faultCurrents[0], &faultCurrents[1],
        &faultCurrents[2], &faultCurrents[3], offsetCurrent, vicorVoltage );

    return (OK);                    /* Return OK                            */
} /* IBC_gf5vGetFaultCurrents() */

/****************************************************************************/
/* Function    : IBC_NewGf5vGetFaultCurrents                                */
/* Purpose     : Read IBC GF/5V Board Ground Fault Current Measurements     */
/* Inputs      : Sio32 channel, Board Address, measured parameters          */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_NewGf5vGetFaultCurrents( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 faultCurrents[GF_MAX_CHANS], Word *chanUpdate, Int16 *offsetCurrent,
    Int16 *vicorVoltage)
{
    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[8];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &reply, sizeof(Word) * 8,
         2, IBC_CPU_APP | GF_GET_CURRENTS, (Word) boardAddr )
         == ERROR ) return(ERROR);

                                    /* Check if command result is CMD OK    */
    if (wordFromBuf(&reply, 0) != CMD_OK)
        return(ERROR);              /* Command failed so return ERROR       */

                                    /* Command OK so update thresholds      */
    wordsFromBuf( reply, 8, &cmdStatus, &faultCurrents[0], &faultCurrents[1],
        &faultCurrents[2], &faultCurrents[3], chanUpdate,
        offsetCurrent, vicorVoltage );

    return (OK);                    /* Return OK                            */
} /* IBC_NewGf5vGetFaultCurrents() */

/****************************************************************************/
/* Function    : IBC_PowerCanGf5vGetFaultCurrents                           */
/* Purpose     : Read IBC GF/5V Board Ground Fault Current Measurements     */
/* Inputs      : Sio32 channel, Board Address, measured parameters          */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_PowerCanGf5vGetFaultCurrents( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 faultCurrents[GF_MAX_CHANS], Word *chanUpdate, Int16 *offsetCurrent,
    Int16 *capacitorCurrent, Int16 *vicorVoltage)
{
    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[9];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &reply, sizeof(Word) * 9,
         2, IBC_CPU_APP | GF_GET_CURRENTS, (Word) boardAddr )
         == ERROR ) return(ERROR);

                                    /* Check if command result is CMD OK    */
    if (wordFromBuf(&reply, 0) != CMD_OK)
        return(ERROR);              /* Command failed so return ERROR       */

                                    /* Command OK so update thresholds      */
    wordsFromBuf( reply, 9, &cmdStatus, &faultCurrents[0], &faultCurrents[1],
        &faultCurrents[2], &faultCurrents[3], chanUpdate,
        offsetCurrent, vicorVoltage, capacitorCurrent );

    return (OK);                    /* Return OK                            */
} /* IBC_PowerCanGf5vGetFaultCurrents() */

/****************************************************************************/
/* Function    : IBC_gf5vGetAlarmStatus                                     */
/* Purpose     : Read IBC GF/5V Board Alarms                                */
/* Inputs      : Sio32 channel, Board Address, Various Alarms               */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vGetAlarmStatus( sio32Chan *IBC_SerialChan, Word boardAddr,
    gfStatus gfAlarms[], ibcAlarm *tempAlarm, ibcAlarm *voltageAlarm,
    gf5v_gfTestStatus *selftestStatus )
{
    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[8];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &reply, sizeof(Word) * 8,
         2, IBC_CPU_APP | GF_GET_ALARM_STATUS, (Word) boardAddr )
         == ERROR ) return(ERROR);

                                    /* Check if command result is CMD OK    */
    if (wordFromBuf(&reply, 0) != CMD_OK)
        return(ERROR);              /* Command failed so return ERROR       */

                                    /* Command OK so update alarms          */
    gfAlarms[0] = (gfStatus) wordFromBuf(&reply, sizeof(Word));
    gfAlarms[1] = (gfStatus) wordFromBuf(&reply, sizeof(Word) * 2);
    gfAlarms[2] = (gfStatus) wordFromBuf(&reply, sizeof(Word) * 3);
    gfAlarms[3] = (gfStatus) wordFromBuf(&reply, sizeof(Word) * 4);

    *tempAlarm      = (ibcAlarm) wordFromBuf(&reply, sizeof(Word) * 5);
    *voltageAlarm   = (ibcAlarm) wordFromBuf(&reply, sizeof(Word) * 6);

    *selftestStatus = (gf5v_gfTestStatus) wordFromBuf(&reply, sizeof(Word) * 7);

    return (OK);                    /* Return OK                            */
} /* IBC_gf5vGetAlarmStatus() */


/****************************************************************************/
/* Function    : IBC_gf5vSetBusCapacitance                                  */
/* Purpose     : Enables model mode by setting bus capacitance (microfarads)*/
/* Inputs      : Sio32 channel, Board Address, Bus Capacitance              */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_gf5vSetBusCapacitance( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 busCapacitance )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         3, IBC_CPU_APP | GF_SET_BUS_CAPACITANCE, (Word) boardAddr,
         busCapacitance) == ERROR )
         return(ERROR);
                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_gf5vSetBusCapacitance() */
