/****************************************************************************/
/* Copyright 1992 to 1996 MBARI                                             */
/****************************************************************************/
/* Summary  : IBC Regen Controller Board Data Manager Functions for VxWorks */
/* Filename : regenDm.c                                                     */
/* Author   : Andrew Pearce                                                 */
/* Project  : Tiburon ROV                                                   */
/* Version  : Version 1.0                                                   */
/* Created  : 06/08/93                                                      */
/* Modified : 08/12/96                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: regenDm.c,v 1.1 93/07/01 14:34:33 pean Exp $
 * $Log:        regenDm.c,v $
 * Revision 1.1  93/07/01  14:34:33  14:34:33  pean (Andrew Pearce)
 * Initial revision
 *
 *
 */
/****************************************************************************/

/* ******************************* To Do *************************************
 * Add sub-sampling and IIR filter to Duty Cycles to
 * calculate Heater 1 and Heater 2 temperatures.
 *
 * Threshold check heater 1 and heater 2 temperature
 * readings and update heater 1 & 2 alarms

 ****************************************************************************/

#include <vxWorks.h>                /* vxWorks system declarations          */
#include <semLib.h>                 /* vxWorks semaphore functions          */
#include <msgQLib.h>                /* vxWorks Message Queue Library        */

#include <mbariTypes.h>             /* MBARI style guide type declarations  */
#include <mbariConst.h>             /* Miscellaneous MBARI constants        */

#include "sio32.h"                  /* SIO32 hardware and driver information*/
#include <sio32Server.h>            /* Sio32 server communication services  */
#include <sio32Client.h>            /* Sio32 client communication services  */

#include <datamgr.h>                /* Data Manager declarations            */
#include <dm_errno.h>               /* Data Manager error declarations      */

#include "microcmd.h"               /* Microcontroller commands             */
#include "ibc_card.h"               /* IBC Card Types                       */
#include "ibc_cmd.h"                /* IBC Serial Commands                  */
#include "filter.h"                 /* General Filter Routines              */
#include "timer.h"                  /* Timer library definitions            */
#include "regen.h"                  /* Regen Controller Board Definitions   */

#include "microDm.h"                /* Micro Data Manager Items & Functions */
#include "regenDm.h"                /* Defines & Functions for regenDm.c     */

/*****************************************************************************/
/* Function    : createRegenDmItems                                          */
/* Purpose     : Initialize Data Manager Items for Regen Controller Board    */
/* Inputs      : Pointer to structure containing IBC Regen Data Manager Items*/
/*               and IBC Data Concentrator Name                              */
/* Outputs     : None, but Data Manager Items change                         */
/*****************************************************************************/
    STATUS
