/****************************************************************************/
/* Copyright 1992, 1993 MBARI                                               */
/****************************************************************************/
/* Summary  : IBC Data Concentrator Data Manager Functions for VxWorks      */
/* Filename : ibcDm.c                                                       */
/* Author   : Andrew Pearce                                                 */
/* Project  : TIburon ROV                                                   */
/* Version  : Version 1.0                                                   */
/* Created  : 10/01/92                                                      */
/* Modified : 06/08/93                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: /usr/tiburon/vw/ibc/lib/RCS/ibcDm.c,v 1.1 1998/02/10 21:28:53 oreilly Exp oreilly $
 * $Log: ibcDm.c,v $
 * Revision 1.1  1998/02/10 21:28:53  oreilly
 * Initial revision
 *
 * Revision 1.1  93/07/01  14:34:30  14:34:30  pean (Andrew Pearce)
 * Initial revision
 *
 *
 */
/****************************************************************************/

#include <vxWorks.h>                /* vxWorks system declarations          */
#include <semLib.h>                 /* vxWorks semaphore functions          */
#include <taskLib.h>                /* vxWorks task library functions       */
#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 MBARI constants        */
#include <tiburon.h>                /* Vehicle constants and definitions    */

#include <sio32.h>                  /* SIO32 hardware and driver information*/
#include <sio32Server.h>            /* Sio32 server communication services  */
#include <sio32Client.h>            /* Sio32 client communication services  */
#include <powerTypes.h>             /* Power management Data Types          */
#include <powerDM.h>                /* Power/Switching Data Manager Items   */

#include <datamgr.h>                /* Data Manager declarations            */
#include <dm_errno.h>               /* Data Manager error declarations      */

#include "microcmd.h"               /* Microcontroller commands             */
#include "microCmd.h"               /* Microcontroller serial I/O functions */
#include "ibc_card.h"               /* IBC Card Types                       */
#include "ibc_cmd.h"                /* IBC Serial Commands                  */
#include "filter.h"                 /* General Filter Routines              */
#include "vicor.h"                  /* Dual Vicor Board Definitions         */

#include "microDm.h"                /* Micro Data Manager Items & Functions */
#include "switch.h"                 /* IBC Function Libarary Definitions    */

#include "ibc.h"                    /* IBC Communication Interface Functions*/
#include "lps.h"                    /* Functions prototypes for lps board   */
#include "hps.h"                    /* Functions prototypes for hps board   */
#include "ibcDm.h"                  /* Functions prototypes for ibcDm.c     */

#include "tiburon.h"                /* Tiburon vehicle-wide definitions     */


/*****************************************************************************/
/* Function    : createIbcCpuDmItems                                         */
/* Purpose     : Initialize Data Manager Item Handles for IBC CPU            */
/* Inputs      : Pointer to structure containing IBC CPU Data Manager Handes */
/*               and IBC Data Concentrator Name                              */
/* Outputs     : None, but Data Manager Items change                         */
/*****************************************************************************/
    STATUS
