/****************************************************************************/
/* Copyright 1995 MBARI                                                     */
/****************************************************************************/
/* Summary  : PDU Microcontroller Interface Module for VxWorks              */
/* Filename : pduMicro.c                                                    */
/* Author   : Douglas Au                                                    */
/* Project  : New ROV                                                       */
/* Version  : Version 1.0                                                   */
/* Created  : 05/22/95                                                      */
/* Modified : 04/30/98                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: pduMicro.c,v 1.1 95/05/22 16:14:21 audo Exp $
 * $Log:        pduMicro.c,v $
 * Revision 1.1  95/05/22  16:14:21  16:14:21  audo ( Douglas Au )
 * Initial revision
 * Revision 1.2  96/08/16  11:55:00  16:14:21  audo ( Douglas Au )
 * 3x5 Task Mods for microIOCtrl structure
 *
 */
/****************************************************************************/

#include <vxWorks.h>                /* vxWorks system declarations          */
#include <stdio.h>                  /* vxWorks standard IO file functions   */
#include <semLib.h>                 /* vxWorks semaphore functions          */
#include <taskLib.h>                /* vxWorks task library functions       */
#include <lstLib.h>                 /* vxWorks linked list library          */
#include <wdLib.h>                  /* vxWorks watch dog timer functions    */
#include <systime.h>                /* vxWorks time and date functions      */
#include <msgQLib.h>                /* vxWorks Message Queue Library        */

#include <mbariTypes.h>             /* MBARI style guide type declarations  */
#include <mbariConst.h>             /* Miscellaneous constants              */

#include <rovPriority.h>            /* MBARI Rov Application Priorities     */
#include <usrTime.h>                /* MBARI time and date functions        */

#include <datamgr.h>                /* Data Manager declarations            */
#include <dm_errno.h>               /* Data Manager error declarations      */

#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 "pduMicro.h"               /* PDU Micro Definitions                */
#include "microDm.h"                /* Micro Data Manager Items & Functions */
#include "powerTypes.h"             /* Power management Data Types          */

#define Boolean MBool               /* Map microcontroller Boolean to MBool */

#include "applic.h"                 /* Microcontroller applications         */
#include "microdef.h"               /* Microcontroller Definitions          */
#include "microcmd.h"               /* Microcontroller commands             */
#include "pdu.h"                    /* PDU Microcontroller defines          */
#include "tiburon.h"                /* Tiburon Power Status task            */
#include "microTask.h"              /* Microcontroller Task IO definitions  */

                                    /* PDU Micro Device Name                */
MLocal char* const pduMicroName = "PDU Micro";
                                    /* PDU Micro Data Mgr Item Name Prefix  */
MLocal char* const pduMicroAppPrefix  = PDU_MICRO_DM_PREFIX;

#define NUM_TASKS           3        /* Number of co-operating tasks        */

#define PDU_MICRO_DM_PERIOD   500000 /* PDU Telemetery Updatep period 2 Hz  */

#define PDU_MICRO_IN_STACKSIZE  2000 /* PDU Micro Input Task size & TCB     */
#define PDU_MICRO_OUT_STACKSIZE 2000 /* PDU Can Micro Output Task size & TCB*/

typedef struct                      /* PDU Micro Data Manager Items         */
{
    microDmItems microDm;           /* Microcontroller Data Manager Items   */

    DM_Item wattage;                /* PDU Wattage value                    */
    DM_Item wattageAlarm;           /* PDU Wattage alarm value              */
    DM_Item wattageWarnThresh;      /* PDU Wattage Warning Threshold        */
    DM_Item wattageAlarmThresh;     /* PDU Wattage alarm threshold          */

    DM_Item ampsPhase3;             /* PDU Amperage value                   */
    DM_Item ampsPhase3Alarm;        /* PDU Amperage alarm value             */
    DM_Item ampsPhase3WarnThresh;   /* PDU Amperage Warning Threshold       */
    DM_Item ampsPhase3AlarmThresh;  /* PDU Amperage alarm threshold         */

    DM_Item ampsPhase2;             /* PDU Amperage value                   */
    DM_Item ampsPhase2Alarm;        /* PDU Amperage alarm value             */
    DM_Item ampsPhase2WarnThresh;   /* PDU Amperage Warning Threshold       */
    DM_Item ampsPhase2AlarmThresh;  /* PDU Amperage alarm threshold         */

    DM_Item ampsPhase1;             /* PDU Amperage value                   */
    DM_Item ampsPhase1Alarm;        /* PDU Amperage alarm value             */
    DM_Item ampsPhase1WarnThresh;   /* PDU Amperage Warning Threshold       */
    DM_Item ampsPhase1AlarmThresh;  /* PDU Amperage alarm threshold         */

    DM_Item outOfPhase;             /* PDU Out of Phase value               */
    DM_Item outOfPhaseAlarm;        /* PDU Out of Phase alarm value         */
    DM_Item outOfPhaseWarnThresh;   /* PDU Out of Phase Warning Threshold   */
    DM_Item outOfPhaseAlarmThresh;  /* PDU Out of Phase alarm threshold     */

    DM_Item voltage;                /* PDU Voltage value                    */
    DM_Item voltageAlarm;           /* PDU Voltage alarm value              */
    DM_Item voltageWarnThresh;      /* PDU Voltage Warning Threshold        */
    DM_Item voltageAlarmThresh;     /* PDU Voltage alarm threshold          */

    DM_Item voltageMinAlarm;        /* PDU Minimum Voltage alarm value      */
    DM_Item voltageMinWarnThresh;   /* PDU Min Voltage Warning Threshold    */
    DM_Item voltageMinAlarmThresh;  /* PDU Min Voltage alarm threshold      */

    DM_Item microTemperature;       /* PDU Micro Temperature Value          */
    DM_Item microTempAlarm;         /* PDU Micro Temperature Alarm Value    */
    DM_Item microTempWarnThresh;    /* PDU Micro Temperature Warning Thresh */
    DM_Item microTempAlarmThresh;   /* PDU Micro Temperature Alarm Theshold */

    DM_Item transTemperature;       /* PDU Transformer Temperature Value    */
    DM_Item transTempAlarm;         /* PDU Trans Temperature Alarm Value    */
    DM_Item transTempWarnThresh;    /* PDU Trans Temperature Warning Thresh */
    DM_Item transTempAlarmThresh;   /* PDU Trans Temperature Alarm Theshold */

    DM_Item extGfCurrent;           /* External Ground Fault Current        */
    DM_Item extGndFaultAlarm;       /* External Ground Fault Alarm          */

    DM_Item tiburonPowerOnDm;       /* Vehicle Power On Data Manager Item   */
} pduMicroDmItems;

/****************************************************************************/

Void pduMicroInTask(pduMicroDmItems *dmItems, microIOControl *microIOCtrl);
Void pduMicroOutTask(pduMicroDmItems* dmItems, microIOControl *microIOCtrl);

MLocal Word processPDUMicroSRQ( Reg pduMicroDmItems* dmItems,
     microIOControl *microIOCtrl);

MLocal STATUS pduMicroDmItemInit( pduMicroDmItems* dmItems,
    sio32Chan* pduMicroDataChan );

/****************************************************************************/
/* Function    : initWattageThreshDm                                        */
/* Purpose     : Read Wattage Thresholds and update data manager item       */
/* Inputs      : Sio32 channel, Wattage alarm threshold dm item handles     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
initWattageThreshDm( sio32Chan *pduMicroDataChan, DM_Item wattageWarnDm,
    DM_Item wattageAlarmDm )
{
    Int16   warnThresh;             /* Wattage warning threshold            */
    Int16   alarmThresh;            /* Wattage alarm Threshold              */
    Flt32   scaledWarnThresh;
    Flt32   scaledAlarmThresh;

    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_WATTAGE_THRESH ) == 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, 3, &cmdStatus, &warnThresh, &alarmThresh);


    scaledWarnThresh = warnThresh / 100;
    scaledAlarmThresh = alarmThresh / 100;


                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */

    urgentWriteDmItem( wattageAlarmDm, &scaledAlarmThresh,
                       sizeof(scaledAlarmThresh));
    return (urgentWriteDmItem(wattageWarnDm, &scaledWarnThresh, sizeof(warnThresh)));
} /* initWattageThreshDm() */

/****************************************************************************/
/* Function    : writeWattageThresh                                         */
/* Purpose     : Get Wattage alarm thresholds from dm and send to micro     */
/* Inputs      : Sio32 channel,wattage threshold dm item handles            */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
writeWattageThresh( sio32Chan *pduMicroDataChan, DM_Item wattageWarnDm,
    DM_Item wattageAlarmDm  )
{
    Flt32   warnThresh;             /* Wattage warning threshold            */
    Flt32   alarmThresh;            /* Wattage alarm Threshold              */
    Int16   scaledWarnThresh;
    Int16   scaledAlarmThresh;

    Errno   status;                 /* Result of dm_read                    */
    Word    cmdStatus;              /* Command Result from microcontroller  */

                                    /* Read Wattage Thresholds from dm      */
    status = dm_read( wattageWarnDm, (char *) &warnThresh,
         sizeof(warnThresh), (DM_Time *) NULL);

    status = dm_read( wattageAlarmDm, (char *) &alarmThresh,
         sizeof(alarmThresh), (DM_Time *) NULL);

    scaledWarnThresh  = (Int16) warnThresh * 1000;
    scaledAlarmThresh = (Int16) alarmThresh * 1000;

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
    {                               /* Send command to microcontroller      */
        if ( sendMicroCommand( pduMicroDataChan, &cmdStatus, sizeof(cmdStatus),
            3,  PDU_MICRO_APP | SET_WATTAGE_THRESH,
            scaledWarnThresh, scaledAlarmThresh ) == ERROR ) return(ERROR);

                                    /* Check command result                  */
        return (wordFromBuf(&cmdStatus, 0) == CMD_OK ? OK : ERROR);
    } /* if */

    return(ERROR);
} /* writeWattageThresh() */

/****************************************************************************/
/* Function    : updateWattageDm                                            */
/* Purpose     : Reads micro Wattage sensor value & updates dmgr item       */
/* Inputs      : Sio32 chan & Wattage sensor data manager item handle       */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateWattageDm( sio32Chan *pduMicroDataChan, DM_Item microWattageDm )
{
    Int16   wattage;                /* Micro Wattage Sensor Value           */
    Flt32   kilowatts;

                                    /* Read Wattage sensor value            */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_WATTAGE, &wattage)
        == ERROR) return (ERROR);

    kilowatts = wattage / 1000.0;     /* Convert to Kilowats                  */

                                    /* Write Wattage to Data Manager        */
    return (writeDmItem(microWattageDm, &kilowatts, sizeof(kilowatts)));
} /* updateWattageDm() */

