/****************************************************************************/
/* Copyright 1992 to 1993, MBARI                                            */
/****************************************************************************/
/* Summary  : IBC Low Power Switch Interface Module for VxWorks             */
/* Filename : lps.c                                                         */
/* Author   : Andrew Pearce                                                 */
/* Project  : New ROV                                                       */
/* Version  : Version 1.0                                                   */
/* Created  : 04/08/93                                                      */
/* Modified : 03/30/95                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: lps.c,v 1.1 93/07/01 14:34:31 pean Exp $
 * $Log:        lps.c,v $
 * Revision 1.1  93/07/01  14:34:31  14:34:31  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 "microcmd.h"               /* Microcontroller commands             */
#include "timer.h"                  /* Microcontroler Timer Definitions     */
#include "ibc_card.h"               /* IBC Card Types                       */
#include "filter.h"                 /* General Filter Routines              */
#include "ibc_cmd.h"                /* IBC Card Serial Commands             */
#include "low_pwr.h"                /* LPS Board Definitions                */

#include "lps.h"                    /* Function Prototypes for lps.c        */

/****************************************************************************/
/* Function    : IBC_LPS_VicorControl                                       */
/* Purpose     : Enable/Disable IBC Low Power Switch Vicor Output           */
/* Inputs      : Sio32 channel, IBC Board Address, Desired Vicor state      */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_VicorControl( sio32Chan *IBC_SerialChan, Word boardAddr,
    MBool desiredState )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         3, IBC_CPU_APP | LPS_VICOR_CONTROL, boardAddr,
         desiredState ) == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_LPS_VicorControl() */

/****************************************************************************/
/* Function    : IBC_LPS_SwitchControl                                      */
/* Purpose     : Sets state of IBC Low Power Switch Channel                 */
/* Inputs      : Sio32 channel, IBC Board Address, Channel, Desired state   */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_SwitchControl( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 channel, MBool desiredState )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         4, IBC_CPU_APP | LPS_SWITCH_CTRL, boardAddr,
         channel, desiredState ) == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_LPS_SwitchControl() */

/****************************************************************************/
/* Function    : IBC_LPS_SwitchStatus                                       */
/* Purpose     : Reads state of IBC Low Power Switches                      */
/* Inputs      : Sio32 channel, IBC Board Address, Switch Status            */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_SwitchStatus( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 *switchState )
{
    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 | LPS_SWITCH_STATUS, 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 temeratures     */
    wordsFromBuf(reply, 2, &cmdStatus, switchState);

    return (OK);                    /* Return OK                            */
} /* IBC_LPS_SwitchStatus() */

/****************************************************************************/
/* Function    : IBC_LPS_SetTempThresh                                      */
/* Purpose     : Sets IBC Low Power Switch Temperature Warning and Alarm    */
/*               Thresholds                                                 */
/* Inputs      : Sio32 channel, Board Address, Vicor & Switch 3 Thresholds  */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_SetTempThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 vicorTempWarn,  Int16 vicorTempAlarm,
    Int16 switchTempWarn, Int16 switchTempAlarm )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         6, IBC_CPU_APP | LPS_SET_TEMP_THRESH, boardAddr,
         vicorTempWarn, vicorTempAlarm, switchTempWarn, switchTempAlarm )
         == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_LPS_SetTempThresh() */

/****************************************************************************/
/* Function    : IBC_LPS_GetTempThresh                                      */
/* Purpose     : Read IBC Low Power Switch Temperature Warning and Alarm    */
/*               Thresholds                                                 */
/* Inputs      : Sio32 channel, Board Address, Vicor & Switch 3 Thresholds  */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_GetTempThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 *vicorTempWarn,  Int16 *vicorTempAlarm,
    Int16 *switchTempWarn, Int16 *switchTempAlarm )

{
    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 | LPS_GET_TEMP_THRESH, 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, vicorTempWarn,  vicorTempAlarm,
                           switchTempWarn, switchTempAlarm);

    return (OK);                    /* Return OK                            */
} /* IBC_LPS_GetTempThresh() */