createIbcCpuDmItems( ibcCpuDmItems *cpuItems, const char* ibcDmPrefix,
    const char* ibcDataConName )
{
    Int32   item;                   /* Counter for DM Item Initialization   */
    Errno   status;                 /* Result of dm_create function call    */

    char dmItemName[DM_ITEM_NAME_LEN];         /* Complete item name string */

    dmItemList ibcCpuDmInit[] =

      { { &cpuItems->microDm.resetEvent,     "Reset Event",
                MICRO_RESET_EVENT_DM,           DM_EMPTY, 1 },

        { &cpuItems->microDm.resetCmd,       "Reset Command",
                MICRO_RESET_CMD_DM,             DM_EMPTY, 1 },

        { &cpuItems->microDm.idString,       "Identification",
                MICRO_IDENT_DM,                 DM_CHAR, MICRO_ID_LEN  },

        { &cpuItems->microDm.serialNo,       "Micro Serial Number",
                MICRO_SERIAL_NO_DM,             DM_CHAR, MICRO_SERNO_LEN },

        { &cpuItems->microDm.softwareRev,    "Software Revision",
                SOFTWARE_REV_DM,                DM_CHAR, SOFTWARE_REV_LEN },

        { &cpuItems->microDm.ramTest,        "Micro RAM Test",
                RAM_TEST_STATUS_DM,             DM_MBOOL, 1 },

        { &cpuItems->ibcCardConfigError,     "IBC Card Config Error",
                IBC_CARD_ERROR_DM,              DM_NAT16, 1 },

        { &cpuItems->microHumidity,          "Humidity Value",
                HUMIDITY_DM,                    DM_NAT16, 1 },

        { &cpuItems->humidityAlarm,          "Humidity Alarm",
                HUMIDITY_ALARM_DM,              DM_ENUM,  1 },

        { &cpuItems->humidityWarnThresh,     "Humidity Warning Threshold",
                HUMIDITY_WARN_THRESH_DM,        DM_NAT16, 1 },

        { &cpuItems->humidityAlarmThresh,    "Humidity Alarm Threshold",
                HUMIDITY_ALARM_THRESH_DM,       DM_NAT16, 1 },

        { NO_ITEM, NULL, NULL, DM_ENDT, 0 } };

                                    /* Clear list of Data Manager Item handles*/
    bzero(cpuItems, sizeof(ibcCpuDmItems));

                                   /* Initialize Data Manager Items from table*/
    if (initMicroDmItemList(ibcCpuDmInit, ibcDmPrefix, ibcDataConName) == ERROR)
        return (ERROR);
                                    /* Build name from name prefix & name     */
    strcpy(dmItemName, (char *) ibcDmPrefix);
    strcat(dmItemName, IBC_CARD_CONFIG_DM);

                                    /* Initilize IBC Card Config DM Item      */
    status = dm_create(dmItemName, 1, &cpuItems->ibcCardConfig,
        DM_NAT16, 1, DM_NAT16, IBC_MAX_CARDS, DM_ENDT);

                                    /* Treat item exists the same as success  */
    if ( (status != SUCCESS) && (status != EDM_NAME_EXISTS) )
    {                               /* Error occurred so print message & exit */
        logMsg("%s: Error Initializing %s DM Item\n", ibcDataConName,
           ibcCpuDmInit[item].errorMsg);
        return(ERROR);
    } /* if */

                                    /* Declare this task an item provider    */
    dm_start_provider(cpuItems->microDm.idString,    DM_STATIC);
    dm_start_provider(cpuItems->microDm.serialNo,    DM_STATIC);
    dm_start_provider(cpuItems->microDm.softwareRev, DM_STATIC);
    dm_start_provider(cpuItems->microDm.resetEvent,  DM_STATIC);
    dm_start_provider(cpuItems->microDm.ramTest,     DM_STATIC);

    dm_start_provider(cpuItems->ibcCardConfig,       DM_STATIC);
    dm_start_provider(cpuItems->ibcCardConfigError,  DM_STATIC);
    dm_start_provider(cpuItems->humidityAlarm,       DM_STATIC);

    return(OK);                     /* All IBC CPU Data Mgr items initialized */
} /* createIbcCpuDmItems() */

    Void
initIbcCpuProvider( ibcCpuDmItems* cpuItems, Period period )
{
    dm_start_provider(cpuItems->microHumidity,  period);
} /* initIbcCpuProvider() */

    DWord
initIbcCpuConsumer( ibcCpuDmItems* cpuItems, cpuUpdateBits *cpuBits,
    SEM_ID updateSem )
{
    DWord cpuGroup;

    cpuGroup = dm_create_group();    /* Create Data Manager Group for CPU  */

    dm_start_consumer(cpuItems->microDm.resetEvent,  DM_STATIC, updateSem);
    dm_start_consumer(cpuItems->microDm.resetCmd,    DM_STATIC, updateSem);
    dm_start_consumer(cpuItems->humidityWarnThresh,  DM_STATIC, updateSem);
    dm_start_consumer(cpuItems->humidityAlarmThresh, DM_STATIC, updateSem);

    dm_group_add_item(cpuGroup, cpuItems->microDm.resetEvent,
                      &cpuBits->resetEventBit);

    dm_group_add_item(cpuGroup, cpuItems->microDm.resetCmd,
                      &cpuBits->resetCmdBit);

    dm_group_add_item(cpuGroup, cpuItems->humidityWarnThresh,
                      &cpuBits->humidityWarnThreshBit);

    dm_group_add_item(cpuGroup, cpuItems->humidityAlarmThresh,
                      &cpuBits->humidityAlarmThreshBit);

    return (cpuGroup);
} /* initIbcCpuConsumer() */

/*****************************************************************************/
/* Function    : initIbcCpuDmItems                                           */
/* Purpose     : Reads parameters from IBC CPU & update Data Manager items   */
/* Inputs      : Array of Data Manager Item handles & serial chan structure  */
/* Outputs     : None, but Data Manager Items change                         */
/*****************************************************************************/
    STATUS