/****************************************************************************/
/* Function    : updateWattageAlarmDm                                       */
/* Purpose     : Reads Wattage alarm status & update dmgr item              */
/* Inputs      : Sio32 chan & Wattage alarm data manager item handle        */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
   LOCAL STATUS
updateWattageAlarmDm( sio32Chan *pduMicroDataChan, DM_Item wattageAlarmDm )
{
    Word alarmStatus;               /* Microcontroller Alarm Status Word    */
    microAlarm wattageAlarmStatus;  /* Micro Wattage alarm status           */
                                    /* Get Wattage Alarm Status from micro  */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_WATTAGE_ALARM_STATUS,
         &alarmStatus) == ERROR) return(ERROR);

    wattageAlarmStatus = (microAlarm) alarmStatus;

                                    /* Write wattage alarm to Dmgr          */
    return(writeDmItem(wattageAlarmDm, &wattageAlarmStatus,
        sizeof(wattageAlarmStatus)));
} /* updateWattageAlarmDm() */

/****************************************************************************/
/* Function    : initVoltageThreshDm                                        */
/* Purpose     : Read Voltage Thresholds and update data manager item       */
/* Inputs      : Sio32 channel, Voltage alarm threshold dm item handles     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
initVoltageThreshDm( sio32Chan *pduMicroDataChan, DM_Item voltageWarnDm,
    DM_Item voltageAlarmDm )
{
    Int16   warnThresh;             /* Voltage warning threshold            */
    Int16   alarmThresh;            /* Voltage alarm Threshold              */

    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_VOLTAGE_THRESH ) == 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, 3, &cmdStatus, &warnThresh, &alarmThresh);

                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */

    urgentWriteDmItem( voltageAlarmDm, &alarmThresh, sizeof(alarmThresh));
    return (urgentWriteDmItem(voltageWarnDm, &warnThresh, sizeof(warnThresh)));
} /* initVoltageThreshDm() */

/****************************************************************************/
/* Function    : setVoltageThresh                                           */
/* Purpose     : Sets Voltage alarm threshold values for 3x5 micro          */
/* Inputs      : Sio32 channel, voltage alarm threshold value               */
/* Outputs     : Return OK or ERROR                                         */
/****************************************************************************/
    MLocal STATUS
setVoltageThresh(sio32Chan *pduMicroDataChan, Int16 warnThresh,
    Int16 alarmThresh )
{
    Word    status;                 /* Command Result from microcontroller  */

                                   /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &status, sizeof(status),
        3,  PDU_MICRO_APP | SET_VOLTAGE_THRESH, warnThresh, alarmThresh )
        == ERROR ) return(ERROR);
                                    /* Check command result                  */
    return (wordFromBuf(&status, 0) == CMD_OK ? OK : ERROR);
} /* setVoltageThresh() */

/****************************************************************************/
/* Function    : writeVoltageThresh                                         */
/* Purpose     : Get Voltage alarm thresholds from dm and send to micro     */
/* Inputs      : Sio32 channel,voltage threshold dm item handles            */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
writeVoltageThresh( sio32Chan *pduMicroDataChan, DM_Item voltageWarnDm,
    DM_Item voltageAlarmDm  )
{
    Int16   warnThresh;             /* Voltage warning threshold            */
    Int16   alarmThresh;            /* Voltage alarm Threshold              */

    Errno   status;                 /* Result of dm_read                    */
    Word    cmdStatus;              /* Command Result from microcontroller  */

                                    /* Read Voltage Thresholds from dm      */
    status = dm_read( voltageWarnDm, (char *) &warnThresh,
         sizeof(warnThresh), (DM_Time *) NULL);

    status = dm_read( voltageAlarmDm, (char *) &alarmThresh,
         sizeof(alarmThresh), (DM_Time *) NULL);

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
                                    /* send command to microcontroller      */
        return (setVoltageThresh(pduMicroDataChan, warnThresh, alarmThresh));

    return(ERROR);
} /* writeVoltageThresh() */

/****************************************************************************/
/* Function    : updateVoltageDm                                            */
/* Purpose     : Reads micro Voltage sensor value & updates dmgr item       */
/* Inputs      : Sio32 chan & Voltage sensor data manager item handle       */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateVoltageDm( sio32Chan *pduMicroDataChan, DM_Item microVoltageDm )
{
    Int16   voltage;                /* Micro Voltage Sensor Value           */
                                    /* Read Voltage sensor value            */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_VOLTAGE, &voltage)
        == ERROR) return (ERROR);
                                    /* Write Voltage to Data Manager        */
    return (writeDmItem(microVoltageDm, &voltage, sizeof(voltage)));
} /* updateVoltageDm() */

/****************************************************************************/
/* Function    : updateVoltageAlarmDm                                       */
/* Purpose     : Reads Voltage alarm status & update dmgr item              */
/* Inputs      : Sio32 chan & Voltage alarm data manager item handle        */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
updateVoltageAlarmDm( sio32Chan *pduMicroDataChan, DM_Item voltageAlarmDm )
{
    Word alarmStatus;               /* Microcontroller Alarm Status Word    */
    microAlarm voltageAlarmStatus;  /* Micro Voltage alarm status           */
                                    /* Get Voltage Alarm Status from micro  */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_VOLTAGE_ALARM_STATUS,
         &alarmStatus) == ERROR) return(ERROR);

    voltageAlarmStatus = (microAlarm) alarmStatus;

                                    /* Write voltage alarm to Dmgr          */
    return(writeDmItem(voltageAlarmDm, &voltageAlarmStatus,
        sizeof(voltageAlarmStatus)));
} /* updateVoltageAlarmDm() */

/****************************************************************************/
/* Function    : initVoltageMinThreshDm                                     */
/* Purpose     : Read Voltage Thresholds and update data manager item       */
/* Inputs      : Sio32 channel, Voltage alarm threshold dm item handles     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
initVoltageMinThreshDm( sio32Chan *pduMicroDataChan, DM_Item voltageWarnDm,
    DM_Item voltageAlarmDm )
{
    Int16   warnThresh;             /* Voltage warning threshold           */
    Int16   alarmThresh;            /* Voltage alarm Threshold             */

    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_VOLTAGE_MIN_THRESH ) == 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, 3, &cmdStatus, &warnThresh, &alarmThresh);

                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */

    urgentWriteDmItem( voltageAlarmDm, &alarmThresh, sizeof(alarmThresh));
    return (urgentWriteDmItem(voltageWarnDm, &warnThresh, sizeof(warnThresh)));
} /* initVoltageMinThreshDm() */

/****************************************************************************/
/* Function    : writeVoltageMinThresh                                      */
/* Purpose     : Get Voltage alarm thresholds from dm and send to micro     */
/* Inputs      : Sio32 channel,voltage threshold dm item handles            */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
writeVoltageMinThresh( sio32Chan *pduMicroDataChan, DM_Item voltageWarnDm,
    DM_Item voltageAlarmDm  )
{
    Int16   warnThresh;             /* Voltage Minimum warning threshold    */
    Int16   alarmThresh;            /* Voltage Minimum alarm Threshold      */

    Errno   status;                 /* Result of dm_read                    */
    Word    cmdStatus;              /* Command Result from microcontroller  */

                                    /* Read Voltage Thresholds from dm      */
    status = dm_read( voltageWarnDm, (char *) &warnThresh,
         sizeof(warnThresh), (DM_Time *) NULL);

    status = dm_read( voltageAlarmDm, (char *) &alarmThresh,
         sizeof(alarmThresh), (DM_Time *) NULL);

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
    {                               /* Send command to microcontroller      */
        if ( sendMicroCommand( pduMicroDataChan, &cmdStatus, sizeof(cmdStatus),
            3,  PDU_MICRO_APP | SET_VOLTAGE_MIN_THRESH, warnThresh, alarmThresh )
             == ERROR ) return(ERROR);

                                    /* Check command result                  */
        return (wordFromBuf(&cmdStatus, 0) == CMD_OK ? OK : ERROR);
    } /* if */

    return(ERROR);
} /* writeVoltageMinThresh() */

/****************************************************************************/
/* Function    : updateVoltageMinAlarmDm                                    */
/* Purpose     : Reads Voltage alarm status & update dmgr item              */
/* Inputs      : Sio32 chan & Voltage Min alarm data manager item handle    */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
updateVoltageMinAlarmDm( sio32Chan *pduMicroDataChan, DM_Item voltageAlarmDm )
{
    Word alarmStatus;               /* Microcontroller Alarm Status Word    */
    microAlarm voltageAlarmStatus;  /* Micro Voltage alarm status           */
                                    /* Get Voltage Alarm Status from micro  */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP |
                        GET_VOLTAGE_MIN_ALARM_STATUS,
                        &alarmStatus) == ERROR) return(ERROR);

    voltageAlarmStatus = (microAlarm) alarmStatus;

                                    /* Write voltage alarm to Dmgr          */
    return(writeDmItem(voltageAlarmDm, &voltageAlarmStatus,
        sizeof(voltageAlarmStatus)));
} /* updateVoltageMinAlarmDm() */

/****************************************************************************/
/* Function    : initMicroTempThreshDm                                      */
/* Purpose     : Read MicroTemp Thresholds and update data manager item     */
/* Inputs      : Sio32 channel, microTemp alarm threshold dm item handles   */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
initMicroTempThreshDm( sio32Chan *pduMicroDataChan, DM_Item microTempWarnDm,
    DM_Item microTempAlarmDm )
{
    Int16   warnThresh;             /* Micro Temperature warning threshold  */
    Int16   alarmThresh;            /* Micro Temperature alarm Threshold    */

    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_MICRO_TEMP_THRESH ) == 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, 3, &cmdStatus, &warnThresh, &alarmThresh);

                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */

    urgentWriteDmItem( microTempAlarmDm, &alarmThresh, sizeof(alarmThresh));
    return (urgentWriteDmItem(microTempWarnDm, &warnThresh,
         sizeof(warnThresh)));
} /* initMicroTempThreshDm() */

