/****************************************************************************/
/* Copyright 1993 MBARI                                                     */
/****************************************************************************/
/* Summary  : Falmouth Sensor Function Library                              */
/* Filename : falmouth.c                                                    */
/* Author   : Andrew Pearce                                                 */
/* Project  : New ROV IBC Based Data Concentrator                           */
/* Version  : 1.0                                                           */
/* Created  : 09/30/93                                                      */
/* Modified : 09/30/93                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: /usr/tiburon/.cvsroot/micro/ibc/falmouth/falmouth.c,v 1.2 1997/05/07 15:40:14 pean Exp $
 * $Log: falmouth.c,v $
 * Revision 1.2  1997/05/07 15:40:14  pean
 * Cleaned up Include files and makefile for new directory structure.
 *
 * Revision 1.1.1.1  1997/05/02 18:51:46  pean
 * Initial check in of IBC microcontroller software
 *
*/
/****************************************************************************/

#pragma model(196)
#pragma nosignedchar

#include "C:/C96/INCLUDE/string.h"      /* string function library          */
#include "const.h"                      /* Misc. constants - TRUE/FALSE etc */
#include "types.h"                      /* MBARI style guide declarations   */
#include "microasm.h"                   /* Assembly language functions      */
#include "microdef.h"                   /* Microcontroller Definitions      */
#include "microlib.h"                   /* Microcontroller Library decls.   */
#include "malloc.h"                     /* Malloc support routines          */
#include "ring.h"                       /* Ring buffer support routines     */
#include "timer.h"                      /* Timer library definitions        */
#include "microCmd.h"                   /* microcontroller commands         */
#include "applay.h"                     /* Application layer funcitions     */

#include "ibc_card.h"                   /* IBC Board Types and Addresses    */
#include "ibc_cmd.h"                    /* Core IBC application definitions */
#include "ibc.h"                        /* IBC Function Library Definitions */
#include "cpu196.h"                     /* IBC 80C196 CPU Board functions   */
#include "pic.h"                        /* Intel 82C59 Interrupt Controller */

#include "quad_serial.h"                /* Quad Serial Board Definitions    */
#include "scc2698.h"                    /* Signetics SCC2698 UART Definition*/

#include "falmouth.h"                   /* Falmouth sensor data structures  */

#define LINE_FEED       0x0a
#define CARRIAGE_RET    0x0d

    MLocal Int16
falmouthCommand( quadSerialChan serialChan, const char* command )
{
    if  (serialChan.boardEntry)
    {
      if (strlen(command))
      {
        if (serialBoardWrite(serialChan.boardEntry, serialChan.channel,
                (Byte*) command, strlen(command) ))
        {
           serialBoardWrite(serialChan.boardEntry, serialChan.channel, "\n",1);
           return(OK);
        } /* if */
      } /* if */
      else
      {
           serialBoardWrite(serialChan.boardEntry, serialChan.channel, "\n",1);
           return(OK);
      } /* else */
    } /* if */

    return(ERROR);
} /* falmouthCommand() */

    Int16
falmouthSetMode( quadSerialChan serialChan, falmouthMode mode)
{
    switch ( mode )
    {
      case FALMOUTH_RUN_MODE:
        return (falmouthCommand(serialChan, "***R"));
        break;

      case FALMOUTH_OPEN_MODE:
        return (falmouthCommand(serialChan, "***O"));
        break;

      case FALMOUTH_CAL_MODE:
        return (falmouthCommand(serialChan, "***C"));
        break;

    } /* switch */

    return (ERROR);
} /* falmouthSetMode() */

    Int16
falmouthWriteEEPROM( quadSerialChan serialChan )
{
    return( falmouthCommand(serialChan, "***E") );
} /* falmouthWriteEEPROM() */

    Int16
falmouthReadEEPROM( quadSerialChan serialChan )
{
    return( falmouthCommand(serialChan, "***Q") );
} /* falmouthReadEEPROM() */


    Int16
falmouthSetRate( quadSerialChan serialChan, Nat16 updateRate )
{
    switch (updateRate)
    {
      default:
      case 4:
        return (falmouthCommand(serialChan, "ST=0"));
        break;

      case 10:
        return (falmouthCommand(serialChan, "ST=1"));
        break;

      case 15:
        return (falmouthCommand(serialChan, "ST=2"));
        break;

      case 25:
        return (falmouthCommand(serialChan, "ST=3"));
        break;

      case 32:
        return (falmouthCommand(serialChan, "ST=4"));
        break;
    } /* switch */

} /* falmouthSetRate() */


    Int16
falmouthReadData(falmouthSensor *sensor, Byte *buffer, Int16 maxLen)
{
    Int16  status;

    while (serialBoardTermRecvd(sensor->serialChan.boardEntry,
            sensor->serialChan.channel) )
    {
        if ( (status = serialBoardRead(sensor->serialChan.boardEntry,
            sensor->serialChan.channel, buffer, maxLen)) <= 0)

	    serialBoardRxFlush(sensor->serialChan.boardEntry,
                sensor->serialChan.channel );

	return(status);
    } /* while */

    return (status);
} /* falmouthReadData() */

    Int16