initIbcCpuDmItems( ibcCpuDmItems* cpuItems, sio32Chan* ibcCpuDataChan,
    const char *ibcDataCon, ibcCardConfig ibcCardConfiguration )
{
    Int16 tries;
                                /* Send Command Enable Command to IBC Micro  */
    for (tries = 0;  ((microCmdEnable(ibcCpuDataChan) == ERROR) &&
           tries < MICRO_ENABLE_TRYS); tries++)
        taskDelay(sysClkRateGet() / 5);

    if (tries == MICRO_ENABLE_TRYS)
    {
        logMsg("%s: Error Enabling IBC Microcontroller\n", ibcDataCon);
        return (ERROR);
    } /* if */

                                /* Set Micro Identification initial value    */
    if (updateMicroIdentDm(ibcCpuDataChan, cpuItems->microDm.idString)
        == ERROR)
        logMsg("%s: Error reading Identification String\n", ibcDataCon);

                                /* Set Micro Serial Number initial value     */
    if (updateSerialNoDm(ibcCpuDataChan, cpuItems->microDm.serialNo) == ERROR)
        logMsg("%s: Error reading Micro Serial Number\n", ibcDataCon);

                                /* Set Software Revision initial value       */
    if (updateSoftwareRevDm(ibcCpuDataChan, cpuItems->microDm.softwareRev)
        == ERROR)
        logMsg("%s: Error reading Software Revision\n", ibcDataCon);

                                /* Set Micro Ram Test Result value           */
    if (updateMicroRamTestDm(ibcCpuDataChan, cpuItems->microDm.ramTest)
        == ERROR)
        logMsg("%s: Error checking micro RAM Test\n", ibcDataCon);

                                /* Read IBC Card Configuration               */
    if (updateIbcCardConfigDm(ibcCpuDataChan, cpuItems->ibcCardConfig,
              cpuItems->ibcCardConfigError, ibcCardConfiguration ) == ERROR)
        logMsg("%s: Error checking IBC Card Configuration\n", ibcDataCon);

                                /* Set default humidity warn/alarm thresholds*/
    if (ibcCpuSetHumidityThresh( ibcCpuDataChan, ROV_HUMIDITY_WARN_THRESH,
        ROV_HUMIDITY_ALARM_THRESH ) == ERROR)
        logMsg("%s: Error setting Humidity Alarm Thresholds\n", ibcDataCon);

                                /* Set Micro Humidity Alarm initial value    */
    if (updateIbcHumidityAlarmDm(ibcCpuDataChan, cpuItems->humidityAlarm)
        == ERROR)
        logMsg("%s: Error checking humidity alarm status\n", ibcDataCon);

    return(OK);
} /* initIbcCpuDmItems() */

/****************************************************************************/
/* Function    : initIbcHumidityThreshDm                                    */
/* Purpose     : Read Humidity Threshold and update data manager item       */
/* Inputs      : Sio32 channel, humidity alarm threshold dm item handle     */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
initIbcHumidityThreshDm( sio32Chan *sio32DataChan, DM_Item humidityWarnDm,
    DM_Item humidityAlarmDm )
{
    Int16   warnThresh, alarmThresh;    /* Humidity Alarm Thresholds        */

                                        /* Get Humidity Alarm Thresh        */
    if (ibcCpuGetHumidityThresh(sio32DataChan, &warnThresh, &alarmThresh) != OK)
        return (ERROR);
                                        /* We MUST use urgent open here as  */
                                        /* another task is normal provider  */

    urgentWriteDmItem( humidityAlarmDm, &alarmThresh, sizeof(alarmThresh));
    return (urgentWriteDmItem(humidityWarnDm, &warnThresh, sizeof(warnThresh)));
} /* initIbcHumidityThreshDm() */

/****************************************************************************/
/* Function    : writeIbcHumidityThresh                                     */
/* Purpose     : Get humidity alarm threshold value from dm and send to IBC */
/* Inputs      : Sio32 channel, humdiity threshold dm item handle           */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
writeIbcHumidityThresh( sio32Chan *sio32DataChan, DM_Item humidityWarnDm,
    DM_Item humidityAlarmDm )
{
    Errno   status;                     /* Result of dm_read                */
    Int16   warnThresh, alarmThresh;    /* Humidity Alarm Threshold         */

                                        /* Read Humidity Thresh from dmgr   */
    status = dm_read( humidityWarnDm, (char *) &warnThresh,
         sizeof(warnThresh), (DM_Time *) NULL);

    status = dm_read( humidityAlarmDm, (char *) &alarmThresh,
         sizeof(alarmThresh), (DM_Time *) NULL);

                                        /* Check for successful dm_read     */
    if ((status == SUCCESS) || (status == EDM_NOPROVIDER))
                                        /* Send value to motor micro        */
        if (ibcCpuSetHumidityThresh( sio32DataChan, warnThresh, alarmThresh)
           == OK) return (OK);

    return(ERROR);
} /* writeIbcHumidityThresh() */