createIbcRegenDmItems( ibcRegenDmItems *regenDmItems, const char* ibcDmPrefix,
    const char* ibcDataCon )
{
    Int32   item;                   /* Counter for DM Item Initialization   */
    Errno   status;                 /* Result of dm_create function call    */

    struct                          /* Data Manager Item Table for table    */
    {                               /* driven item initialization           */
        DM_Item *dmItem;            /* pointer to actual dm item handle     */
        char    *errorMsg;          /* Message to display of dmCreate fails */
        char    *name;              /* Data Manager Item Name               */
        DM_Type type;               /* Data Manager Item Type               */
        DM_Num  len;                /* Data Manager Item Element Count      */
    } regenDmInit[] =

      { { &regenDmItems->busVoltage,            "Regen Bus Voltage",
              REGEN_BUS_VOLTAGE_DM,               DM_INT16, 1 },

        { &regenDmItems->dutyCycle1,            "Regen Duty Cycle 1",
              REGEN_DUTY_CYCLE1_DM,               DM_INT16, 1 },

        { &regenDmItems->dutyCycle2,            "Regen Duty Cycle 2",
              REGEN_DUTY_CYCLE2_DM,               DM_INT16, 1 },

        { &regenDmItems->heatsinkTemp,          "Regen Heatsink Temp",
              REGEN_HEATSINK_TEMP_DM,             DM_INT16, 1 },

        { &regenDmItems->heatsinkWarnThresh,     "Regen Heatsink Warn Temp",
              REGEN_TEMP_WARN_THRESH_DM,          DM_INT16, 1 },

        { &regenDmItems->heatsinkAlarmThresh,   "Regen Heatsink Alarm Temp",
              REGEN_TEMP_ALARM_THRESH_DM,         DM_INT16, 1 },

        { &regenDmItems->heatsinkTempAlarm,     "Regen Heatsink Temp Alarm",
              REGEN_HEATSINK_TEMP_ALARM_DM,       DM_ENUM, 1 },

        { &regenDmItems->heater1Temp,           "Regen Heater 1 Temp",
              REGEN_HEATER1_TEMP_DM,              DM_INT16, 1 },

        { &regenDmItems->heater1WarnThresh,     "Regen Heater 1 Warn Thresh",
              REGEN_HEATER1_TEMP_WARN_THRESH_DM,  DM_INT16, 1 },

        { &regenDmItems->heater1AlarmThresh,    "Regen Heater 1 Alarm Temp",
              REGEN_HEATER1_TEMP_ALARM_THRESH_DM, DM_INT16, 1 },

        { &regenDmItems->heater1TempAlarm,      "Regen Heater 1 Temp Alarm",
              REGEN_HEATER1_TEMP_ALARM_DM,        DM_ENUM, 1 },

        { &regenDmItems->heater2Temp,           "Regen Heater 2 Temp",
              REGEN_HEATER2_TEMP_DM,              DM_INT16, 1 },

        { &regenDmItems->heater2WarnThresh,     "Regen Heater 2 Warn Thresh",
              REGEN_HEATER2_TEMP_WARN_THRESH_DM,  DM_INT16, 1 },

        { &regenDmItems->heater2AlarmThresh,    "Regen Heater 2 Alarm Temp",
              REGEN_HEATER2_TEMP_ALARM_THRESH_DM, DM_INT16, 1 },

        { &regenDmItems->heater2TempAlarm,      "Regen Heater 2 Temp Alarm",
              REGEN_HEATER2_TEMP_ALARM_DM,        DM_ENUM, 1 },

        { &regenDmItems->minBusVoltage,         "Regen Minimum Bus Voltage",
              REGEN_MIN_BUS_VOLTAGE_DM,           DM_INT16, 1 },

        { &regenDmItems->minBusVoltWarnThresh,  "Regen Min Warning Voltage",
              REGEN_MIN_VOLT_WARN_THRESH_DM,      DM_INT16, 1 },

        { &regenDmItems->minBusVoltAlarmThresh, "Regen Min Alarm Voltage",
              REGEN_MIN_VOLT_ALARM_THRESH_DM,     DM_INT16, 1 },

        { &regenDmItems->minBusVoltageAlarm,    "Regen Min Voltage Alarm",
              REGEN_MIN_VOLTAGE_ALARM_DM,          DM_ENUM, 1 },

        { &regenDmItems->maxBusVoltage,         "Regen Maximum Bus Voltage",
              REGEN_MAX_BUS_VOLTAGE_DM,           DM_INT16, 1 },

        { &regenDmItems->maxBusVoltWarnThresh,  "Regen Max Warning Voltage",
              REGEN_MAX_VOLT_WARN_THRESH_DM,      DM_INT16, 1 },

        { &regenDmItems->maxBusVoltAlarmThresh, "Regen Max Alarm Voltage",
              REGEN_MAX_VOLT_ALARM_THRESH_DM,     DM_INT16, 1 },

        { &regenDmItems->maxBusVoltageAlarm,    "Regen Max Voltage Alarm",
              REGEN_MAX_VOLT_ALARM_DM,            DM_ENUM, 1 },

        { &regenDmItems->resetMinMaxVoltCmd,    "Regen Min/Max Voltage Reset",
              REGEN_RESET_MIN_MAX_DM,             DM_EMPTY, 1 },

        { &regenDmItems->openHeaterAlarm,       "Regen Open Heater Alarm",
              REGEN_OPEN_HEATER_ALARM_DM,         DM_MBOOL, 1 },

        { &regenDmItems->dutyCycleAlarm,        "Regen Duty Cycle Alarm",
              REGEN_DUTY_CYCLE_ALARM_DM,          DM_MBOOL, 1 },

        { &regenDmItems->digitalScopeChan,      "Regen Digital Scope Channel",
              REGEN_DIGITAL_SCOPE_CHAN_DM,        DM_INT16, 1 },

        { &regenDmItems->digitalScopeData,      "Regen Digital Scope Data",
              REGEN_DIGITAL_SCOPE_DATA_DM,        DM_UCHAR, REGEN_SAMPLES },

        { NO_ITEM, NULL, NULL, DM_ENDT, 0 } };

                                    /* Clear list of Data Manager Item handles*/
    bzero(regenDmItems, sizeof(ibcRegenDmItems));

                                   /* Initialize Data Manager Items from table*/
    for (item = 0; regenDmInit[item].dmItem != NO_ITEM; item++)
    {
        if ((*regenDmInit[item].dmItem =
             initMicroDmItem(ibcDmPrefix, regenDmInit[item].name,
             regenDmInit[item].type, regenDmInit[item].len)) == ERROR)

        {                           /* Error occurred so print message & exit */
            logMsg("%s: Error Initializing %s DM Item\n",
                ibcDataCon, regenDmInit[item].errorMsg);
            return(ERROR);
        } /* if */
    } /* for */

    return(OK);                     /* All IBC CPU Data Mgr items initialized */
} /* createIbcRegenDmItems() */

    Void