/****************************************************************************/
/* Function    : writeMicroTempThresh                                       */
/* Purpose     : Get microTemp alarm thresholds from dm and send to micro   */
/* Inputs      : Sio32 channel, microTemp threshold dm item handles         */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
writeMicroTempThresh( sio32Chan *pduMicroDataChan, DM_Item microTempWarnDm,
    DM_Item microTempAlarmDm  )
{
    Errno   status;                 /* Result of dm_read                    */
    Word    cmdStatus;              /* Command Result from microcontroller  */

    Int16   warnThresh;             /* MicroTemp warning threshold          */
    Int16   alarmThresh;            /* MicroTemp alarm Threshold            */

                                    /* Read MicroTemp Thresholds from dm    */
    status = dm_read( microTempWarnDm, (char *) &warnThresh,
         sizeof(warnThresh), (DM_Time *) NULL);

    status = dm_read( microTempAlarmDm, (char *) &alarmThresh,
         sizeof(alarmThresh), (DM_Time *) NULL);

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
    {                               /* Send command to microcontroller      */
        if ( sendMicroCommand( pduMicroDataChan, &cmdStatus, sizeof(cmdStatus),
            3,  PDU_MICRO_APP | SET_MICRO_TEMP_THRESH, warnThresh, alarmThresh )
             == ERROR ) return(ERROR);

                                    /* Check command result                 */
        return (wordFromBuf(&cmdStatus, 0) == CMD_OK ? OK : ERROR);
    } /* if */

    return(ERROR);
} /* writeMicroTempThresh() */

/****************************************************************************/
/* Function    : updateMicroTempDm                                          */
/* Purpose     : Reads  microTemp sensor value & updates dmgr item          */
/* Inputs      : Sio32 chan & microTemp sensor data manager item handle     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateMicroTempDm( sio32Chan *pduMicroDataChan, DM_Item microTempDm )
{
    Int16   microTemp;              /* Micro MicroTemp Sensor Value         */
                                    /* Read microTemp sensor value          */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_MICRO_TEMPERATURE,
        &microTemp) == ERROR)
        return (ERROR);
                                    /* Write microTemp to Data Manager      */
    return (writeDmItem(microTempDm, &microTemp, sizeof(microTemp)));
} /* updateMicroTempDm() */

/****************************************************************************/
/* Function    : updateMicroTempAlarmDm                                     */
/* Purpose     : Reads microTemp alarm status & updates dmgr item           */
/* Inputs      : Sio32 chan & microTemp alarm data manager item handle      */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateMicroTempAlarmDm( sio32Chan *pduMicroDataChan, DM_Item microTempAlarmDm )
{
    Word alarmStatus;               /* Microcontroller Alarm Status Word    */
    microAlarm microTempAlarmStatus;/* Micro microTemp alarm status         */
                                    /* Get TempAlarm Status from micro      */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_MICRO_TEMP_ALARM_STATUS,
         &alarmStatus) == ERROR) return(ERROR);

    microTempAlarmStatus = (microAlarm) alarmStatus;

                                    /* Write microTemp alarm to Dmgr        */
    return(writeDmItem(microTempAlarmDm, &microTempAlarmStatus,
        sizeof(microTempAlarmStatus)));
} /* updateMicroTempAlarmDm() */

/****************************************************************************/
/* Function    : initTransTempThreshDm                                      */
/* Purpose     : Read TransTemp Thresholds and update data manager item     */
/* Inputs      : Sio32 channel, transTemp alarm threshold dm item handles   */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
initTransTempThreshDm( sio32Chan *pduMicroDataChan, DM_Item transTempWarnDm,
    DM_Item transTempAlarmDm )
{
    Int16   warnThresh;             /* Temperature warning threshold        */
    Int16   alarmThresh;            /* Temperature alarm Threshold          */

    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_TRANS_TEMP_THRESH ) == 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, 3, &cmdStatus, &warnThresh, &alarmThresh);

                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */

    urgentWriteDmItem( transTempAlarmDm, &alarmThresh, sizeof(alarmThresh));
    return (urgentWriteDmItem(transTempWarnDm, &warnThresh,
         sizeof(warnThresh)));
} /* initTransTempThreshDm() */

/****************************************************************************/
/* Function    : writeTransTempThresh                                       */
/* Purpose     : Get transTemp alarm thresholds from dm and send to micro   */
/* Inputs      : Sio32 channel, transTemp threshold dm item handles         */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
writeTransTempThresh( sio32Chan *pduMicroDataChan, DM_Item transTempWarnDm,
    DM_Item transTempAlarmDm  )
{
    Errno   status;                 /* Result of dm_read                    */
    Word    cmdStatus;              /* Command Result from microcontroller  */

    Int16   warnThresh;             /* TransTemp warning threshold        */
    Int16   alarmThresh;            /* TransTemp alarm Threshold          */

                                    /* Read TransTemp Thresholds from dm  */
    status = dm_read( transTempWarnDm, (char *) &warnThresh,
         sizeof(warnThresh), (DM_Time *) NULL);

    status = dm_read( transTempAlarmDm, (char *) &alarmThresh,
         sizeof(alarmThresh), (DM_Time *) NULL);

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
    {                               /* Send command to microcontroller      */
        if ( sendMicroCommand( pduMicroDataChan, &cmdStatus, sizeof(cmdStatus),
            3,  PDU_MICRO_APP | SET_TRANS_TEMP_THRESH, warnThresh, alarmThresh )
             == ERROR ) return(ERROR);

                                    /* Check command result                 */
        return (wordFromBuf(&cmdStatus, 0) == CMD_OK ? OK : ERROR);
    } /* if */

    return(ERROR);
} /* writeTransTempThresh() */

/****************************************************************************/
/* Function    : updateTransTempDm                                          */
/* Purpose     : Reads transTemp sensor value & updates dmgr item           */
/* Inputs      : Sio32 chan & transTemp sensor data manager item handle     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateTransTempDm( sio32Chan *pduMicroDataChan, DM_Item transTempDm )
{
    Int16   transTemp;                /* Trans TransTemp Sensor Value       */
                                      /* Read transTemp sensor value        */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_TRANS_TEMPERATURE,
        &transTemp) == ERROR)
        return (ERROR);
                                    /* Write transTemp to Data Manager      */
    return (writeDmItem(transTempDm, &transTemp, sizeof(transTemp)));
} /* updateTransTempDm() */

/****************************************************************************/
/* Function    : updateTransTempAlarmDm                                     */
/* Purpose     : Reads transTemp alarm status & updates dmgr item           */
/* Inputs      : Sio32 chan & transTemp alarm data manager item handle      */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateTransTempAlarmDm( sio32Chan *pduMicroDataChan, DM_Item transTempAlarmDm )
{
    Word alarmStatus;               /* microcontroller Alarm Status Word    */
    microAlarm transTempAlarmStatus;/*  transTemp alarm status              */
                                    /* Get TempAlarm Status from micro      */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_TRANS_TEMP_ALARM_STATUS,
         &alarmStatus) == ERROR) return(ERROR);

    transTempAlarmStatus = (microAlarm) alarmStatus;

                                    /* Write transTemp alarm to Dmgr      */
    return(writeDmItem(transTempAlarmDm, &transTempAlarmStatus,
        sizeof(transTempAlarmStatus)));
} /* updateTransTempAlarmDm() */

/****************************************************************************/
/* Function    : initOutOfPhaseThreshDm                                     */
/* Purpose     : Read OutOfPhase Thresholds and update data manager item    */
/* Inputs      : Sio32 channel, OutOfPhase alarm threshold dm item handles  */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
initOutOfPhaseThreshDm( sio32Chan *pduMicroDataChan, DM_Item outOfPhaseWarnDm,
    DM_Item outOfPhaseAlarmDm )
{
    Int16   warnThresh;             /* out Of Phase warning threshold       */
    Int16   alarmThresh;            /* Out Of Phase alarm Threshold         */

    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_OUT_OF_PHASE_THRESH ) == 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, 3, &cmdStatus, &warnThresh, &alarmThresh);

                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */
    urgentWriteDmItem( outOfPhaseAlarmDm, &alarmThresh, sizeof(alarmThresh));
    return (urgentWriteDmItem(outOfPhaseWarnDm, &warnThresh,
         sizeof(warnThresh)));
} /* initOutOfPhaseThreshDm() */

/****************************************************************************/
/* Function    : writeOutOfPhaseThresh                                      */
/* Purpose     : Get Out Of Phase alarm thresholds from dm and send to micro*/
/* Inputs      : Sio32 channel, Out Of Phase threshold dm item handles      */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
writeOutOfPhaseThresh( sio32Chan *pduMicroDataChan, DM_Item outOfPhaseWarnDm,
    DM_Item outOfPhaseAlarmDm  )
{
    Errno   status;                 /* Result of dm_read                    */
    Word    cmdStatus;              /* Command Result from microcontroller  */

    Int16   warnThresh;             /* TransTemp warning threshold        */
    Int16   alarmThresh;            /* TransTemp alarm Threshold          */

                                    /* Read TransTemp Thresholds from dm  */
    status = dm_read( outOfPhaseWarnDm, (char *) &warnThresh,
         sizeof(warnThresh), (DM_Time *) NULL);

    status = dm_read( outOfPhaseAlarmDm, (char *) &alarmThresh,
         sizeof(alarmThresh), (DM_Time *) NULL);

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
    {                               /* Send command to microcontroller      */
        if ( sendMicroCommand( pduMicroDataChan, &cmdStatus, sizeof(cmdStatus),
            3,  PDU_MICRO_APP | SET_OUT_OF_PHASE_THRESH,
                  warnThresh, alarmThresh ) == ERROR ) return(ERROR);

                                    /* Check command result                 */
        return (wordFromBuf(&cmdStatus, 0) == CMD_OK ? OK : ERROR);
    } /* if */

    return(ERROR);
} /* writeOutOfPhaseThresh() */

/****************************************************************************/
/* Function    : updateOutOfPhaseDm                                         */
/* Purpose     : Reads Out Of Phase sensor value & updates dmgr item        */
/* Inputs      : Sio32 chan & out of phase sensor data manager item handle  */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateOutOfPhaseDm( sio32Chan *pduMicroDataChan, DM_Item outOfPhaseDm )
{
    Int16   outOfPhase;               /* out of phase Sensor Value       */
                                      /* Read Out OF Phase sensor value  */
    if (microCommand(pduMicroDataChan, PDU_MICRO_APP | GET_OUT_OF_PHASE_VALUE,
        &outOfPhase) == ERROR)
        return (ERROR);
                                    /* Write transTemp to Data Manager      */
    return (writeDmItem(outOfPhaseDm, &outOfPhase, sizeof(outOfPhase)));
} /* updateOutOfPhaseDm() */

