/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  : MBARI Tailcone Application - Main C Source file               */
/* Filename : tailcone.c                                                    */
/* Author   : Andrew Pearce                                                 */
/* Project  : Dorado AUV Tailcone                                           */
/* Version  : 1.0                                                           */
/* Created  : 01/19/00                                                      */
/* Modified : 01/19/00                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/

#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 "applic.h"                     /* Microcontroller applications     */
#include "malloc.h"                     /* Malloc support routines          */
#include "applay.h"

#include "microdef.h"                   /* Microcontroller definitions      */
#include "microlib.h"                   /* Microcontroller Library decls.   */

#include "timer.h"                      /* Timer library definitions        */
#include "ring.h"                       /* Ring buffer support routines     */

#include "syslib.h"                     /* Board Support library decls.     */

#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 "filter.h"                     /* IBC General IIR Filter Routines  */

#include "cpu196.h"                     /* IBC 80C196 CPU Board functions   */
#include "pic.h"                        /* Intel 82C59 Interrupt Controller */

#include "low_pwr.h"                    /* Low Power Switch Board Defs      */
#include "quad_serial.h"                /* Quad Serial Board Definitions    */
#include "scc2698.h"                    /* Signetics SCC2698 UART Definition*/

#include "tailcone.h"                   /* Application specific definitions */
#include "stp100.h"                     /* Stepper Motor Controller         */
#include "sv203.h"                      /* Servo Motor Controller           */

/****************************************************************************/

const Char micro_id[] = "87C196KC Tailcone";
const Char softwareRev[] = "$Revision: 1.2 $";
const Char serialNumber[] = "Tailcone 01";
const Char *microSerialNo;

MLocal Boolean microEnabled;            /* Enables serial command processing*/

typedef IBC_BoardEntry * IBCCardPtr;

                                        /* Array of IBC boards in backplane */
IBCCardPtr IBC_CardTable[IBC_MAX_CARDS];
Int16   IBC_CardCount;                  /* IBC cards found in backplane     */

sv203Struct propMotor;                  /* Tailcone propeller motor struct  */
stpStruct   elevator;                   /* Tailcone elevator control surface*/
stpStruct   rudder;                     /* Tailcone rudder control surface  */

                                        /* Forward declarations             */

/****************************************************************************/
/* Function    : processApplicCommands                                      */
/* Purpose     : Decode application specific serial port commands           */
/* Inputs      : Command buffer and command buffer length                   */
/* Outputs     : Return TRUE if command recognized and processed, else FALSE*/
/****************************************************************************/
    MLocal Int16
processApplicCommands( Char *commandBuf, Int16 commandLen )
{
                                /* try to recognize the command and call    */
                                /* the appropriate handler                  */
    switch (wordFromBuf(commandBuf, 0))
    {
        default:
            return (FALSE);     /* Command not recognized return FALSE      */

    } /* switch */

    return (TRUE);              /* Command recognized & processed           */
} /* processApplicCommands() */

/****************************************************************************/
/* Function    : executeCommand                                             */
/* Purpose     : Check commands received from serial port and call handler  */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
executeCommand( Void )
{
#if 0

    Byte*   commandBuf;             /* Pointer to the command packet data.  */
    Int16   commandLen;             /* Length of the command packet data    */

                                    /* read a command from serial port      */
    while (readRecvdPacket(&commandBuf, &commandLen) == OK)
    {
        if ( wordFromBuf(commandBuf, 0) == (MICRO_APP | CMD_ENABLE) )
        {
            microEnabled = TRUE;
            replyToCommand(1, CMD_OK );
        } /* if */

        else if (microEnabled)
        {                           /* try to recognize the command and call*/
                                    /* the appropriate handler              */
            if ( processApplicCommands( commandBuf, commandLen ) == FALSE )

                if ( processIBCCommands ( IBC_CardTable, IBC_CardCount,
                                commandBuf, commandLen ) == FALSE )

                    processMicroCommands ( commandBuf, commandLen );
        } /* if */

        freeRecvdPacket(commandBuf);/* Free up the memory allocated for the */
                                    /* packet by readSerialPacket()         */
    } /* while */
#endif

} /* executeCommand() */

/****************************************************************************/
/* Function    : initializeAlarms                                           */
/* Purpose     : Initializes various alarm status and thresholds            */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
initializeAlarms( Void )
{

} /* initializeAlarms() */

    Int16
