/****************************************************************************/
/* Copyright 1996 MBARI                                                     */
/****************************************************************************/
/* Summary  : IBC Hydrophone PSU Board Functions                            */
/* Filename : hydroPSU.c                                                    */
/* Author   : Andrew Pearce                                                 */
/* Project  : Tiburon ROV IBC Based Data Concentrator                       */
/* Version  : 1.0                                                           */
/* Created  : 06/09/96                                                      */
/* Modified : 06/09/96                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: /usr/tiburon/.cvsroot/micro/ibc/boards/hydropsu/hydropsu.c,v 1.2 1997/05/07 15:29:39 pean Exp $
 * $Log: hydropsu.c,v $
 * Revision 1.2  1997/05/07 15:29:39  pean
 * Cleaned up Include files and makefile for new directory structure.
 *
 * Revision 1.1.1.1  1997/05/02 18:51:35  pean
 * Initial check in of IBC microcontroller software
 *
*/
/****************************************************************************/

#pragma model(196)
#pragma nosignedchar

#include "C:/C96/include/stddef.h"      /* C Standard Definitions           */
#include "const.h"                      /* Misc. constants - TRUE/FALSE etc */
#include "types.h"                      /* MBARI style guide declarations   */
#include "microasm.h"                   /* Assembly language functions      */
#include "microdef.h"                   /* Microcontroller definitions      */
#include "microlib.h"                   /* Microcontroller Library decls.   */
#include "malloc.h"                     /* Malloc support routines          */
#include "microCmd.h"                   /* microcontroller commands         */
#include "applay.h"                     /* Application layer funcitions     */

#include "filter.h"                     /* General Filter Routines          */
#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 "ibc_asm.h"                    /* IBC Assembly Language Functions  */

#include "hydroPSU.h"                   /* Hydrophone PSU Switch Board Defs */

/****************************************************************************/
/* Function    : hydroPSU_BoardSearch                                       */
/* Purpose     : Scans IBC backplane looking for Hydrophone PSU Boards      */
/* Inputs      : IBC Board Entry Table and maximum table size               */
/* Outputs     : Returns number of boards found                             */
/****************************************************************************/
    Int16
hydroPSU_BoardSearch( IBC_BoardEntry *IBC_Boards[], Int16 maxCards )
{
    Byte  *addr;                        /* hydro PSU Board base address     */
    Int16 board;                        /* Counts number of PSU boards found*/
    IBC_BoardEntry *boardEntry;         /* Pointer to hydroPSU data struct  */

    board = 0;                          /* Set board count to zero          */
    if (maxCards > 0)                   /* Check for space in IBC Card Table*/
    {
        if ((boardEntry = (IBC_BoardEntry *)
             hydroPSU_BoardInit( (Byte*) HYDROPHONE_PSU_ADDR)) != NULL)
        {                          /* Add hydroPSU data struct to IBC Table */
            IBC_Boards[board++] = boardEntry;
            if (board == maxCards)      /* Check if IBC Card Table is full  */
                return(board);     /* Return number of hydroPSU boards found*/
        } /* if */
    } /* if */

    return(board);                 /* Return number of hydroPSU boards found*/
} /* hydroPSU_BoardSearch() */

/****************************************************************************/
/* Function    : hydroPSU_BoardInit                                         */
/* Purpose     : Hydrophone Power Supply Board Initialization routine       */
/* Inputs      : Base address of Hydrophone PSU board                       */
/* Outputs     : Returns pointer to IBC board data structure                */
/****************************************************************************/
    hydroPSU_BoardEntry*
hydroPSU_BoardInit( Byte *boardBaseAddr )
{
    hydroPSU_BoardEntry *hydroPSU_Board;/* Pointer to board entry           */
                                        /* Check if board exists by reading */
                                        /* Status Register. Returns OK if   */
                                        /* board asserts xack               */
    if ( ibcBusReadByte( boardBaseAddr + HYDRO_PSU_STATUS_REG) == ERROR )
        return(( hydroPSU_BoardEntry *) NULL);
                                        /* Board doesn't exist return NULL  */

                                        /* Allocate space for board entry   */
    hydroPSU_Board = (hydroPSU_BoardEntry *)
        malloc( sizeof (hydroPSU_BoardEntry) );

    if (hydroPSU_Board == (hydroPSU_BoardEntry *) NULL )
        return( (hydroPSU_BoardEntry *) NULL);
                                        /* Insufficient memory return NULL  */

                                        /* Fill out board entry structure   */
    hydroPSU_Board->IBC_Board.baseAddress  = boardBaseAddr;
    hydroPSU_Board->IBC_Board.boardType    = HYDROPHONE_PSU;
    hydroPSU_Board->IBC_Board.intrLevel    = IBC_INT_LVL_OFF;

    hydroPSU_Board->psuStatus = hydroPSU_BoardSwitchState(hydroPSU_Board);
    hydroPSU_BoardSwitch( hydroPSU_Board, OFF );  /* Switch PSU OFF, LED ON */

    return (hydroPSU_Board);       /* Return pointer to hydroPSU data struct*/
} /* hydroPSU_BoardInit() */