/****************************************************************************/
/* Function    : IBC_LPS_GetTemperatures                                    */
/* Purpose     : Read IBC Low Power Switch Temperatures                     */
/* Inputs      : Sio32 channel, Board Address, Vicor & Switch Temperatures  */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_GetTemperatures( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 *vicorTemp, Int16 *switchTemp )
{
    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 | LPS_GET_TEMPERATURES,  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 temeratures     */
    wordsFromBuf(reply, 3, &cmdStatus, vicorTemp, switchTemp);

    return (OK);                    /* Return OK                            */
} /* IBC_LPS_GetTemperatures() */

/****************************************************************************/
/* Function    : IBC_LPS_SetVoltageThresh                                   */
/* Purpose     : Sets IBC Low Power Switch Voltage Warning and Alarm        */
/*               Thresholds                                                 */
/* Inputs      : Sio32 channel, Board Address, Voltage Thresholds           */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_SetVoltageThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 voltageWarn, Nat16 voltageAlarm)
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         4, IBC_CPU_APP | LPS_SET_VOLTAGE_THRESH, boardAddr,
         voltageWarn  /= LPS_VOLTAGE_ALARM_SCALAR,
         voltageAlarm /= LPS_VOLTAGE_ALARM_SCALAR) == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_LPS_SetVoltageThresh() */

/****************************************************************************/
/* Function    : IBC_LPS_GetVoltageThresh                                   */
/* Purpose     : Read IBC Low Power Switch Voltage Warning and Alarm        */
/*               Thresholds                                                 */
/* Inputs      : Sio32 channel, Board Address, Voltage Thresholds           */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_GetVoltageThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 *voltageWarn,  Nat16 *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 | LPS_GET_VOLTAGE_THRESH, 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);

    *voltageWarn  *= LPS_VOLTAGE_ALARM_SCALAR;
    *voltageAlarm *= LPS_VOLTAGE_ALARM_SCALAR;

    return (OK);                    /* Return OK                            */
} /* IBC_LPS_GetVoltageThresh() */

/****************************************************************************/
/* Function    : IBC_LPS_GetVoltage                                         */
/* Purpose     : Read IBC Low Power Switch Voltage                          */
/* Inputs      : Sio32 channel, Board Address, Voltage                      */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_GetVoltage( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 *lpsVoltage )
{
    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 | LPS_GET_VOLTAGE,  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 currents        */
    wordsFromBuf(reply, 2, &cmdStatus, lpsVoltage);

    return (OK);                    /* Return OK                            */
} /* IBC_LPS_GetVoltage() */

/****************************************************************************/
/* Function    : IBC_LPS_GetCurrents                                        */
/* Purpose     : Read IBC Low Power Switch Currents                         */
/* Inputs      : Sio32 channel, Board Address, Switch Currents              */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_GetCurrents( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 lpsCurrent[] )
{
    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 | LPS_GET_CURRENTS,  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 currents        */
    wordsFromBuf(reply, 5, &cmdStatus, &lpsCurrent[0], &lpsCurrent[1],
                 &lpsCurrent[2], &lpsCurrent[3]);

    return (OK);                    /* Return OK                            */
} /* IBC_LPS_GetCurrents() */

/****************************************************************************/
/* Function    : IBC_LPS_GetCurrentThresh                                   */
/* Purpose     : Read IBC Low Power Switch Current Alarm Thresholds         */
/* Inputs      : Sio32 channel, Board Address, Current Alarm Thresholds     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_GetCurrentThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 warn[], Int16 alarm[] )
{
    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 | LPS_GET_CURRENT_THRESH,  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 currents        */
    wordsFromBuf(reply, 9, &cmdStatus,
         &warn[0], &alarm[0], &warn[1], &alarm[1],
         &warn[2], &alarm[2], &warn[3], &alarm[3] );

    return (OK);                    /* Return OK                            */
} /* IBC_LPS_GetCurrentThresh() */