/****************************************************************************/
/* Function    : updateOutOfPhaseAlarmDm                                    */
/* Purpose     : Reads Out Of Phase alarm status & updates dmgr item        */
/* Inputs      : Sio32 chan & out of phase alarm data manager item handle   */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateOutOfPhaseAlarmDm(sio32Chan *pduMicroDataChan, DM_Item outOfPhaseAlarmDm)
{
    Word alarmStatus;               /* microcontroller Alarm Status Word    */
    microAlarm outOfPhaseAlarmStatus;/*  out of Phase alarm status          */
                                    /* Get out of phase Alarm Status o      */
    if (microCommand(pduMicroDataChan,
                       PDU_MICRO_APP | GET_OUT_OF_PHASE_ALARM_STATUS,
                                        &alarmStatus) == ERROR) return(ERROR);

    outOfPhaseAlarmStatus = (microAlarm) alarmStatus;

                                    /* Write outOfPhase  alarm to Dmgr      */
    return(writeDmItem(outOfPhaseAlarmDm, &outOfPhaseAlarmStatus,
        sizeof(outOfPhaseAlarmStatus)));
} /* updateOutOfPhaseAlarmDm() */

/****************************************************************************/
/* Function    : updateAmperagesDm                                           */
/* Purpose     : Read Amperages and update data manager item                */
/* Inputs      : Sio32 channel, amperage item handles                       */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateAmperagesDm( sio32Chan *pduMicroDataChan, DM_Item ampsPhase3Dm,
    DM_Item ampsPhase2Dm, DM_Item ampsPhase1Dm)
{
    Int16   ampsPhase3, ampsPhase2, ampsPhase1; /* Amperage values          */

    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[2];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 2,
         1, PDU_MICRO_APP | GET_AMPS_PHASE3 ) == 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 amperage value  */
    wordsFromBuf(reply, 2, &cmdStatus, &ampsPhase3);

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 2,
         1, PDU_MICRO_APP | GET_AMPS_PHASE2 ) == 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 amperage value  */
    wordsFromBuf(reply, 2, &cmdStatus, &ampsPhase2);

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 2,
         1, PDU_MICRO_APP | GET_AMPS_PHASE1 ) == 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 amperage value  */
    wordsFromBuf(reply, 2, &cmdStatus, &ampsPhase1);

    writeDmItem( ampsPhase3Dm, &ampsPhase3, sizeof(ampsPhase3) );
    writeDmItem( ampsPhase2Dm, &ampsPhase2, sizeof(ampsPhase2) );
    writeDmItem( ampsPhase1Dm, &ampsPhase1, sizeof(ampsPhase1) );

    return(OK);
} /* updateAmperagesDm() */

/****************************************************************************/
/* Function    : initAmpsThreshDm                                            */
/* Purpose     : Read Amperage Alarm Thresholds and update data manager items*/
/* Inputs      : Sio32 channel, amperage alarm threshold dm handles         */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
initAmpsThreshDm( sio32Chan *pduMicroDataChan, DM_Item ampsPhase3WarnThreshDm,
    DM_Item ampsPhase3AlarmThreshDm, DM_Item ampsPhase2WarnThreshDm,
    DM_Item ampsPhase2AlarmThreshDm, DM_Item ampsPhase1WarnThreshDm,
    DM_Item ampsPhase1AlarmThreshDm)
{
    Int16   ampsPhase3AlarmThresh, ampsPhase2AlarmThresh, ampsPhase1AlarmThresh;
    Int16   ampsPhase3WarnThresh, ampsPhase2WarnThresh, ampsPhase1WarnThresh;

    Int16   cmdStatus;              /* Command Status                       */
    Word    reply[3];               /* Command Result from microcontroller  */

                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_AMPS_PHASE3_THRESH ) == 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 alarm thresholds*/
    wordsFromBuf(reply, 3, &cmdStatus, &ampsPhase3WarnThresh,
                                             &ampsPhase3AlarmThresh);

                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */
    if (urgentWriteDmItem( ampsPhase3WarnThreshDm, &ampsPhase3WarnThresh,
        sizeof(ampsPhase3WarnThresh))==ERROR)
        return(ERROR);

    if (urgentWriteDmItem( ampsPhase3AlarmThreshDm, &ampsPhase3AlarmThresh,
        sizeof(ampsPhase3AlarmThresh))==ERROR)
        return(ERROR);

                                     /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_AMPS_PHASE2_THRESH ) == 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 alarm thresholds*/
    wordsFromBuf(reply, 3, &cmdStatus, &ampsPhase2WarnThresh,
                                             &ampsPhase2AlarmThresh);

                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */
    if (urgentWriteDmItem( ampsPhase2WarnThreshDm, &ampsPhase2WarnThresh,
        sizeof(ampsPhase2WarnThresh))==ERROR)
        return(ERROR);

    if (urgentWriteDmItem( ampsPhase2AlarmThreshDm, &ampsPhase2AlarmThresh,
        sizeof(ampsPhase2AlarmThresh))==ERROR)
        return(ERROR);;

                                     /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 3,
         1, PDU_MICRO_APP | GET_AMPS_PHASE1_THRESH ) == 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 alarm thresholds*/
    wordsFromBuf(reply, 3, &cmdStatus, &ampsPhase1WarnThresh,
                                             &ampsPhase1AlarmThresh);

                                    /* We MUST use urgent open here as      */
                                    /* another task is normal provider      */
    if (urgentWriteDmItem( ampsPhase1WarnThreshDm, &ampsPhase1WarnThresh,
        sizeof(ampsPhase1WarnThresh))==ERROR)
        return(ERROR);

    if (urgentWriteDmItem( ampsPhase1AlarmThreshDm, &ampsPhase1AlarmThresh,
        sizeof(ampsPhase1AlarmThresh))== ERROR)
        return(ERROR);

    return(OK);

} /* initAmpsAlarmThreshDm() */

/****************************************************************************/
/* Function    : writeAmperageThresh                                    */
/* Purpose     : Get coolant level alarm thresholds from dm & send to micro */
/* Inputs      : Sio32 channel, alarm level threshold dm item handles       */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
writeAmperageThresh( sio32Chan *pduMicroDataChan,
          DM_Item ampsPhase3WarnThreshDm, DM_Item ampsPhase3AlarmThreshDm,
          DM_Item ampsPhase2WarnThreshDm, DM_Item ampsPhase2AlarmThreshDm,
          DM_Item ampsPhase1WarnThreshDm, DM_Item ampsPhase1AlarmThreshDm)
{
    Errno   status;                 /* Result of dm_read                    */
    Word    cmdStatus;              /* Command Result from microcontroller  */

    Int16   ampsPhase3AlarmThresh, ampsPhase2AlarmThresh, ampsPhase1AlarmThresh;
    Int16   ampsPhase3WarnThresh, ampsPhase2WarnThresh, ampsPhase1WarnThresh;

                                    /* Read Amperage thresholds from dm   */
    status = dm_read( ampsPhase3AlarmThreshDm, (char *) &ampsPhase3AlarmThresh,
         sizeof(ampsPhase3AlarmThresh), (DM_Time *) NULL);

    status = dm_read( ampsPhase3WarnThreshDm, (char *) &ampsPhase3WarnThresh,
         sizeof(ampsPhase3WarnThresh), (DM_Time *) NULL);

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
    {                               /* Send command to microcontroller      */
        if ( sendMicroCommand( pduMicroDataChan, &cmdStatus, sizeof(cmdStatus),
            3,  PDU_MICRO_APP | SET_AMPS_PHASE3_THRESH,
             ampsPhase3WarnThresh, ampsPhase3AlarmThresh ) == ERROR )
        return(ERROR);

                                    /* Check command result                 */
        return (wordFromBuf(&cmdStatus, 0) == CMD_OK ? OK : ERROR);
    } /* if */


                                    /* Read Amperage thresholds from dm   */
    status = dm_read( ampsPhase2AlarmThreshDm, (char *) &ampsPhase2AlarmThresh,
         sizeof(ampsPhase2AlarmThresh), (DM_Time *) NULL);

    status = dm_read( ampsPhase2WarnThreshDm, (char *) &ampsPhase2WarnThresh,
         sizeof(ampsPhase2WarnThresh), (DM_Time *) NULL);

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
    {                               /* Send command to microcontroller      */
        if ( sendMicroCommand( pduMicroDataChan, &cmdStatus, sizeof(cmdStatus),
            3,  PDU_MICRO_APP | SET_AMPS_PHASE2_THRESH,
             ampsPhase2WarnThresh, ampsPhase2AlarmThresh ) == ERROR )
        return(ERROR);

                                    /* Check command result                 */
        return (wordFromBuf(&cmdStatus, 0) == CMD_OK ? OK : ERROR);
    } /* if */


                                    /* Read Amperage thresholds from dm   */
    status = dm_read( ampsPhase1AlarmThreshDm, (char *) &ampsPhase1AlarmThresh,
         sizeof(ampsPhase1AlarmThresh), (DM_Time *) NULL);

    status = dm_read( ampsPhase1WarnThreshDm, (char *) &ampsPhase1WarnThresh,
         sizeof(ampsPhase1WarnThresh), (DM_Time *) NULL);

                                    /* Check for successful dm_read         */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
    {                               /* Send command to microcontroller      */
        if ( sendMicroCommand( pduMicroDataChan, &cmdStatus, sizeof(cmdStatus),
            3,  PDU_MICRO_APP | SET_AMPS_PHASE1_THRESH,
             ampsPhase1WarnThresh, ampsPhase1AlarmThresh ) == ERROR )
        return(ERROR);

                                    /* Check command result                 */
        return (wordFromBuf(&cmdStatus, 0) == CMD_OK ? OK : ERROR);
    } /* if */


    return(ERROR);
} /* writeAmperageThresh() */

/****************************************************************************/
/* Function    : updateAmperageAlarmsDm                                     */
/* Purpose     : Read Amperage Alarm status & updates DM                    */
/* Inputs      : Sio32 chan &  amperage alarm status dm item handles        */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateAmperageAlarmsDm( sio32Chan *pduMicroDataChan, DM_Item ampsPhase3AlarmDm,
                        DM_Item ampsPhase2AlarmDm, DM_Item ampsPhase1AlarmDm )
{
    microAlarm ampsPhase3Alarm;       /* Amperage phase3 alarm status       */
    microAlarm ampsPhase2Alarm;       /* Amperage phase2 alarm status       */
    microAlarm ampsPhase1Alarm;       /* Amperage phase1 alarm status       */

    Word  ampsPhase3AlarmStatus;      /* Amps Phase3 Alarm Status Word      */
    Word  ampsPhase2AlarmStatus;      /* Amps Phase2 Alarm Status Word      */
    Word  ampsPhase1AlarmStatus;      /* Amps Phase1 Alarm Status Word      */

    Int16 cmdStatus;                /* Command Status                       */
    Word  reply[2];                 /* Command Result from microcontroller  */


                                    /* Read Amperage  alarm status          */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 2,
         1, PDU_MICRO_APP | GET_AMPS_PHASE3_ALARM_STATUS ) == 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, &ampsPhase3AlarmStatus);

    ampsPhase3Alarm  = (microAlarm) ampsPhase3AlarmStatus;


                                    /* Read Amperage  alarm status          */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 2,
         1, PDU_MICRO_APP | GET_AMPS_PHASE2_ALARM_STATUS ) == 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, &ampsPhase2AlarmStatus);

    ampsPhase2Alarm  = (microAlarm) ampsPhase2AlarmStatus;


                                    /* Read Amperage  alarm status          */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 2,
         1, PDU_MICRO_APP | GET_AMPS_PHASE1_ALARM_STATUS ) == 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, &ampsPhase1AlarmStatus);

    ampsPhase1Alarm  = (microAlarm) ampsPhase1AlarmStatus;

                                    /* Write Amps alarm status to dm        */
    writeDmItem(ampsPhase3AlarmDm, &ampsPhase3Alarm, sizeof(ampsPhase3Alarm));
    writeDmItem(ampsPhase2AlarmDm, &ampsPhase2Alarm, sizeof(ampsPhase2Alarm));

    return ( writeDmItem(ampsPhase1AlarmDm, &ampsPhase1Alarm,
                                                  sizeof(ampsPhase1Alarm)));

} /* updateAmperageAlarmsDm() */