initIbcRegenProvider( ibcRegenDmItems* regenItems, Period period )
{
    dm_start_provider(regenItems->busVoltage,    period);
    dm_start_provider(regenItems->dutyCycle1,    period);
    dm_start_provider(regenItems->dutyCycle2,    period);

    dm_start_provider(regenItems->heatsinkTemp,  period);
    dm_start_provider(regenItems->heater1Temp,   period);
    dm_start_provider(regenItems->heater2Temp,   period);

    dm_start_provider(regenItems->minBusVoltage, period);
    dm_start_provider(regenItems->maxBusVoltage, period);
} /* initIbcRegenProvider() */

    Void
initIbcRegenAlarmProvider( ibcRegenDmItems* regenItems )
{
    dm_start_provider(regenItems->heatsinkTempAlarm,  DM_STATIC);
    dm_start_provider(regenItems->heater1TempAlarm,   DM_STATIC);
    dm_start_provider(regenItems->heater2TempAlarm,   DM_STATIC);

    dm_start_provider(regenItems->minBusVoltageAlarm, DM_STATIC);
    dm_start_provider(regenItems->maxBusVoltageAlarm, DM_STATIC);

    dm_start_provider(regenItems->openHeaterAlarm, DM_STATIC);
    dm_start_provider(regenItems->dutyCycleAlarm, DM_STATIC);
} /* initIbcRegenAlarmProvider() */


    DWord