/****************************************************************************/
/* Function    : hydroPSU_BoardSwitch                                       */
/* Purpose     : Control state of Hydrophone PSU Board - On or Off          */
/* Inputs      : hydroPSU Board data structure and desired switch state     */
/* Outputs     : Returns result of IBC Bus Write - OK or ERROR if timeout   */
/****************************************************************************/
   Int16
hydroPSU_BoardSwitch( hydroPSU_BoardEntry *hydroPSU_Board, Boolean state )
{
    Byte switchCmd;

    if ( hydroPSU_Board == NULL)        /* Check for valid hydroPSU struct  */
         return (ERROR);

    if (state == ON)                    /* Desired switch state is On       */
    {                                   /* Set software copy of switch state*/
        hydroPSU_Board->switchState = ON;
        switchCmd = HYDRO_PSU_SWITCH_ON;
    } /* if */
    else                                /* Desired switch state is Off      */
    {                                   /* Set software copy of switch state*/
        hydroPSU_Board->switchState = OFF;
        switchCmd = HYDRO_PSU_SWITCH_OFF;
    } /* else */

    return(ibcBusWriteByte(             /* Set physical switch state        */
        hydroPSU_Board->IBC_Board.baseAddress + HYDRO_PSU_COMMAND_REG,
           switchCmd | HYDRO_PSU_LED_ON));
} /* hydroPSU_BoardSwitch() */

/****************************************************************************/
/* Function    : hydroPSU_BoardSwitchState                                  */
/* Purpose     : Return PSU Failed bit from Hydrophone PSU Board            */
/* Inputs      : hydroPSU Board data structure                              */
/* Outputs     : Returns PSU State bits or ERROR if timeout                 */
/****************************************************************************/
    Int16
hydroPSU_BoardSwitchState( hydroPSU_BoardEntry *hydroPSU_Board )
{
    Int16 psuStatus;              /* Reads status bits from hydroPSU board */

    if ( hydroPSU_Board == NULL)  /* Check for valid hydroPSU data struct  */
         return (ERROR);
                                  /* Read hydroPSU Board Status Register   */
    if ( (psuStatus = ibcBusReadByte(hydroPSU_Board->IBC_Board.baseAddress +
        HYDRO_PSU_STATUS_REG) ) == ERROR)
        return(ERROR);
    else                          /* Mask off PSU Failed status bit        */
        return(psuStatus & HYDRO_PSU_FAILED);
} /* hydroPSU_BoardSwitchState() */

/****************************************************************************/
/* Function    : hydroPSU_SwitchControlCmd                                  */
/* Purpose     : Process command to switch Hydrohone PSU On or Off          */
/* Inputs      : IBC Card Table, Number of cards & serial command buffer    */
/* Outputs     : None, but switch state is modified                         */
/****************************************************************************/
    Void
hydroPSU_SwitchControlCmd( IBC_BoardEntry* IBC_CardTable[], Int16 IBC_CardCount,
    Byte *commandBuf )
{
    Byte    *boardAddr;         /* hydroPSU Board base address              */
    Boolean state;              /* hydroPSU Board desired switch state      */
    Int16   card;               /* Card index into Card Table               */
    Word    command;            /* Serial command word - ignored            */
    hydroPSU_BoardEntry *hydroPSU_Board;  /* hydroPSU board data structure  */

                                /* Extract command and arguments from buffer*/
    wordsFromBuf(commandBuf, 3, &command, &boardAddr, &state);

                                /* Find card table index for this address   */
    if ( (card = ibcBoardTableIndex(IBC_CardTable, IBC_CardCount,
                 boardAddr, HYDROPHONE_PSU) ) == ERROR)
    {                           /* Card not present so return error         */
        replyToCommand(1, EARGUMENT);
        return;
    } /* if */

                           /* Get pointer to hydroPSU data structure        */
    hydroPSU_Board = (hydroPSU_BoardEntry *) IBC_CardTable[card];

    state = (state ? ON : OFF); /* Translate any non-zero value to ON       */

                                /* Change physical switch state             */
    if (hydroPSU_BoardSwitch( hydroPSU_Board, state) != ERROR)
        replyToCommand(1, CMD_OK);      /* Report status to serial port     */
    else
        replyToCommand(1, CMD_ERROR);   /* Report ERROR to serial port      */

} /* hydroPSU_SwitchControlCmd() */