/****************************************************************************/
/* Function    : pduGetGndFltAlarm                                          */
/* Purpose     : Returns Groud Fault alarm status from PDU micro            */
/* Inputs      : Sio32 channel, pointer to Ground Fault Alarm status        */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    MLocal STATUS
pduGetGndFltAlarm( sio32Chan *pduMicroDataChan, gfStatus *extGfAlarm)
{
    Int16 cmdStatus;                /* Command Status                       */
    Word  reply[2];                 /* Command Result from microcontroller  */
    Word  extGfStatus;

                                    /* Get Ground Fault Alarm Status        */
                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 2,
         1, MICRO_APP | GET_GNDFLT_STATUS ) == 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 GF Status       */
    wordsFromBuf(reply, 2, &cmdStatus, &extGfStatus);

                                 /* Map to vxWorks ENUM definition         */
    *extGfAlarm   = (gfStatus) extGfStatus;

    return(OK);
} /* pduGetGndFltAlarm() */

/****************************************************************************/
/* Function    : updateGndFltAlarmDm                                        */
/* Purpose     : Reads Ground Fault alarm status & updates dmgr item        */
/* Inputs      : Sio32 chan & Ground Fault alarm data manager item handle   */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateGndFltAlarmDm( sio32Chan *sio32DataChan, DM_Item extGfAlarmDm )
{
    gfStatus extGfAlarm;                /* External Ground Fault alarm      */

    if (pduGetGndFltAlarm(sio32DataChan, &extGfAlarm) != OK)
        return(ERROR);
                                        /* Write Ground Fault alarm to Dmgr */
    writeDmItem(extGfAlarmDm,   &extGfAlarm,   sizeof(extGfAlarm));

    return (OK);
} /* updateGndFltAlarmDm() */

/****************************************************************************/
/* Function    : pduGetGndFltCurrent                                        */
/* Purpose     : Returns Groud Fault current measurements from micro        */
/* Inputs      : Sio32 channel, pointer to local and ext GF currents        */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    MLocal STATUS
pduGetGndFltCurrent( sio32Chan *pduMicroDataChan, Int16 *extGfCurrent)
{
    Int16 cmdStatus;                /* Command Status                       */
    Word  reply[2];                 /* Command Result from microcontroller  */
    Word  extGf;

                                    /* Get Ground Fault Currents from micro */
                                    /* Send command to microcontroller      */
    if ( sendMicroCommand( pduMicroDataChan, &reply, sizeof(Word) * 2,
         1, MICRO_APP | GET_GNDFLT_VALUE ) == 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 GF currents     */
    wordsFromBuf(reply, 2, &cmdStatus, &extGf);
    *extGfCurrent = (Int16) extGf;

    return(OK);
} /* pduGetGndFltCurrent() */

/****************************************************************************/
/* Function    : updateGndFltCurrentDm                                      */
/* Purpose     : Reads Ground Fault currents & updates dmgr items           */
/* Inputs      : Sio32 chan & Ground Fault current item handles             */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
updateGndFltCurrentDm( sio32Chan *sio32DataChan, DM_Item extGfCurrentDm )
{
    Int16 extGfCurrent;                 /* External Ground Fault Current    */

    if (pduGetGndFltCurrent(sio32DataChan, &extGfCurrent)
        != OK) return(ERROR);
                                        /* Write Ground Fault current to DM */
    writeDmItem(extGfCurrentDm,   &extGfCurrent,   sizeof(extGfCurrent));

    return (OK);
} /* updateGndFltCurrentDm() */

/****************************************************************************/
/* Function    : createPDUMicroAppDmItems                                   */
/* Purpose     : Create Data Mgr Items specific to PDU Micro Application    */
/* Inputs      : Pointer to structure of DM item handles, PDU Micro DM      */
/*               prefix, PDU Micro Microcontroller Name                     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    LOCAL STATUS
createPDUMicroAppDmItems( pduMicroDmItems *dmItems,
    const char* pduMicroAppPrefix, const char* pduMicroName )
{
    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      */
    } pduMicroDmInit[] =

      { { &dmItems->microDm.resetEvent,      "Reset Event",
                MICRO_RESET_EVENT_DM,           DM_EMPTY, 1 },

        { &dmItems->microDm.resetCmd,        "Reset Command",
                MICRO_RESET_CMD_DM,             DM_EMPTY, 1 },

        { &dmItems->microDm.idString,        "Identification",
                MICRO_IDENT_DM,                 DM_CHAR, MICRO_ID_LEN  },

        { &dmItems->microDm.serialNo,        "Micro Serial Number",
                MICRO_SERIAL_NO_DM,             DM_CHAR, MICRO_SERNO_LEN },

        { &dmItems->microDm.softwareRev,     "Software Revision",
                SOFTWARE_REV_DM,                DM_CHAR, SOFTWARE_REV_LEN },

        { &dmItems->microDm.ramTest,         "Micro RAM Test",
                RAM_TEST_STATUS_DM,             DM_MBOOL, 1 },

        { &dmItems->wattage,                 "Wattage Value",
                WATTAGE_DM,                     DM_FLT32, 1 },

        { &dmItems->wattageAlarm,            "Wattage Alarm",
                WATTAGE_ALARM_DM,               DM_ENUM, 1 },

        { &dmItems->wattageWarnThresh,       "Wattage Warn Threshold",
                WATTAGE_WARN_THRESH_DM,         DM_FLT32, 1 },

        { &dmItems->wattageAlarmThresh,      "Wattage Alarm Threshold",
                WATTAGE_ALARM_THRESH_DM,        DM_FLT32, 1 },

        { &dmItems->voltage,                 "Voltage Value",
                VOLTAGE_DM,                     DM_INT16, 1 },

        { &dmItems->voltageAlarm,            "Voltage Alarm",
                VOLTAGE_ALARM_DM,               DM_ENUM, 1 },

        { &dmItems->voltageWarnThresh,       "Voltage Warn Threshold",
                VOLTAGE_WARN_THRESH_DM,         DM_INT16, 1 },

        { &dmItems->voltageAlarmThresh,      "Voltage Alarm Threshold",
                VOLTAGE_ALARM_THRESH_DM,        DM_INT16, 1 },

        { &dmItems->voltageMinAlarm,         "Voltage Alarm",
                VOLTAGE_MIN_ALARM_DM,           DM_ENUM, 1 },

        { &dmItems->voltageMinWarnThresh,    "Voltage Warn Threshold",
                VOLTAGE_MIN_WARN_THRESH_DM,     DM_INT16, 1 },

        { &dmItems->voltageMinAlarmThresh,   "Voltage Alarm Threshold",
                VOLTAGE_MIN_ALARM_THRESH_DM,    DM_INT16, 1 },

        { &dmItems->ampsPhase3,                 "AmpsPhase3 Value",
                AMPS_PHASE3_DM,                    DM_INT16, 1 },

        { &dmItems->ampsPhase3Alarm,            "AmpsPhase3 Alarm",
                AMPS_PHASE3_ALARM_DM,              DM_ENUM, 1 },

        { &dmItems->ampsPhase3WarnThresh,       "AmpsPhase3 Warn Threshold",
                AMPS_PHASE3_WARN_THRESH_DM,        DM_INT16, 1 },

        { &dmItems->ampsPhase3AlarmThresh,      "AmpsPhase3 Alarm Threshold",
                AMPS_PHASE3_ALARM_THRESH_DM,       DM_INT16, 1 },

        { &dmItems->ampsPhase2,                 "AmpsPhase2 Value",
                AMPS_PHASE2_DM,                    DM_INT16, 1 },

        { &dmItems->ampsPhase2Alarm,            "AmpsPhase2 Alarm",
                AMPS_PHASE2_ALARM_DM,              DM_ENUM, 1 },

        { &dmItems->ampsPhase2WarnThresh,       "AmpsPhase2 Warn Threshold",
                AMPS_PHASE2_WARN_THRESH_DM,        DM_INT16, 1 },

        { &dmItems->ampsPhase2AlarmThresh,      "AmpsPhase2 Alarm Threshold",
                AMPS_PHASE2_ALARM_THRESH_DM,       DM_INT16, 1 },

        { &dmItems->ampsPhase1,                 "AmpsPhase1 Value",
                AMPS_PHASE1_DM,                    DM_INT16, 1 },

        { &dmItems->ampsPhase1Alarm,            "AmpsPhase1 Alarm",
                AMPS_PHASE1_ALARM_DM,              DM_ENUM, 1 },

        { &dmItems->ampsPhase1WarnThresh,       "AmpsPhase1 Warn Threshold",
                AMPS_PHASE1_WARN_THRESH_DM,        DM_INT16, 1 },

        { &dmItems->ampsPhase1AlarmThresh,      "AmpsPhase1 Alarm Threshold",
                AMPS_PHASE1_ALARM_THRESH_DM,       DM_INT16, 1 },

        { &dmItems->outOfPhase,                 "Out Of Phase Value",
                OUT_OF_PHASE_DM,                    DM_INT16, 1 },

        { &dmItems->outOfPhaseAlarm,            "Out Of Phase Alarm",
                OUT_OF_PHASE_ALARM_DM,              DM_ENUM, 1 },

        { &dmItems->outOfPhaseWarnThresh,       "Out Of Phase Warn Threshold",
                OUT_OF_PHASE_WARN_THRESH_DM,        DM_INT16, 1 },

        { &dmItems->outOfPhaseAlarmThresh,      "Out Of Phase Alarm Threshold",
                OUT_OF_PHASE_ALARM_THRESH_DM,       DM_INT16, 1 },

        { &dmItems->microTemperature,        "Micro Temperature",
                MICRO_TEMP_DM,                  DM_INT16, 1 },

        { &dmItems->microTempAlarm,          "Micro Temperature Alarm",
                TEMP_ALARM_DM,                  DM_ENUM,  1 },

        { &dmItems->microTempWarnThresh,     "Micro Temp Warn Threshold",
                TEMP_WARN_THRESH_DM,            DM_INT16, 1 },

        { &dmItems->microTempAlarmThresh,    "Micro Temp Alarm Threshold",
                TEMP_ALARM_THRESH_DM,           DM_INT16, 1 },

        { &dmItems->transTemperature,        "Transformer Temperature",
                TRANS_TEMP_DM,                  DM_INT16, 1 },

        { &dmItems->transTempAlarm,          "Transformer Temp Alarm",
                TRANS_TEMP_ALARM_DM,            DM_ENUM,  1 },

        { &dmItems->transTempWarnThresh,     "Trans Temp Warn Threshold",
                TRANS_TEMP_WARN_THRESH_DM,      DM_INT16, 1 },

        { &dmItems->transTempAlarmThresh,    "Trans Temp Alarm Threshold",
                TRANS_TEMP_ALARM_THRESH_DM,     DM_INT16, 1 },

         { &dmItems->extGfCurrent,            "External Ground Fault Current",
                EXT_GND_FLT_CURRENT_DM,         DM_INT16, 1 },

        { &dmItems->extGndFaultAlarm,        "External Ground Fault Alarm",
                EXT_GND_FLT_ALARM_DM,           DM_ENUM, 1 },

        { NO_ITEM, NULL, NULL, DM_ENDT, 0 } };

                                  /* Initialize PDU Micro Data Manager Items*/
    for (item = 0; pduMicroDmInit[item].dmItem != NO_ITEM; item++)
    {
        if ((*pduMicroDmInit[item].dmItem =
             initMicroDmItem(pduMicroAppPrefix, pduMicroDmInit[item].name,
             pduMicroDmInit[item].type, pduMicroDmInit[item].len)) == ERROR)
        {                         /* Error occurred so print message & exit*/
            logMsg("%s: Error Initializing %s DM Item\n",
                pduMicroName, pduMicroDmInit[item].errorMsg);
            return(ERROR);
        } /* if */
    } /* for */
                                  /* Create and initialize POWER ON item   */
    dmItems->tiburonPowerOnDm =
        initMicroDmItem(TIBURON_DM_PREFIX, TIBURON_POWER_ON_DM, DM_MBOOL, 1);

    return(OK);
} /* createPDUMicroAppDmItems() */