setupFalmouthSensor( falmouthSensor *sensor )
{
    falmouthSetMode( sensor->serialChan, FALMOUTH_OPEN_MODE);
    taskDelay(FALMOUTH_DELAY);

    falmouthCommand( sensor->serialChan, "CCOP");
    taskDelay(FALMOUTH_DELAY);

    falmouthCommand( sensor->serialChan, "CAOP");
    taskDelay(FALMOUTH_DELAY);

    falmouthCommand( sensor->serialChan, "CSOT");
    taskDelay(FALMOUTH_DELAY);

    falmouthCommand( sensor->serialChan, "SCOP");
    taskDelay(FALMOUTH_DELAY);

    falmouthSetRate( sensor->serialChan, 25);
    taskDelay(FALMOUTH_DELAY);

    falmouthWriteEEPROM( sensor->serialChan );
#if 0
    falmouthGetSerialNo( sensor->serialChan, sensor->serialNo );
    falmouthGetVersion(  sensor->serialChan, sensor->version  );
    falmouthCalDate(     sensor->serialChan, sensor->calDate  );
#endif

    falmouthSetMode( sensor->serialChan, FALMOUTH_RUN_MODE );
    taskDelay(FALMOUTH_DELAY);

    falmouthCommand( sensor->serialChan, "SC");

} /* setupFalmouthSensor()  */

    Int16
initFalmouthSensor( falmouthSensor *sensor, Byte* boardAddr, Nat16 chan,
    IBC_BoardEntry *IBC_CardTable[], Int16 cardCount )
{
    Int16 serialCard;           /* Serial Card index into IBC Card Table    */

    sensor->integer  = 0;
    sensor->fraction = 0;

    sensor->serialChan.boardEntry = (serialBoardEntry*) NULL;

                                /* Find card index of serial board in table */
    if ( (serialCard = ibcBoardTableIndex(IBC_CardTable, cardCount,
         boardAddr, QUAD_SERIAL) ) == ERROR)
        return (ERROR);

    sensor->serialChan.boardEntry =
         (serialBoardEntry*) IBC_CardTable[serialCard];

    sensor->serialChan.channel = chan;

    serialBoardOpenChan(sensor->serialChan.boardEntry, chan);
    sccSetLineFormat(sensor->serialChan.boardEntry, chan,
             9600, 8, 1, 2, HANDSHAKE_OFF, RS485_MODE);

     return(OK);
} /* initFalmouthSensor() */


    Void
readFalmouthSensorValue( falmouthSensor *sensor )
{
    Int16 blen;                     /* Length of reply string from sensor   */
    Byte  *digitPtr;                /* Points to digits in reply string     */
    Byte  *ptr;                     /* Points to characters in reply string */
    Byte  buffer[FALMOUTH_BUF_LEN];

    bzero((Byte*) buffer, (Nat16) FALMOUTH_BUF_LEN);

    if ((blen = falmouthReadData(sensor, buffer, FALMOUTH_BUF_LEN)) > 0)
    {                               /* We go to some pain to validate string*/
                                    /* Look for Carriage Return / Line Feed */
        if ((buffer[blen - 2] != CARRIAGE_RET) ||
            (buffer[blen - 1] != LINE_FEED))
            return;                 /* Check that string is CR/LF Terminated*/

        buffer[blen - 2] = '\0';    /* Replace CR/LF with NULL              */

        ptr = buffer;               /* Point to start of buffer             */
        if ((*ptr != ' ') && (*ptr != '+') && (*ptr !='-'))
            return;                 /* Number must start with space,+ or -  */

                                    /* Check for valid numeric characters   */
        for (digitPtr = ptr + 1; *digitPtr != '\0'; digitPtr++)
        {
            if ( (*digitPtr < '0') || (*digitPtr > '9'))
            {
                if (*digitPtr != '.')
                    return;
            } /* if */
        } /* for */

        blen = blen - 2;            /* Subtract 2 for CR/LF                 */
                                    /* Look for decimal point in position 5 */
        if ( *(ptr + blen - 5) != '.')
                return;

        *(ptr + blen - 5) = '\0';   /* Replace decimal point with NULL      */
        sensor->integer  = atoi(ptr);             /* Get Integer portion    */
        sensor->fraction = atoi(ptr + blen - 4);  /* Get Fractional portion */

    } /* if */
} /* readFalmouthSensorValue() */


   Int16
triggerFalmouthSensor(falmouthSensor *sensor)
{
   if (sensor->serialChan.boardEntry == (serialBoardEntry *) NULL)
        return(0);

   falmouthCommand(sensor->serialChan, "");     /* Null string requests data*/
} /* triggerFalmouthSensor() */

