/****************************************************************************/
/* Copyright 1990 to 1994 MBARI                                             */
/****************************************************************************/
/* Summary  : Application layer interface to microcontroller communications */
/* Filename : applay.c                                                      */
/* Author   : Andrew Pearce                                                 */
/* Project  : ROV 1.5 Microcontroller Board Rev 2.0                         */
/* Version  : 2.0                                                           */
/* Created  : 04/06/92                                                      */
/* Modified : 08/23/94                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: /usr/tiburon/.cvsroot/micro/lib/applay.c,v 1.1.1.1 1997/05/02 17:15:59 pean Exp $
 * $Log: applay.c,v $
 * Revision 1.1.1.1  1997/05/02 17:15:59  pean
 * Initial release of the microcontroller software after Tiburon
 * Moolpool Dive to test IView, Lapboxes, modified Power can
 * GF/5V using bus capacitance mode.
 *
 * Revision 1.1  92/05/14  09:14:25  09:14:25  pean (Andrew Pearce 408-647-3746)
 * Initial revision
 *
*/
/****************************************************************************/
                                        /* Generate code for the 80C196KB   */
#pragma model(196)
#pragma nosignedchar                    /* Use unsigned char (Char)         */

#include "C:/C96/include/80C196.h"      /* 80196 Register mapping           */
#include "C:/C96/include/stddef.h"      /* C Standard Definitions           */
#include "C:/C96/include/stdarg.h"      /* C var args Definitions           */

#include "const.h"                      /* Misc. constants - TRUE/FALSE etc */
#include "types.h"                      /* MBARI style guide declarations   */
#include "microasm.h"                   /* Assembly language functions      */
#include "malloc.h"                     /* Malloc support definitions       */
#include "microdef.h"                   /* Microcontroller Definitions      */
#include "microlib.h"                   /* Microcontroller Library decls.   */
#include "serial.h"                     /* data link layer functions        */
#include "proto.h"                      /* protocol layer functions         */
#include "applay.h"                     /* application layer functions      */

/****************************************************************************/
/* Function    : wordToBuf                                                  */
/* Purpose     : Insert a word into a buffer using Big Endian format        */
/* Inputs      : buffer and word                                            */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
wordToBuf(Byte *buffer, Word data)
{
    *buffer++ = (Byte) (data >> 8);     /* store high byte                  */
    *buffer = (Byte) (data & 0xff);     /* store low byte                   */
} /* wordToBuf() */

/****************************************************************************/
/* Function    : wordFromBuf                                                */
/* Purpose     : Remove a word from a buffer using Big Endian format        */
/* Inputs      : buffer offset in bytes                                     */
/* Outputs     : Word                                                       */
/****************************************************************************/
    Word
wordFromBuf(Byte *buffer, Int16 index)
{
                                    /* Get high and low bytes and build     */
                                    /* a word                               */
    return ((((Word) (*(buffer + index))) << 8) | (*(buffer + index + 1)));
} /* wordFromBuf() */

/****************************************************************************/
/* Function    : wordsToBuf                                                 */
/* Purpose     : Insert several words into a buffer using Big Endian format */
/* Inputs      : Buffer, number of arguments, list of words                 */
/* Outputs     : Word                                                       */
/****************************************************************************/
    Void
wordsToBuf(Byte *buffer, Int16 nWords, ... )
{
    Int16   i;                      /* Argument counter                     */
    va_list argPtr;                 /* Argument list pointer                */

    va_start(argPtr, nWords);       /* argPtr points to 1st unnamed argument*/

    for (i = 0; i < nWords; i++)
    {
        *buffer++ = (Byte) ((*(Word *) argPtr) >> 8);   /* store high byte  */
        *buffer++ = (Byte) ((*(Word *) argPtr) & 0xff); /* store low byte   */
        va_arg(argPtr, Word*);      /* Point to next word pointer argument  */
    } /* for */

    va_end(argPtr);                 /* Cleanup var args stuff               */
} /* wordsToBuf() */

/****************************************************************************/
/* Function    : wordsFromBuf                                               */
/* Purpose     : Remove several words from a buffer using Big Endian format */
/* Inputs      : Buffer, number of arguments, list of pointers to words     */
/* Outputs     : Word                                                       */
/****************************************************************************/
    Void
wordsFromBuf(Byte *buffer, Int16 nWords, ... )
{
    Int16   arg;                    /* Argument counter                     */
    va_list argPtr;                 /* Argument list pointer                */
    Word    *ptr;                   /* Copy of buffer pointer               */

    va_start(argPtr, nWords);       /* argPtr points to 1st unnamed argument*/

    for (arg = 0; arg < nWords; arg++)
    {
        ptr = (Word *) (* (Word *)argPtr);
                                    /* Get high and low bytes and build word*/
        *ptr = (( (Word) (*buffer++) << 8) | (*buffer++));
        va_arg(argPtr, Word*);      /* Point to next word pointer argument  */
    } /* for */

    va_end(argPtr);                 /* Cleanup var args stuff               */
} /* wordsFromBuf() */