initIbcRegenConsumer( ibcRegenDmItems* regenItems, regenUpdateBits *regenBits,
    SEM_ID updateSem )
{
    DWord regenGroup;

    regenGroup = dm_create_group();    /* Create Data Manager Group for regen*/

    dm_start_consumer(regenItems->heatsinkWarnThresh,    DM_STATIC, updateSem);
    dm_start_consumer(regenItems->heatsinkAlarmThresh,   DM_STATIC, updateSem);
    dm_start_consumer(regenItems->heater1WarnThresh,     DM_STATIC, updateSem);
    dm_start_consumer(regenItems->heater1AlarmThresh,    DM_STATIC, updateSem);
    dm_start_consumer(regenItems->heater2WarnThresh,     DM_STATIC, updateSem);
    dm_start_consumer(regenItems->heater2AlarmThresh,    DM_STATIC, updateSem);
    dm_start_consumer(regenItems->minBusVoltWarnThresh,  DM_STATIC, updateSem);
    dm_start_consumer(regenItems->minBusVoltAlarmThresh, DM_STATIC, updateSem);
    dm_start_consumer(regenItems->maxBusVoltWarnThresh,  DM_STATIC, updateSem);
    dm_start_consumer(regenItems->maxBusVoltAlarmThresh, DM_STATIC, updateSem);
    dm_start_consumer(regenItems->resetMinMaxVoltCmd,    DM_STATIC, updateSem);

    dm_start_consumer(regenItems->digitalScopeChan, DM_STATIC, updateSem);
    dm_start_provider(regenItems->digitalScopeData, DM_STATIC);

    dm_group_add_item(regenGroup, regenItems->heatsinkWarnThresh,
         &regenBits->heatsinkWarnBit );

    dm_group_add_item(regenGroup, regenItems->heatsinkAlarmThresh,
         &regenBits->heatsinkAlarmBit);

    dm_group_add_item(regenGroup, regenItems->heater1WarnThresh,
         &regenBits->heater1WarnBit);

    dm_group_add_item(regenGroup, regenItems->heater1AlarmThresh,
         &regenBits->heater1AlarmBit);

    dm_group_add_item(regenGroup, regenItems->heater2WarnThresh,
         &regenBits->heater2WarnBit);

    dm_group_add_item(regenGroup, regenItems->heater2AlarmThresh,
         &regenBits->heater2AlarmBit);

    dm_group_add_item(regenGroup, regenItems->minBusVoltWarnThresh,
         &regenBits->minBusVoltWarnBit);

    dm_group_add_item(regenGroup, regenItems->minBusVoltAlarmThresh,
         &regenBits->minBusVoltAlarmBit);

    dm_group_add_item(regenGroup, regenItems->maxBusVoltWarnThresh,
         &regenBits->maxBusVoltWarnBit);

    dm_group_add_item(regenGroup, regenItems->maxBusVoltAlarmThresh,
         &regenBits->maxBusVoltAlarmBit);

    dm_group_add_item(regenGroup, regenItems->resetMinMaxVoltCmd,
         &regenBits->resetMinMaxBit);

    dm_group_add_item(regenGroup, regenItems->digitalScopeChan,
         &regenBits->digitalScopeChanBit);

    return (regenGroup);
} /* initIbcRegenConsumer() */

    STATUS
updateIbcRegenDm( sio32Chan *sio32DataChan, Word boardAddr,
    ibcRegenDmItems *regenItems )
{
    Int16 dutyCycle1, dutyCycle2;
    Int16 busVoltage, minBusVoltage, maxBusVoltage;
    Int16 heatsinkTemp, heater1Temp, heater2Temp;

    if (IBC_regenGetMeasurements( sio32DataChan, boardAddr,
        &dutyCycle1,    &dutyCycle2,    &busVoltage,
        &minBusVoltage, &maxBusVoltage, &heatsinkTemp ) != OK)
        return (ERROR);

    heater1Temp = 0;
    heater2Temp = 0;

    writeDmItem( regenItems->busVoltage, &busVoltage, sizeof(busVoltage) );
    writeDmItem( regenItems->minBusVoltage, &minBusVoltage,
                sizeof(minBusVoltage) );

    writeDmItem(regenItems->maxBusVoltage, &maxBusVoltage,
                sizeof(maxBusVoltage) );

    writeDmItem( regenItems->dutyCycle1,   &dutyCycle1,   sizeof(dutyCycle1) );
    writeDmItem( regenItems->dutyCycle2,   &dutyCycle2,   sizeof(dutyCycle2) );
    writeDmItem( regenItems->heatsinkTemp, &heatsinkTemp, sizeof(heatsinkTemp));
    writeDmItem( regenItems->heater1Temp,  &heater1Temp,  sizeof(heater1Temp) );

    return( writeDmItem( regenItems->heater2Temp, &heater2Temp,
                        sizeof(heater2Temp) ) );
} /* updateIbcRegenDm() */

    STATUS
