/*****************************************************************************/
/* Copyright 1996 MBARI                                                      */
/*****************************************************************************/
/* Summary  : microcontroller task synchronization and IO interface          */
/* Filename : microTask.c                                                    */
/* Author   : Andrew Pearce                                                  */
/* Project  : Tiburon                                                        */
/* Version  : Version 1.0                                                    */
/* Created  : 08/02/96                                                       */
/* Modified : 08/02/98                                                       */
/* Archived :                                                                */
/*****************************************************************************/
/* Modification History:                                                     */
/* $Header$
 * $Log$
 */
/*****************************************************************************/

#include <vxWorks.h>                /* vxWorks system declarations           */
#include <semLib.h>                 /* vxWorks Semaphore declarations        */
#include <msgQLib.h>                /* vxWorks Message Queue Library         */

#include "mbariTypes.h"             /* MBARI style guide type declarations   */
#include "mbariConst.h"             /* Miscellaneous constants               */

#include <datamgr.h>                /* Data Manager declarations             */
#include <dm_errno.h>               /* Data Manager error declarations       */

#include "sio32Drv.h"               /* SIO32 hardware and driver information */
#include "sio32Server.h"            /* Sio32 Client/Server Communication     */
#include "sio32Client.h"            /* Sio32 Client/Server Communication     */

#include "microDm.h"                /* Microcontroller Data Manager Items   */
#include "powerTypes.h"             /* Power management Data Types          */

#include "microTask.h"              /* Microcontroller Task IO definitions   */


/*****************************************************************************/
    STATUS
initMicroTaskIO( microIOControl *microIOCtrl, Nat16 numTasks, Nat16 serialChan,
    const char *prefix, const char *chanName, const char *powerDmItemName )
{
    Nat16 task;

    microIOCtrl->powerSwitchDm   = NO_ITEM;
    microIOCtrl->powerSwitchSem  = SEM_NULL;

    microIOCtrl->resetEventCount = 0;
    microIOCtrl->announceResets  = FALSE;
    microIOCtrl->microConfigured = FALSE;
    microIOCtrl->serialLinkState = LINK_DOWN;

    if ((microIOCtrl->comErrorDm =
         initMicroDmItem(prefix, COM_LINK_ERROR_DM, DM_MBOOL, 1))
            == ERROR) return(ERROR);

    dm_start_provider (microIOCtrl->comErrorDm, DM_STATIC);
    writeBooleanDmItem(microIOCtrl->comErrorDm, TRUE);

    if (powerDmItemName != NULL)
    {                              /* Create Power Switch DM Item handle    */
        if ((microIOCtrl->powerSwitchDm =
            initMicroDmItem("", (char *) powerDmItemName, DM_ENUM, 1))
            == ERROR) return(ERROR);

        if ((microIOCtrl->powerSwitchSem =
            semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
            return (ERROR);

        dm_start_consumer(microIOCtrl->powerSwitchDm, DM_STATIC,
            microIOCtrl->powerSwitchSem);
    } /* if */
                                   /* Initialize micro serial communication */
    if (sio32ChanInit(serialChan, (char *) chanName,
        &microIOCtrl->sio32DataChan) == ERROR)
        return (ERROR);

    numTasks--;                    /* Don't include parent SRQ Task         */
    microIOCtrl->numChildTasks = numTasks;

    if ((microIOCtrl->childTasks = (microChildTask *)
         malloc(sizeof(microChildTask) * numTasks)) == (microChildTask *) NULL)
        return (ERROR);

    for (task = 0; task < numTasks; task++)
    {                              /* Create task synchronization sem       */
        if ((microIOCtrl->childTasks[task].taskSyncSem =
            semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
        {
            free (microIOCtrl->childTasks);
            return(ERROR);
        } /* if */

        microIOCtrl->childTasks[task].taskId = NULL;
    } /* for */

    return (OK);
} /* initMicroTaskIO() */

    Void
setSerialLinkState(microIOControl *microIOCtrl, serialComState linkState)
{
    MBool comError;

    if (linkState == LINK_UP)
    {
        microIOCtrl->serialLinkState = LINK_UP;
        microIOCtrl->announceResets  = TRUE;
        comError = FALSE;
    } /* if */
    else
    {
        microIOCtrl->serialLinkState = LINK_DOWN;
        microIOCtrl->announceResets  = FALSE;
        comError = TRUE;
    } /* else */

    urgentWriteDmItem(microIOCtrl->comErrorDm, &comError, sizeof(comError));
} /* setSerialLinkState() */

     switchStatus
microDevPowerSwitchState(microIOControl *microIOCtrl)
{
    switchStatus powerSwitch;

    if (microIOCtrl->powerSwitchDm == NO_ITEM)
        return (SWITCH_ON);

    if (dm_read(microIOCtrl->powerSwitchDm, &powerSwitch,
        sizeof(powerSwitch), (DM_Time *) NULL) == SUCCESS )
        return (powerSwitch);
    else
        return (SWITCH_OFF);
} /* microDevPowerSwitchStatus() */