/****************************************************************************/
/* Function    : hydroPSU_GetPSUStateCmd                                    */
/* Purpose     : Process command to read hydro PSU On/Off Status            */
/* Inputs      : IBC Card Table, Number of cards & serial command buffer    */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
hydroPSU_GetPSUStateCmd(IBC_BoardEntry* IBC_CardTable[], Int16 IBC_CardCount,
    Byte *commandBuf)
{
    Int16   card;               /* Card index into Card Table               */
    Byte    *boardAddr;         /* hydro PSU Board base address             */
    hydroPSU_BoardEntry *hydroPSU_Board;  /* hydro PSU Board Entry structure*/

                                /* Extract command and arguments from buffer*/
    boardAddr = (Byte*) wordFromBuf(commandBuf, sizeof(Word));

                                /* Find card table index for this address   */
    if ( (card = ibcBoardTableIndex(IBC_CardTable, IBC_CardCount,
                 boardAddr, HYDROPHONE_PSU) ) == ERROR)
    {                           /* Card not present so return error         */
        replyToCommand(1, EARGUMENT);
        return;
    } /* if */
                                /* Extract pointer to hydroPSU structure    */
    hydroPSU_Board = (hydroPSU_BoardEntry *) IBC_CardTable[card];

                                /* Send PSU On/Off Status to serial port    */
    replyToCommand(2, CMD_OK, (Word) hydroPSU_Board->switchState);
} /* hydroPSU_GetPSUStateCmd() */

/****************************************************************************/
/* Function    : hydroPSU_GetFaultCmd                                       */
/* Purpose     : Process command to read hydro PSU Fault Bit                */
/* Inputs      : IBC Card Table, Number of cards & serial command buffer    */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
hydroPSU_GetFaultCmd(IBC_BoardEntry* IBC_CardTable[], Int16 IBC_CardCount,
    Byte *commandBuf)
{
    Byte    *boardAddr;         /* hydro PSU Board base address             */
    Int16   card;               /* Card index into Card Table               */
    Int16   psuStatus;          /* Hydrophone PSU Status                    */

                                /* Extract board address from buffer        */
    boardAddr = (Byte*) wordFromBuf(commandBuf, sizeof(Word));

                                /* Find card table index for this address   */
    if ( (card = ibcBoardTableIndex(IBC_CardTable, IBC_CardCount,
                 boardAddr, HYDROPHONE_PSU) ) == ERROR)
    {                           /* Card not present so return error         */
        replyToCommand(1, EARGUMENT);
        return;
    } /* if */
                           /* Read PSU Fault Status from hydro PSU Board    */
    if (( psuStatus = hydroPSU_BoardSwitchState( (hydroPSU_BoardEntry *)
         IBC_CardTable[card] )) == ERROR)
        replyToCommand(1, CMD_ERROR);         /* Report ERROR to serial port*/
    else
                                              /* Report switch status       */
        replyToCommand(2, CMD_OK, psuStatus);
} /* hydroPSU_GetFaultCmd() */

/****************************************************************************/
/* Function    : hydroPSUFunctions                                          */
/* Purpose     : Hydrophone PSU Board real-time loop functions              */
/* Inputs      : hydroPSU Board data structure                              */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
hydroPSUFunctions( hydroPSU_BoardEntry *hydroPSU_Board )
{
    Int16   psuStatus;          /* Hydrophone PSU Status                    */

    if (hydroPSU_Board->switchState == OFF)
	return;
                                /* Read PSU Fault Status from hydro PSU Brd */
    if (( psuStatus = hydroPSU_BoardSwitchState(hydroPSU_Board)) == ERROR)
	return;

    if ( hydroPSU_Board->psuStatus != psuStatus)
    {
	hydroPSU_Board->psuStatus = psuStatus;
	writeServiceRequest(2, HYDRO_PSU_FAULT_SRQ, psuStatus);
    } /* if */
} /* hydroPSUFunctions() */