initializePropMotor(sv203Struct *propMotor, Nat16 serialChan)
{
    sv203OpenSerialChan(propMotor, (Byte*) QUAD_SERIAL_0_ADDR,
            serialChan, IBC_CardTable, IBC_CardCount );

    sv203BoardSelect(propMotor, 1);
    sv203ServoSelect(propMotor, 1);
} /* initializePropMotor() */

    Int16
initializeControlSurface(stpStruct *ctrlSurface, Nat16 serialChan)
{
    stp100OpenSerialChan(ctrlSurface, (Byte*) QUAD_SERIAL_0_ADDR,
            serialChan, IBC_CardTable, IBC_CardCount );

    stp100InitializeController(ctrlSurface, CTRL_SURFACE_CTRL_PERIOD);

    stp100FindHome(ctrlSurface);
    stp100StepDelay(ctrlSurface, 256);

    stp100VelocityProfile(ctrlSurface, 2000, 5);
} /* initializeControlSurface() */


    MLocal Void
switchOnActuators( Void )
{
    Int16 card;                       /* Card index into Card Table         */
    LPS_BoardEntry *lpsBoard;

    if ( (card = ibcBoardTableIndex(IBC_CardTable, IBC_CardCount,
        (Byte *) LOW_PWR_SWITCH_24V_0_ADDR, LOW_POWER_SWITCH) ) != ERROR)
    {
        lpsBoard = (LPS_BoardEntry *) IBC_CardTable[card];

                                      /* Switch Vicor Output On             */
        LPS_BoardVicorCtrl( lpsBoard, ON );
        LPS_BoardSwitch( lpsBoard, RUDDER_LPS_CHAN,     ON );
        LPS_BoardSwitch( lpsBoard, ELEVATOR_LPS_CHAN,   ON );
        LPS_BoardSwitch( lpsBoard, PROP_MOTOR_LPS_CHAN, ON );
     } /* if */

} /* switchOnActuators() */

/****************************************************************************/
/* Function    : mainLoop                                                   */
/* Purpose     : C main program called from assembler startup routine       */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
mainLoop( Void )
{
    char firmware[20];
    Byte position;
    Int16 psn, i;

    initIoport1();              /* Initialize Input/Output Port 1           */
    initIoport2();              /* Initialize Input/Output Port 2           */

    initMalloc();               /* Initialize Memory allocator              */
    initBoardStatus();          /* Initialize board status word             */

    microEnabled = FALSE;       /* Disabled processing of serial commands   */
    microSerialNo = serialNumber;

                                /* Initialize installed IBC Cards           */
    IBC_CardCount = IBC_initializeCards( IBC_CardTable, IBC_MAX_CARDS);

    initializeAlarms();         /* Initialize application specific alarms   */

    switchOnActuators();        /* Power up actuators                       */
                                /* Initialize propeller motor               */
    initializePropMotor(&propMotor, PROP_MOTOR_SER_CHAN);

#if 0
                                /* Initialize rudder control surface        */
    initializeControlSurface(&rudder, RUDDER_SER_CHAN);

#endif

                                /* Initialize rudder control surface        */
    initializeControlSurface(&elevator, ELEVATOR_SER_CHAN);

    i = 0;
    elevator.desiredPosition = 2000;

    FOREVER
    {
            stp100PositionControl(&elevator);
            if (i == 100)
                    elevator.desiredPosition = -2000;

            if (i++ == 200)
            {
                    i = 0;
                    elevator.desiredPosition = 2000;
            }
    }

    FOREVER
    {
        for (position = 122; position < 160; position++)
            sv203MoveAbsolute(&propMotor, position);

        taskDelay(10);

        for (position = 160; position > 122; position--)
            sv203MoveAbsolute(&propMotor, position);

        taskDelay(10);

        for (position = 122; position > 84; position--)
            sv203MoveAbsolute(&propMotor, position);

        taskDelay(10);

        for (position = 84; position < 122; position++)
            sv203MoveAbsolute(&propMotor, position);

        taskDelay(10);

    } /* forever */

    FOREVER
    {                           /* Repeat forever                           */
        executeCommand();       /* Process any commands from the VME CPU    */

                                /* Execute any IBC card specific functions  */
        IBC_CardFunctions( &(IBC_CardTable[0]), IBC_CardCount );

    } /* forever */
} /* mainLoop() */