/****************************************************************************/
/* Function    : updateIbcHumidityDm                                        */
/* Purpose     : Reads IBC CPU humidity sensor value & updates dmgr item    */
/* Inputs      : Sio32 chan & humidity sensor data manager item handle      */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
updateIbcHumidityDm( sio32Chan *sio32DataChan, DM_Item microHumidityDm )
{
    Int16 humidity;                 /* IBC CPU Humidity Sensor Value        */
                                    /* Read humidity sensor status          */
    if (ibcCpuGetHumidity(sio32DataChan, &humidity) != OK)
        return(ERROR);
                                    /* Write humidity sensor to Data Manager*/
    return (writeDmItem(microHumidityDm, &humidity, sizeof(humidity) ));
} /* updateIbcHumidityDm() */

/****************************************************************************/
/* Function    : updateIbcHumidityAlarmDm                                   */
/* Purpose     : Reads IBC CPU humidity alarm value & updates dmgr item     */
/* Inputs      : Sio32 chan & humidity alarm data manager item handle       */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
    STATUS
updateIbcHumidityAlarmDm( sio32Chan *sio32DataChan, DM_Item humidityAlarmDm )
{
    microAlarm humidityAlarm;       /* IBC CPU Humidity Alarm Value         */
    Word alarmStatus;               /* Humidity alarm status                */

                                    /* Read humidity alarm status           */
    if (ibcCpuGetHumidityAlarm(sio32DataChan, &alarmStatus) != OK)
        return(ERROR);

    humidityAlarm = (microAlarm) alarmStatus;

                                    /* Write humidity alarm to Data Manager */
    return(writeDmItem(humidityAlarmDm, &humidityAlarm, sizeof(humidityAlarm)));
} /* updateIbcHumidityAlarmDm() */

/****************************************************************************/
/* Function    : updateIbcCardConfigDm                                      */
/* Purpose     : Reads IBC Card Configuration & updates date manager item   */
/* Inputs      : Sio32 chan & IBC Card Config data manager item handle      */
/* Outputs     : Returns OK or ERROR                                        */
/****************************************************************************/
STATUS
updateIbcCardConfigDm( sio32Chan *sio32DataChan, DM_Item ibcCardConfigDm,
    DM_Item ibcCardConfigErrorDm, ibcCardConfig cardConfig )
{
    ibcCardConfig ibcCards;
    Nat16       configStatus;
    Int16       totalCards;
    Int16       card, cardFound;

    if (ibcCpuGetCardConfig( sio32DataChan, &ibcCards) != OK)
        return(ERROR);
                                    /* Write IBC Card Config Data Manager   */
    writeDmItem(ibcCardConfigDm, &ibcCards, sizeof(ibcCards) );

    totalCards = cardConfig.numCards;

    for (card = 0; card < cardConfig.numCards; card++)
        for (cardFound = 0; cardFound < ibcCards.numCards; cardFound++)
            if (ibcCards.address[cardFound] == cardConfig.address[card])
            {
                cardConfig.address[card] = 0;
                totalCards--;
            } /* if */

    if (totalCards > 0)
    {
        for (card = 0; card < cardConfig.numCards; card++)
          if (cardConfig.address[card] != 0)
                                    /* Write IBC Card Config Error Data Mgr  */
             return (writeDmItem(ibcCardConfigErrorDm,
                 &cardConfig.address[card], sizeof(cardConfig.address[card])) );
    } /* if */

    configStatus = (totalCards == 0 ? OK : ERROR);
                                    /* Write IBC Card Config Error Data Mgr  */
    return (writeDmItem(ibcCardConfigErrorDm,
                &configStatus, sizeof(configStatus) ));
} /* updateIbcCardConfigCmd() */

    MBool
processIbcCpuSRQ( Word srqRequest, Byte* buffer, ibcCpuDmItems* cpuItems )
{
    Word alarmStatus;               /* Microcontroller Alarm Status Word     */
    microAlarm alarm;               /* Alarm Status                          */

    switch (srqRequest)
    {
        case MICRO_RESET_SRQ:           /* Microcontroller Reset Occurred     */
            printf("Reset Recvd\n");
            break;

        case HUMIDITY_ALARM_SRQ:       /* Humidity Sensor Alarm Active       */
            wordsFromBuf(buffer, 2, &srqRequest, &alarmStatus);
            alarm = (microAlarm) alarmStatus;
            writeDmItem(cpuItems->humidityAlarm, &alarm, sizeof(alarm));
            break;

        default:
            return(FALSE);              /* SRQ Request not recognized        */

    } /* switch */

    return(TRUE);                       /* SRQ Request recognized            */
} /* processIbcCpuSRQ() */