updateIbcRegenAlarmsDm( sio32Chan *sio32DataChan, Word boardAddr,
    ibcRegenDmItems *regenItems )
{
    ibcAlarm heatsinkTempAlarm, minBusVoltAlarm, maxBusVoltAlarm;
    ibcAlarm heater1Alarm = MICRO_ALARM_OK, heater2Alarm = MICRO_ALARM_OK;
    MBool openHeaterAlarm, dutyCycleAlarm;

    if (IBC_regenGetAlarmStatus( sio32DataChan, boardAddr, &heatsinkTempAlarm,
        &minBusVoltAlarm, &maxBusVoltAlarm, &openHeaterAlarm, &dutyCycleAlarm)
        != OK) return (ERROR);

                                    /* Write alarm status to Data Manager */
    writeDmItem(regenItems->heatsinkTempAlarm, &heatsinkTempAlarm,
                        sizeof(heatsinkTempAlarm) );

    writeDmItem(regenItems->minBusVoltageAlarm, &minBusVoltAlarm,
                        sizeof(minBusVoltAlarm) );

    writeDmItem(regenItems->maxBusVoltageAlarm, &maxBusVoltAlarm,
                        sizeof(maxBusVoltAlarm) );

    writeDmItem(regenItems->openHeaterAlarm, &openHeaterAlarm,

                        sizeof(openHeaterAlarm) );

    writeDmItem(regenItems->dutyCycleAlarm, &dutyCycleAlarm,
                        sizeof(dutyCycleAlarm) );

    writeDmItem(regenItems->heater1TempAlarm, &heater1Alarm,
                        sizeof(heater1Alarm) );

    return (writeDmItem(regenItems->heater2TempAlarm, &heater2Alarm,
                        sizeof(heater2Alarm) ));
} /* updateIbcRegenAlarmsDm() */

/*****************************************************************************/
/* Function    : initIbcRegenDmItems                                         */
/* Purpose     : Reads Regen Board parameters from IBC & update Data Manager */
/* Inputs      : Array of Data Manager Item handles & serial chan structure  */
/* Outputs     : None, but Data Manager Items change                         */
/*****************************************************************************/
    Void
initIbcRegenDmItems( sio32Chan* sio32DataChan, Word boardAddr,
    ibcRegenDmItems* regenItems, const char* ibcDataCon )
{
    Int16 warnThresh,  alarmThresh;
    Int16 voltMinWarn, voltMinAlarm;
    Int16 voltMaxWarn, voltMaxAlarm;

    if (IBC_regenGetTempThresh( sio32DataChan, boardAddr,
        &warnThresh, &alarmThresh ) == ERROR)
    {
        logMsg("%s: Error reading Regen Temp Alarm Thresholds\n", ibcDataCon);
        return;
    } /* if */

    if (IBC_regenGetVoltageThresh( sio32DataChan, boardAddr,
        &voltMinWarn, &voltMinAlarm, &voltMaxWarn, &voltMaxAlarm ) == ERROR)
    {
        logMsg("%s: Error reading Regen Voltage Alarm Thresholds\n",
               ibcDataCon);
        return;
    } /* if */
                                /* Regen Temp Alarm Threshold initial values*/
    urgentWriteDmItem( regenItems->heatsinkWarnThresh,
                      &warnThresh, sizeof(warnThresh) );

    urgentWriteDmItem( regenItems->heatsinkAlarmThresh,
                      &alarmThresh, sizeof(alarmThresh) );

    warnThresh  = REGEN_HEATER_WARN_THRESH;
    alarmThresh = REGEN_HEATER_ALARM_THRESH;

    urgentWriteDmItem( regenItems->heater1WarnThresh,
                      &warnThresh, sizeof(warnThresh) );

    urgentWriteDmItem( regenItems->heater1AlarmThresh,
                      &alarmThresh, sizeof(alarmThresh) );

    urgentWriteDmItem( regenItems->heater2WarnThresh,
                      &warnThresh, sizeof(warnThresh) );

    urgentWriteDmItem( regenItems->heater2AlarmThresh,
                      &alarmThresh, sizeof(alarmThresh) );

    urgentWriteDmItem( regenItems->minBusVoltWarnThresh,
                      &voltMinWarn, sizeof(voltMinWarn) );

    urgentWriteDmItem( regenItems->minBusVoltAlarmThresh,
                      &voltMinAlarm, sizeof(voltMinAlarm) );

    urgentWriteDmItem( regenItems->maxBusVoltWarnThresh,
                      &voltMaxWarn, sizeof(voltMaxWarn) );

    urgentWriteDmItem( regenItems->maxBusVoltAlarmThresh,
                      &voltMaxAlarm, sizeof(voltMaxAlarm) );
} /* initIbcRegenDmItems() */


    STATUS