/****************************************************************************/
/* Function    : IBC_LPS_SetCurrentThresh                                   */
/* Purpose     : Sets IBC Low Power Switch Current Warning and Alarm        */
/*               Thresholds                                                 */
/* Inputs      : Sio32 channel, Board Address, Warning & Alarm Thresholds   */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_SetCurrentThresh( sio32Chan *IBC_SerialChan, Word boardAddr,
    Int16 warn[],  Int16 alarm[] )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         10, IBC_CPU_APP | LPS_SET_CURRENT_THRESH,  boardAddr,
         warn[0], alarm[0], warn[1], alarm[1],
         warn[2], alarm[2], warn[3], alarm[3] )
         == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_LPS_SetCurrentThresh() */

    STATUS
IBC_LPS_SetChanCurrentThreshold( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 chan, Int16 warn, Int16 alarm )
{
    Word    status;                 /* Command Result from microcontroller  */
    Int16   warnThresh[LPS_MAX_CHANS], alarmThresh[LPS_MAX_CHANS];

    if (chan >= LPS_MAX_CHANS)
        return (ERROR);

    if (IBC_LPS_GetCurrentThresh( IBC_SerialChan, boardAddr,
        warnThresh, alarmThresh) == ERROR)
        return (ERROR);

    warnThresh[chan]  = warn;
    alarmThresh[chan] = alarm;

    return (IBC_LPS_SetCurrentThresh( IBC_SerialChan, boardAddr,
        warnThresh, alarmThresh));
} /* IBC_LPS_SetChanCurrentThresh() */

/****************************************************************************/
/* Function    : IBC_LPS_GetAlarmStatus                                     */
/* Purpose     : Read IBC Low Power Switch Board Alarms                     */
/* Inputs      : Sio32 channel, Board Address, Various Alarms               */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_GetAlarmStatus( sio32Chan *IBC_SerialChan, Word boardAddr,
    ibcAlarm currentAlarms[], ibcAlarm *vicorTempAlarm,
    ibcAlarm *switchTempAlarm, ibcAlarm *vicorVoltageAlarm )
{
    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 | LPS_GET_ALARM_STATUS,  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          */
    currentAlarms[0] = (ibcAlarm) wordFromBuf(&reply, sizeof(Word));
    currentAlarms[1] = (ibcAlarm) wordFromBuf(&reply, sizeof(Word) * 2);
    currentAlarms[2] = (ibcAlarm) wordFromBuf(&reply, sizeof(Word) * 3);
    currentAlarms[3] = (ibcAlarm) wordFromBuf(&reply, sizeof(Word) * 4);

    *vicorTempAlarm    = (ibcAlarm) wordFromBuf(&reply, sizeof(Word) * 5);
    *switchTempAlarm   = (ibcAlarm) wordFromBuf(&reply, sizeof(Word) * 6);
    *vicorVoltageAlarm = (ibcAlarm) wordFromBuf(&reply, sizeof(Word) * 7);

    return (OK);                    /* Return OK                            */
} /* IBC_LPS_GetAlarmStatus() */

/****************************************************************************/
/* Function    : IBC_LPS_GangOutputs                                        */
/* Purpose     : Enable/disable gang output mode for LPS switch chan pairs  */
/* Inputs      : Sio32 channel, IBC Board Address, Channel, gang state      */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_GangOutputs( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 channel, MBool gangState )
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         4, IBC_CPU_APP | LPS_SET_GANG_OUTPUT, boardAddr,
         channel, gangState ) == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_LPS_GangOutputs() */

/****************************************************************************/
/* Function    : IBC_LPS_SetSwitchDelay                                     */
/* Purpose     : Set LPS switch on delay for voltage checking               */
/* Inputs      : Sio32 channel, IBC Board Address, Delay time 10 msec units */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
IBC_LPS_SetSwitchDelay( sio32Chan *IBC_SerialChan, Word boardAddr,
    Nat16 delayTime)
{
    Word    status;                 /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( IBC_SerialChan, &status, sizeof(status),
         3, IBC_CPU_APP | LPS_SET_SWITCH_DELAY, boardAddr, delayTime)
         == ERROR ) return(ERROR);

                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* IBC_LPS_SetSwitchDelay() */