/****************************************************************************/
/* Function    : initSerialProtocol                                         */
/* Purpose     : Application layer function to initialize serial protocol   */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
initSerialProtocol( Void (*disconnectFunc) () )
{
    initSerialPort();                   /* Initialize micro Serial Port     */
    initDataLinkLayer();                /* Initialize data link layer       */
    initProtocolLayer();                /* Initialize protocol layer        */
                                        /* Add disconnect function hook     */
    dataLinkDisconnectHook(disconnectFunc);
} /* initSerialProtocol() */

/****************************************************************************/
/* Function    : freeRecvdPacket                                            */
/* Purpose     : Frees packet previously read with readRecvdPacket          */
/* Inputs      : packet buffer                                              */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
freeRecvdPacket(Byte *packet)
{
     free(packet);
} /* freeRecvdPacket() */

/****************************************************************************/
/* Function    : writeWordPacket                                            */
/* Purpose     : Applic. layer function to send a word using protcol layer  */
/* Inputs      : Word to send                                               */
/* Outputs     : Returns ERROR or OK                                        */
/****************************************************************************/
    Int16
writeWordPacket(Word value)
{
    Byte    buffer[sizeof(value)];     /* buffer to hold the data          */

    wordToBuf(buffer, value);          /* copy the status word into buffer */
                                       /* and write to serial port         */
    return(writeDataPacket(buffer, sizeof(value)));
} /* writeWordPacket() */

/****************************************************************************/
/* Function    : writeServiceRequest                                        */
/* Purpose     : Applic. layer function to send a service request packet    */
/* Inputs      : Number of words and list of Service Request Words to send  */
/* Outputs     : Returns ERROR or OK                                        */
/****************************************************************************/
    Int16
writeServiceRequest(Int16 nWords, ... )
{
    Int16   arg;                    /* Argument counter                     */
    va_list argPtr;                 /* Argument list pointer                */
    Byte    buffer[MAX_REPLY_WORDS * sizeof(Word)];
    Byte   *bufPtr = buffer;

    va_start(argPtr, nWords);       /* argPtr points to 1st unnamed argument*/

    for (arg = 0; arg < nWords; arg++)
    {
        *bufPtr++ = (Byte) ((*(Word *) argPtr) >> 8);   /* store high byte  */
        *bufPtr++ = (Byte) ((*(Word *) argPtr) & 0xff); /* store low byte   */
        va_arg(argPtr, Word*);      /* Point to next word pointer argument  */
    } /* for */

    va_end(argPtr);                 /* Cleanup var args stuff               */

                                    /**** Send Data Packet to Serial Port ***/
    return (writeSRQPacket( buffer, nWords * sizeof(Word) ));
} /* writeServiceRequest() */

/****************************************************************************/
/* Function    : replyToCommand                                             */
/* Purpose     : Send serial command reply to serial port                   */
/* Inputs      : Number of arguments, list of word arguments                */
/* Outputs     : Returns result of writeDataPacket                          */
/****************************************************************************/
    Int16
replyToCommand(Int16 nWords, ... )
{
    Int16   arg;                    /* Argument counter                     */
    va_list argPtr;                 /* Argument list pointer                */
    Byte    buffer[MAX_REPLY_WORDS * sizeof(Word)];
    Byte   *bufPtr = buffer;

    va_start(argPtr, nWords);       /* argPtr points to 1st unnamed argument*/

    for (arg = 0; arg < nWords; arg++)
    {
        *bufPtr++ = (Byte) ((*(Word *) argPtr) >> 8);   /* store high byte  */
        *bufPtr++ = (Byte) ((*(Word *) argPtr) & 0xff); /* store low byte   */
        va_arg(argPtr, Word*);      /* Point to next word pointer argument  */
    } /* for */

    va_end(argPtr);                 /* Cleanup var args stuff               */

                                    /**** Send Data Packet to Serial Port ***/
    return (writeDataPacket(buffer, nWords + nWords));
} /* replyToCommand() */

/****************************************************************************/
/* Function    : writeDataPacket                                            */
/* Purpose     : Applic. layer function to send a data packet               */
/* Inputs      : Buffer containing packet and packet length                 */
/* Outputs     : Returns ERROR or OK                                        */
/****************************************************************************/
    Int16
writeDataPacket(Byte *packet, Int16 packetLen)
{
    return (transmitDataPacket(packet, packetLen));
} /* writeDataPacket() */

/****************************************************************************/
/* Function    : writeSRQPacket                                             */
/* Purpose     : Applic. layer function to send a Service Request packet    */
/* Inputs      : Buffer containing packet and packet length                 */
/* Outputs     : Returns ERROR or OK                                        */
/****************************************************************************/
    Int16
writeSRQPacket(Byte *packet, Int16 packetLen)
{
    return (enqueueSRQPacket(packet, packetLen));
} /* writeSRQPacket() */