ibcRegenSetBusVoltageAlarmThresh(sio32Chan* sio32DataChan, Word boardAddr,
    ibcRegenDmItems *regenItems,
    Int16 voltMinWarn, Int16 voltMinAlarm,
    Int16 voltMaxWarn, Int16 voltMaxAlarm)
{
    urgentWriteDmItem( regenItems->minBusVoltWarnThresh,
                      &voltMinWarn, sizeof(voltMinWarn) );

    urgentWriteDmItem( regenItems->minBusVoltAlarmThresh,
                      &voltMinAlarm, sizeof(voltMinAlarm) );

    urgentWriteDmItem( regenItems->maxBusVoltWarnThresh,
                      &voltMaxWarn, sizeof(voltMaxWarn) );

    urgentWriteDmItem( regenItems->maxBusVoltAlarmThresh,
                      &voltMaxAlarm, sizeof(voltMaxAlarm) );

    return(IBC_regenSetVoltageThresh( sio32DataChan, boardAddr,
         voltMinWarn, voltMinAlarm, voltMaxWarn, voltMaxAlarm));
} /* ibcRegenSetBusVoltageAlarmThresh() */

    Void
ibcRegenUpdateCheck( sio32Chan* sio32DataChan, Word boardAddr,
    ibcRegenDmItems* regenItems, regenUpdateBits *regenBits,
    DM_Group regenGroup )
{
    DWord regenGroupBits;           /* Holds dm_group_changes bit vector     */

    Int16 tempWarn, tempAlarm;
    Int16 minBusVoltWarn, minBusVoltAlarm;
    Int16 maxBusVoltWarn, maxBusVoltAlarm;

    Nat16 analogChannel;
    Byte  scopeReadings[REGEN_SAMPLES];

                                    /* Ask DMgr If Regen items have changed  */
    if ( (regenGroupBits = dm_get_group_changes(regenGroup)) == (DWord) 0)
        return;

                                    /* Regen Board Heatsink Temp Thresholds  */
    if ( (regenGroupBits & regenBits->heatsinkWarnBit)  ||
         (regenGroupBits & regenBits->heatsinkAlarmBit) )
    {
                                        /* Read Heatsink Thresholds from dmgr*/
        dm_read( regenItems->heatsinkWarnThresh, (char *) &tempWarn,
            sizeof(tempWarn), (DM_Time *) NULL);

        dm_read( regenItems->heatsinkAlarmThresh, (char *) &tempAlarm,
            sizeof(tempAlarm), (DM_Time *) NULL);

        IBC_regenSetTempThresh( sio32DataChan, boardAddr, tempWarn, tempAlarm);
    } /* if */

                                    /* Regen Board Voltage Thresholds        */
    if ( (regenGroupBits & regenBits->minBusVoltWarnBit)  ||
         (regenGroupBits & regenBits->minBusVoltAlarmBit) ||
         (regenGroupBits & regenBits->maxBusVoltWarnBit)  ||
         (regenGroupBits & regenBits->maxBusVoltAlarmBit) )
    {
                                    /* Read Voltage Thresholds from dmgr */
        dm_read( regenItems->minBusVoltWarnThresh, (char *) &minBusVoltWarn,
            sizeof(minBusVoltWarn), (DM_Time *) NULL);

        dm_read( regenItems->minBusVoltAlarmThresh, (char *) &minBusVoltAlarm,
            sizeof(minBusVoltAlarm), (DM_Time *) NULL);

        dm_read( regenItems->maxBusVoltWarnThresh, (char *) &maxBusVoltWarn,
            sizeof(maxBusVoltWarn), (DM_Time *) NULL);

        dm_read( regenItems->maxBusVoltAlarmThresh, (char *) &maxBusVoltAlarm,
            sizeof(maxBusVoltAlarm), (DM_Time *) NULL);

        IBC_regenSetVoltageThresh( sio32DataChan, boardAddr,
            minBusVoltWarn, minBusVoltAlarm, maxBusVoltWarn, maxBusVoltAlarm );
    } /* if */

    if (regenGroupBits & regenBits->resetMinMaxBit)
        IBC_regenResetMinMax( sio32DataChan, boardAddr );

    if (regenGroupBits & regenBits->digitalScopeChanBit)
    {
        dm_read( regenItems->digitalScopeChan, (char *) &analogChannel,
            sizeof(analogChannel), (DM_Time *) NULL);

        IBC_regenDigitalScope( sio32DataChan, boardAddr, analogChannel,
                              scopeReadings );

        writeDmItem( regenItems->digitalScopeData, &scopeReadings,
                    sizeof(scopeReadings) );
    } /* if */
} /* ibcRegenUpdateCheck() */

    MBool