/****************************************************************************/
/* Function    : pduMicroDmItemInit                                         */
/* Purpose     : Read parameters from microcontroller and update DMgr       */
/* Inputs      : Pointer to DM item handles, micro serial channel           */
/* Outputs     : None, but data manager items change                        */
/****************************************************************************/
    LOCAL STATUS
pduMicroDmItemInit(pduMicroDmItems* dmItems, sio32Chan* pduMicroDataChan)
{
    Int16 trys;
                                /* Send Command Enable Command to IBC Micro  */
    for (trys = 0; ((microCmdEnable(pduMicroDataChan) == ERROR) &&
         trys < MICRO_ENABLE_TRYS); trys++)
         taskDelay(sysClkRateGet() / 5);

    if (trys == MICRO_ENABLE_TRYS)
    {
        logMsg("PDU Micro: Error Enabling PDU Micro Microcontroller\n");
        return(ERROR);
    }
                                /* Set Micro Identification initial value    */
    if (updateMicroIdentDm(pduMicroDataChan, dmItems->microDm.idString)
        == ERROR)
        logMsg("PDU Micro: Error reading Identification String\n");

                                /* Set Micro Serial Number initial value     */
    if (updateSerialNoDm(pduMicroDataChan, dmItems->microDm.serialNo) == ERROR)
        logMsg("PDU Micro: Error reading Micro Serial Number\n");

                                /* Set Software Revision initial value       */
    if (updateSoftwareRevDm(pduMicroDataChan, dmItems->microDm.softwareRev)
        == ERROR)
        logMsg("PDU Micro: Error reading Software Revision\n");

                                /* Set Micro Ram Test Result value           */
    if (updateMicroRamTestDm(pduMicroDataChan, dmItems->microDm.ramTest)
        == ERROR)
        logMsg("PDU Micro: Error checking micro RAM Test\n");

                                /* Set Wattage Alarm initial value           */
    if (updateWattageAlarmDm(pduMicroDataChan, dmItems->wattageAlarm)
         == ERROR)
        logMsg("PDU Micro: Error checking wattage alarm status\n");


    if (setVoltageThresh(pduMicroDataChan, PDU_MICRO_VOLTAGE_WARN_THRESH,
        PDU_MICRO_VOLTAGE_ALARM_THRESH ) == ERROR)
        logMsg("PDU Micro: Error setting voltage alarm thresholds\n");

                              /* Set Voltage Alarm initial value            */
    if (updateVoltageAlarmDm(pduMicroDataChan, dmItems->voltageAlarm)
         == ERROR)
        logMsg("PDU Micro: Error checking voltage alarm status\n");

                              /* Set Voltage Alarm initial value            */
    if (updateVoltageMinAlarmDm(pduMicroDataChan, dmItems->voltageMinAlarm)
         == ERROR)
        logMsg("PDU Micro: Error checking voltage Min alarm status\n");

                               /* Set amps Alarm initial value               */
    if (updateAmperageAlarmsDm(pduMicroDataChan, dmItems->ampsPhase3Alarm,
                                                 dmItems->ampsPhase2Alarm,
                                                 dmItems->ampsPhase1Alarm)
         == ERROR)
        logMsg("PDU Micro: Error checking Amperage alarm status\n");

                               /* Set amps Out of Phase Alarm initial value  */
    if (updateOutOfPhaseAlarmDm(pduMicroDataChan, dmItems->outOfPhaseAlarm)
         == ERROR)
        logMsg("PDU Micro: Error checking Out of Phase alarm status\n");

                               /* Set Micro Temperature Alarm initial value  */
    if (updateMicroTempAlarmDm(pduMicroDataChan, dmItems->microTempAlarm) == ERROR)
        logMsg("PDU Micro: Error checking micro temperature alarm status\n");

                               /* Set Transformer Temp  Alarm initial value  */
    if (updateTransTempAlarmDm(pduMicroDataChan, dmItems->transTempAlarm) == ERROR)
        logMsg("PDU Micro: Error checking trans temperature alarm status\n");

                                /* Set Ground Fault Alarm initial values     */
    if (updateGndFltAlarmDm(pduMicroDataChan,
                                           dmItems->extGndFaultAlarm) == ERROR)
        logMsg("PDU: Error checking ground fault alarm status\n");

    return(OK);
} /* pduMicroDmItemInit() */

/****************************************************************************/
/* Function    : pduMicroTask                                               */
/* Purpose     : Initializes communication with PDU Micro Microcontroller   */
/*               Provides interface between PDU Micro and Data Manager      */
/* Inputs      : SIO32 serial channel number for PDU Micro Microcontrller   */
/*               Physically maps the PDU Micro to a serial channel          */
/* Outputs     : Normally runs forever, but returns ERROR on fatal error    */
/****************************************************************************/
    STATUS
pduMicroTask( Nat16 pduMicroSerialChan )
{
    pduMicroDmItems dmItems;        /* PDU Micro Application Data Mgr items  */
    microIOControl microIOCtrl;     /* Microcontroller IO Task control       */

                                    /* Initialize serial channel and task    */
                                    /* synchronization resources             */
    if (initMicroTaskIO( &microIOCtrl, NUM_TASKS, pduMicroSerialChan,
        pduMicroAppPrefix, "/sio32/pduMicro", NO_ITEM ) == ERROR)
    {
        logMsg("Error initializing IO for PDU Micro");
        return(ERROR);
    } /* if */
                                   /* Clear PDU Micro Data Manager handles   */
    bzero(&dmItems, sizeof(dmItems));

                                   /* Create PDU Micro Application Items     */
    if (createPDUMicroAppDmItems(&dmItems, pduMicroAppPrefix, pduMicroName)
         == ERROR)
    {                              /* Error occurred so print message & exit */
        sio32ChanDestroy( pduMicroSerialChan, &microIOCtrl.sio32DataChan );
        return(ERROR);
    } /* if */

                                   /* Start Provider for Static Data & Alarms*/
    dm_start_provider(dmItems.microDm.resetEvent,  DM_STATIC);
    dm_start_provider(dmItems.microDm.idString,    DM_STATIC);
    dm_start_provider(dmItems.microDm.serialNo,    DM_STATIC);
    dm_start_provider(dmItems.microDm.softwareRev, DM_STATIC);
    dm_start_provider(dmItems.microDm.ramTest,     DM_STATIC);

    dm_start_provider(dmItems.wattageAlarm,        DM_STATIC);
    dm_start_provider(dmItems.voltageAlarm,        DM_STATIC);
    dm_start_provider(dmItems.voltageMinAlarm,     DM_STATIC);
    dm_start_provider(dmItems.ampsPhase3Alarm,     DM_STATIC);
    dm_start_provider(dmItems.ampsPhase2Alarm,     DM_STATIC);
    dm_start_provider(dmItems.ampsPhase1Alarm,     DM_STATIC);
    dm_start_provider(dmItems.outOfPhaseAlarm,     DM_STATIC);
    dm_start_provider(dmItems.microTempAlarm,      DM_STATIC);
    dm_start_provider(dmItems.transTempAlarm,      DM_STATIC);
    dm_start_provider(dmItems.extGndFaultAlarm,    DM_STATIC);

    dm_start_consumer(dmItems.tiburonPowerOnDm, DM_STATIC, SEM_NULL);

                                    /* Initialize PDU Micro Data Out Task    */
    if ((microIOCtrl.childTasks[OUT_TASK].taskId =
         taskSpawn("pduMicroOut", PDU_MICRO_OUT_PRIORITY, VX_FP_TASK,
         PDU_MICRO_OUT_STACKSIZE, (FUNCPTR) pduMicroOutTask,
         (int) &dmItems, (int) &microIOCtrl,
         0, 0, 0, 0, 0, 0, 0, 0)) == ERROR)
    {
                                    /* Close serial communication channel    */
        sio32ChanDestroy( pduMicroSerialChan, &microIOCtrl.sio32DataChan );
        logMsg("PDU Micro: Error spawning data output task\n");
        return(ERROR);
    } /* if */

                                    /* Initialize PDU Micro Data In Task     */
    if (( microIOCtrl.childTasks[IN_TASK].taskId =
         taskSpawn( "pduMicroIn", PDU_MICRO_IN_PRIORITY, VX_FP_TASK,
         PDU_MICRO_IN_STACKSIZE, (FUNCPTR) pduMicroInTask,
         (int) &dmItems, (int) &microIOCtrl,
         0, 0, 0, 0, 0, 0, 0, 0) ) == ERROR)
    {                               /* Delete Sonar Dcon Out Task             */
        taskDelete(microIOCtrl.childTasks[OUT_TASK].taskId);
        sio32ChanDestroy( pduMicroSerialChan, &microIOCtrl.sio32DataChan );
        logMsg("PDU Micro: Error spawning data input task\n");
        return(ERROR);
    } /* if */

    FOREVER
    {
        if (microIOCtrl.resetEventCount != 0)
                                    /* Process SRQ's from micro               */
        while(processPDUMicroSRQ(&dmItems, &microIOCtrl)
               != MICRO_RESET_SRQ);

        microIOCtrl.resetEventCount++;   /* Count reset events ffrom micro    */

                                    /* Reset event received from Micro so     */
                                    /* Mark serial coms link as up            */
        setSerialLinkState(&microIOCtrl, LINK_UP);

                                    /* Initialize PDU Micro DM Item values   */
        if (pduMicroDmItemInit( &dmItems,  &microIOCtrl.sio32DataChan ) == OK)
                                     /* Wake up output task to configure micro*/
            semGive(microIOCtrl.childTasks[OUT_TASK].taskSyncSem);
        else
            setSerialLinkState(&microIOCtrl, LINK_DOWN);

    } /* FOREVER */
                                    /* Delete Child Tasks                     */
    taskDelete(microIOCtrl.childTasks[IN_TASK].taskId);
    taskDelete(microIOCtrl.childTasks[OUT_TASK].taskId);

                                    /* Close serial communication channel    */
    sio32ChanDestroy( pduMicroSerialChan, &microIOCtrl.sio32DataChan );

                        /* dm_stop_provider, dm_stop_consumer, etc are NOT   */
                        /* required when the task exits as the Data Manager  */
                        /* does this automatically when the task is deleted  */
                        /* via taskDeleteHookAdd() and dm_task_exit functions*/

    return(OK);         /* That's all folks                                  */
} /* pduMicroTask() */