processIbcRegenSRQ( Word srqRequest, Byte* buffer, Word regenBoardAddr,
    ibcRegenDmItems* regen )
{
    Word boardAddr;                 /* IBC Board Address                      */
    Word channel;                   /* IBC Board Channel Number               */
    Word status;                    /* IBC Alarm Status Word                  */
    ibcAlarm alarmStatus;           /* IBC Alarm Status                       */

    switch (srqRequest)
    {
        case REGEN_TEMP_ALARM_SRQ:
            wordsFromBuf(buffer, 3, &srqRequest, &status, &boardAddr);
            alarmStatus = (ibcAlarm) status;

            if (boardAddr != regenBoardAddr)
                return(FALSE);          /* Address missmatch                 */

            writeDmItem(regen->heatsinkTempAlarm, &alarmStatus,
                        sizeof(alarmStatus));
            break;

        case REGEN_MIN_VOLTAGE_ALARM_SRQ:
            wordsFromBuf(buffer, 3, &srqRequest, &status, &boardAddr);
            alarmStatus = (ibcAlarm) status;

            if (boardAddr != regenBoardAddr)
                return(FALSE);          /* Address missmatch                 */

            writeDmItem(regen->minBusVoltageAlarm, &alarmStatus,
                        sizeof(alarmStatus));
            break;

        case REGEN_MAX_VOLTAGE_ALARM_SRQ:
            wordsFromBuf(buffer, 3, &srqRequest, &status, &boardAddr);
            alarmStatus = (ibcAlarm) status;

            if (boardAddr != regenBoardAddr)
                return(FALSE);          /* Address missmatch                 */

            writeDmItem(regen->maxBusVoltageAlarm, &alarmStatus,
                        sizeof(alarmStatus));
            break;

        case REGEN_OPEN_HEATER_ALARM_ON:
        case REGEN_OPEN_HEATER_ALARM_OFF:
            wordsFromBuf(buffer, 2, &srqRequest, &boardAddr);

            if (boardAddr != regenBoardAddr)
                return(FALSE);          /* Address missmatch                 */

            if (srqRequest == REGEN_OPEN_HEATER_ALARM_ON)
                 writeBooleanDmItem(regen->openHeaterAlarm, TRUE);
             else
                 writeBooleanDmItem(regen->openHeaterAlarm, FALSE);
            break;

        case REGEN_BAD_DUTY_ALARM_ON:
            wordsFromBuf(buffer, 2, &srqRequest, &boardAddr);

            if (boardAddr != regenBoardAddr)
                return(FALSE);          /* Address missmatch                 */
            writeBooleanDmItem(regen->dutyCycleAlarm, TRUE);
            break;

        case REGEN_BAD_DUTY_ALARM_OFF:
            wordsFromBuf(buffer, 2, &srqRequest, &boardAddr);

            if (boardAddr != regenBoardAddr)
                return(FALSE);          /* Address missmatch                 */

            writeBooleanDmItem(regen->dutyCycleAlarm, FALSE);
            break;

        default:
            return(FALSE);              /* SRQ Request not recognized        */

    } /* switch */

    return(TRUE);                       /* SRQ Request recognized            */
} /* processIbcRegenSRQ() */