/*****************************************************************************/
/* Function    : pduMicroOutTask                                             */
/* Purpose     : PDU Can Micro Out Task. Read DM items & write to PDU Micro  */
/* Inputs      : Array of Data Manager Item handles & serial chan structure  */
/* Outputs     : Normally runs forever, but exits if error occurs            */
/*****************************************************************************/
     Void
pduMicroOutTask(Reg pduMicroDmItems *dmItems, microIOControl *microIOCtrl)
{
    DM_Group dmGroup;               /* PDU Micro Data Manager Group          */
    SEM_ID   dmUpdateSem;           /* Data Manager wakes up task when an    */

    DWord   changedBits;            /* Holds dm_group_changes bit vector     */
    DWord   resetEventBit;          /* Microcontroller reset event  bit      */
    DWord   resetCmdBit;            /* Microcontroller reset item changed bit*/
    DWord   wattageWarnBit;         /* Wattage Warning item changed bit      */
    DWord   wattageAlarmBit;        /* Wattage Alarm item changed bit        */
    DWord   voltageWarnBit;         /* Voltage Warning item changed bit      */
    DWord   voltageAlarmBit;        /* Voltage Alarm item changed bit        */
    DWord   ampsPhase3WarnBit;      /* Amps Phase3 Warning item changed bit  */
    DWord   ampsPhase3AlarmBit;     /* Amps Phase3 Alarm item changed bit    */
    DWord   ampsPhase2WarnBit;      /* Amps Phase2 Warning item changed bit  */
    DWord   ampsPhase2AlarmBit;     /* Amps Phase2 Alarm item changed bit    */
    DWord   ampsPhase1WarnBit;      /* Amps Phase1 Warning item changed bit  */
    DWord   ampsPhase1AlarmBit;     /* Amps Phase1 Alarm item changed bit    */
    DWord   outOfPhaseWarnBit;      /* Out of Phase Warning item changed bit */
    DWord   outOfPhaseAlarmBit;     /* Out of Phase Alarm item changed bit   */
    DWord   microTempWarnBit;       /* Micro Temp Warning item changed bit   */
    DWord   microTempAlarmBit;      /* Micro Temp Alarm item changed bit     */
    DWord   transTempWarnBit;       /* Trans Temp Warning item changed bit   */
    DWord   transTempAlarmBit;      /* Trans Temp Alarm item changed bit     */
    DWord   gndFltTestBit;          /* Ground Fault test item changed bit    */

    DWord   voltageMinWarnBit;      /* Voltage Warning item changed bit      */
    DWord   voltageMinAlarmBit;     /* Voltage Alarm item changed bit        */

                                    /* Create switch & power sync semaphores */
    if ((dmUpdateSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
    {
        logMsg("PDU Micro: Error initializing Input Task Resources\n");
        return;
    } /* if */
                                    /* Declare this task a consumer of items */
                                    /* which are written to the PDU Micro t  */
    dm_start_consumer(dmItems->microDm.resetEvent,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->microDm.resetCmd,    DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->wattageWarnThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->wattageAlarmThresh, DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->voltageWarnThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->voltageAlarmThresh, DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->ampsPhase3WarnThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->ampsPhase3AlarmThresh, DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->ampsPhase2WarnThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->ampsPhase2AlarmThresh, DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->ampsPhase1WarnThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->ampsPhase1AlarmThresh, DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->outOfPhaseWarnThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->outOfPhaseAlarmThresh, DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->microTempWarnThresh,   DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->microTempAlarmThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->transTempWarnThresh,   DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->transTempAlarmThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->voltageMinWarnThresh,  DM_STATIC, dmUpdateSem);
    dm_start_consumer(dmItems->voltageMinAlarmThresh, DM_STATIC, dmUpdateSem);

    dmGroup = dm_create_group();    /* Create Data Manager Group for items   */

    dm_group_add_item(dmGroup, dmItems->microDm.resetEvent,  &resetEventBit);
    dm_group_add_item(dmGroup, dmItems->microDm.resetCmd,    &resetCmdBit);

    dm_group_add_item(dmGroup, dmItems->wattageWarnThresh,  &wattageWarnBit);
    dm_group_add_item(dmGroup, dmItems->wattageAlarmThresh, &wattageAlarmBit);
    dm_group_add_item(dmGroup, dmItems->voltageWarnThresh,  &voltageWarnBit);
    dm_group_add_item(dmGroup, dmItems->voltageAlarmThresh, &voltageAlarmBit);
    dm_group_add_item(dmGroup, dmItems->ampsPhase3WarnThresh, &ampsPhase3WarnBit);
    dm_group_add_item(dmGroup, dmItems->ampsPhase3AlarmThresh,&ampsPhase3AlarmBit);
    dm_group_add_item(dmGroup, dmItems->ampsPhase2WarnThresh, &ampsPhase2WarnBit);
    dm_group_add_item(dmGroup, dmItems->ampsPhase2AlarmThresh,&ampsPhase2AlarmBit);
    dm_group_add_item(dmGroup, dmItems->ampsPhase1WarnThresh, &ampsPhase1WarnBit);
    dm_group_add_item(dmGroup, dmItems->ampsPhase1AlarmThresh,&ampsPhase1AlarmBit);
    dm_group_add_item(dmGroup, dmItems->outOfPhaseWarnThresh, &outOfPhaseWarnBit);
    dm_group_add_item(dmGroup, dmItems->outOfPhaseAlarmThresh,&outOfPhaseAlarmBit);
    dm_group_add_item(dmGroup, dmItems->microTempWarnThresh,  &microTempWarnBit);
    dm_group_add_item(dmGroup, dmItems->microTempAlarmThresh, &microTempAlarmBit);
    dm_group_add_item(dmGroup, dmItems->transTempWarnThresh,  &transTempWarnBit);
    dm_group_add_item(dmGroup, dmItems->transTempAlarmThresh, &transTempAlarmBit);
    dm_group_add_item(dmGroup, dmItems->voltageMinWarnThresh,  &voltageMinWarnBit);
    dm_group_add_item(dmGroup, dmItems->voltageMinAlarmThresh, &voltageMinAlarmBit);

    FOREVER
    {
        microIOCtrl->microConfigured = FALSE;

                                    /* Wait for micro reset via SRQ Task      */
        semTake(microIOCtrl->childTasks[OUT_TASK].taskSyncSem, WAIT_FOREVER);

        /* We need to initialize default state of Data manager Items here    */

        initWattageThreshDm(SERIAL_CHAN, dmItems->wattageWarnThresh,
                             dmItems->wattageAlarmThresh);

        initVoltageThreshDm(SERIAL_CHAN, dmItems->voltageWarnThresh,
                             dmItems->voltageAlarmThresh);

        initVoltageMinThreshDm(SERIAL_CHAN, dmItems->voltageMinWarnThresh,
                             dmItems->voltageMinAlarmThresh);

        initAmpsThreshDm(SERIAL_CHAN, dmItems->ampsPhase3WarnThresh,
           dmItems->ampsPhase3AlarmThresh, dmItems->ampsPhase2WarnThresh,
           dmItems->ampsPhase2AlarmThresh, dmItems->ampsPhase1WarnThresh,
           dmItems->ampsPhase1AlarmThresh );


        initOutOfPhaseThreshDm(SERIAL_CHAN, dmItems->outOfPhaseWarnThresh,
                             dmItems->outOfPhaseAlarmThresh);

        initMicroTempThreshDm(SERIAL_CHAN, dmItems->microTempWarnThresh,
                             dmItems->microTempAlarmThresh);

        initTransTempThreshDm(SERIAL_CHAN, dmItems->transTempWarnThresh,
                             dmItems->transTempAlarmThresh);

                                    /* Ask Data Manager which items changed  */
        changedBits = dm_get_group_changes(dmGroup);


                                    /* Flag that micro has been configured    */
        microIOCtrl->microConfigured = TRUE;

                                    /* Wake up input task to read from micro  */
        semGive(microIOCtrl->childTasks[IN_TASK].taskSyncSem);

        while (microIOCtrl->serialLinkState == LINK_UP)
        {                           /* Wait for any data items to change     */
            semTake(dmUpdateSem, WAIT_FOREVER);

                                   /* Ask Data Manager which items changed   */
            changedBits = dm_get_group_changes(dmGroup);

                                    /* Check if micro Reset Event occurred   */
            if (changedBits & resetEventBit)
                break;              /* Exit loop and re-initialize DM items  */

            taskSafe();             /* Prevent task from being deleted during*/
                                    /* serial IO and Data Manager updates    */

            if ( (changedBits & wattageWarnBit) ||
                 (changedBits & wattageAlarmBit) )
                writeWattageThresh(SERIAL_CHAN,
                    dmItems->wattageWarnThresh, dmItems->wattageAlarmThresh);

            if ( (changedBits & voltageWarnBit) ||
                 (changedBits & voltageAlarmBit) )
                writeVoltageThresh(SERIAL_CHAN,
                    dmItems->voltageWarnThresh, dmItems->voltageAlarmThresh);

            if ( (changedBits & voltageMinWarnBit) ||
                 (changedBits & voltageMinAlarmBit) )
                writeVoltageMinThresh(SERIAL_CHAN,
                    dmItems->voltageMinWarnThresh, dmItems->voltageMinAlarmThresh);

            if ( (changedBits & ampsPhase3WarnBit) ||
                 (changedBits & ampsPhase3AlarmBit) )
                writeAmperageThresh(SERIAL_CHAN,
                 dmItems->ampsPhase3WarnThresh, dmItems->ampsPhase3AlarmThresh,
                 dmItems->ampsPhase2WarnThresh, dmItems->ampsPhase2AlarmThresh,
                 dmItems->ampsPhase1WarnThresh, dmItems->ampsPhase1AlarmThresh);

            if ( (changedBits & ampsPhase2WarnBit) ||
                 (changedBits & ampsPhase2AlarmBit) )
                writeAmperageThresh(SERIAL_CHAN,
                 dmItems->ampsPhase3WarnThresh, dmItems->ampsPhase3AlarmThresh,
                 dmItems->ampsPhase2WarnThresh, dmItems->ampsPhase2AlarmThresh,
                 dmItems->ampsPhase1WarnThresh, dmItems->ampsPhase1AlarmThresh);


            if ( (changedBits & ampsPhase1WarnBit) ||
                 (changedBits & ampsPhase1AlarmBit) )
                writeAmperageThresh(SERIAL_CHAN,
                 dmItems->ampsPhase3WarnThresh, dmItems->ampsPhase3AlarmThresh,
                 dmItems->ampsPhase2WarnThresh, dmItems->ampsPhase2AlarmThresh,
                 dmItems->ampsPhase1WarnThresh, dmItems->ampsPhase1AlarmThresh);


            if ( (changedBits & outOfPhaseWarnBit) ||
                 (changedBits & outOfPhaseAlarmBit) )
                writeOutOfPhaseThresh(SERIAL_CHAN,
                    dmItems->outOfPhaseWarnThresh, dmItems->outOfPhaseAlarmThresh);

            if ( (changedBits & microTempWarnBit) ||
                 (changedBits & microTempAlarmBit) )
                writeMicroTempThresh(SERIAL_CHAN,
                     dmItems->microTempWarnThresh, dmItems->microTempAlarmThresh);

            if ( (changedBits & transTempWarnBit) ||
                 (changedBits & transTempAlarmBit) )
                writeTransTempThresh(SERIAL_CHAN,
                     dmItems->transTempWarnThresh, dmItems->transTempAlarmThresh);

                                   /* Check if Reset Command request occurred*/
            if (changedBits & resetCmdBit)
            {                       /* Mark serial link as down               */
                setSerialLinkState(microIOCtrl, LINK_DOWN);
                                    /* Manual reset so announce it            */
                microIOCtrl->announceResets = TRUE;
                                    /* Send Reset Command to Microcontroller  */
                microResetCmd(SERIAL_CHAN);
                break;              /* Exit loop and wait for RESET           */
            } /* if */

            taskUnsafe();          /* Task may now be safely deleted         */

        } /* while (LINK_UP) */
    } /* FOREVER */

                       /* dm_stop_provider, dm_stop_consumer, dm_delete_group*/
                       /* etc are NOT required when the task exits as the    */
                       /* Data Manager does this automatically when the task */
                       /* is deleted via the taskDeleteHookAdd() and         */
                       /* dm_task_exit functions.                            */

                       /* That's all folks !                                 */
} /* pduMicroOutTask() */


/*****************************************************************************/
/* Function    : pduMicroInTask                                              */
/* Purpose     : PDU Micro Input Task. Wakes up periodically, read data      */
/*               from the PDU Micro and write Data Manager Items             */
/* Inputs      : Array of Data Manager Item handles & serial chan structure  */
/* Outputs     : Normally runs forever, but exits if error occurs            */
/*****************************************************************************/
    Void
pduMicroInTask(Reg pduMicroDmItems* dmItems, microIOControl *microIOCtrl)
{
    SEM_ID  wakeupSem;              /* Used by watch dog to wake up this task*/

                                    /* Create wakeup semaphore and watch dog */
                                    /* timer for provider rate control       */
    if ((wakeupSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL )
    {
        logMsg("PDU Micro: Error initializing Input Task Resources\n");
        return;
    } /* if */
                                   /* Provider Task for non-static data items*/
    dm_start_provider(dmItems->wattage,    PDU_MICRO_DM_PERIOD);
    dm_start_provider(dmItems->voltage,    PDU_MICRO_DM_PERIOD);
    dm_start_provider(dmItems->ampsPhase3, PDU_MICRO_DM_PERIOD);
    dm_start_provider(dmItems->ampsPhase2, PDU_MICRO_DM_PERIOD);
    dm_start_provider(dmItems->ampsPhase1, PDU_MICRO_DM_PERIOD);
    dm_start_provider(dmItems->outOfPhase, PDU_MICRO_DM_PERIOD);
    dm_start_provider(dmItems->microTemperature, PDU_MICRO_DM_PERIOD);
    dm_start_provider(dmItems->transTemperature, PDU_MICRO_DM_PERIOD);
    dm_start_provider(dmItems->extGfCurrent,     PDU_MICRO_DM_PERIOD);
                                    /* Update Rate is not guaranteed due to  */
                                    /* the possibility of task preemption    */
    FOREVER
    {                               /* Wait for IBC Coms to be initialized   */
       semTake(microIOCtrl->childTasks[IN_TASK].taskSyncSem, WAIT_FOREVER);

       while (microIOCtrl->serialLinkState == LINK_UP)
       {
           taskSafe();             /* Prevent task from being deleted during*/
                                    /* serial IO and Data Manager updates    */

           updateWattageDm   (SERIAL_CHAN, dmItems->wattage );
           updateVoltageDm   (SERIAL_CHAN, dmItems->voltage );
           updateAmperagesDm (SERIAL_CHAN, dmItems->ampsPhase3,
                              dmItems->ampsPhase2,
                              dmItems->ampsPhase1);
           updateOutOfPhaseDm(SERIAL_CHAN, dmItems->outOfPhase );
           updateMicroTempDm(SERIAL_CHAN, dmItems->microTemperature );
           updateTransTempDm(SERIAL_CHAN, dmItems->transTemperature );
                                    /* Update Ground Fault Current           */
           updateGndFltCurrentDm(SERIAL_CHAN, dmItems->extGfCurrent );

           taskUnsafe();            /* task may now be deleted safely        */

                                    /* pend until sem timeout  wakes us up   */
           semTake(wakeupSem, sysClkRateGet() /
                   (USECS_PER_SEC / PDU_MICRO_DM_PERIOD));
       } /* while */
   } /* FOREVER */

   semDelete(wakeupSem);           /* semaphore resources                   */

                       /* dm_stop_provider, dm_stop_consumer, dm_delete_group*/
                       /* etc are not required when the task exits as the    */
                       /* data manager does this automatically when the task */
                       /* is deleted via the taskDeleteHookAdd() and         */
                       /* dm_task_exit functions.                            */

                       /* that's all folks !                                 */
} /* pduMicroInTask() */

/*****************************************************************************/
/* Function    : processPDUMicroSRQ                                           */
/* Purpose     : Decode Service Request and take appropriate action          */
/* Inputs      : SRQ code, array of DM items, serial channel                 */
/* Outputs     : Returns Reset Status & many DM items are changed            */
/*****************************************************************************/
    LOCAL Word
processPDUMicroSRQ( Reg pduMicroDmItems* dmItems, microIOControl *microIOCtrl )
{
    Byte buffer[SRQ_PACKET_LEN];    /* Buffer for micro communications data  */
    Word srqRequest;                /* Service Request Value                 */
    Word alarmStatus;               /* Microcontroller Alarm Status Word     */
    microAlarm alarm;               /* Alarm Status                          */
    gfStatus   gfAlarm;             /* Ground Fault Alarm Status             */

                                    /* Block on Reading Service Request      */
    if (readSRQPacket(SERIAL_CHAN, buffer, SRQ_PACKET_LEN,
                 WAIT_FOREVER) != ERROR)
                                    /* Service Request received so process it*/
    srqRequest = wordFromBuf(buffer, 0);

    switch (srqRequest)             /* Decode Service Request from micro     */
    {
      case MICRO_RESET_SRQ:         /* Microcontroller Reset Occurred        */
                                    /* Post Reset Event DM Item              */
        if (microIOCtrl->announceResets)
           microResetEventDm(dmItems->microDm.resetEvent);
        break;

      case WATTAGE_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->wattageAlarm, &alarm, sizeof(alarm));
        break;

      case VOLTAGE_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->voltageAlarm, &alarm, sizeof(alarm));
        break;

      case VOLTAGE_MIN_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->voltageMinAlarm, &alarm, sizeof(alarm));
        break;

      case AMPS_PHASE3_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->ampsPhase3Alarm, &alarm, sizeof(alarm));
        break;


      case AMPS_PHASE2_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->ampsPhase2Alarm, &alarm, sizeof(alarm));
        break;

      case AMPS_PHASE1_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->ampsPhase1Alarm, &alarm, sizeof(alarm));
        break;

      case OUT_OF_PHASE_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->outOfPhaseAlarm, &alarm, sizeof(alarm));
        break;

      case MICRO_TEMP_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->microTempAlarm, &alarm, sizeof(alarm));
        break;

      case TRANS_TEMP_ALARM_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        alarm = (microAlarm) alarmStatus;
        writeDmItem(dmItems->transTempAlarm, &alarm, sizeof(alarm));
        break;

      case EXTERNAL_GNDFLT_SRQ:
        wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
        gfAlarm = (gfStatus) alarmStatus;
        writeDmItem(dmItems->extGndFaultAlarm, &gfAlarm,
                    sizeof(gfAlarm));
        break;

      default:
        printf("PDU Micro: Unrecognized SRQ 0x%x\n", srqRequest);
    } /* switch */

    return (srqRequest);                    /* Return SRQ Received to Caller */
} /* processPDUMicroSRQ() */












