/****************************************************************************/
/* Copyright 1991 to 1993, MBARI                                            */
/****************************************************************************/
/* Summary  : IBC CPU Microcontroller Board - Hardware Support Functions    */
/* Filename : cpu196.c                                                      */
/* Author   : Andrew Pearce                                                 */
/* Project  : New ROV IBC Based Data Concentrator                           */
/* Version  : 1.0                                                           */
/* Created  : 05/05/92                                                      */
/* Modified : 11/05/93                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: /usr/tiburon/.cvsroot/micro/ibc/boards/cpu196/cpu196.c,v 1.2 1997/05/07 15:26:38 pean Exp $
 * $Log: cpu196.c,v $
 * Revision 1.2  1997/05/07 15:26:38  pean
 * Cleaned up Include files and makefile for new directory structure.
 *
 * Revision 1.1.1.1  1997/05/02 18:51:27  pean
 * Initial check in of IBC microcontroller software
 *
 * Revision 1.1  93/07/02  09:22:22  09:22:22  pean (Andrew Pearce)
 * Initial revision
 *
 * Revision 1.1  92/09/17  12:10:58  12:10:58  pean (Andrew Pearce)
 * Initial revision
 *
 * Revision 1.3  92/07/23 15:37:02 15:37:02  pean (Andrew Pearce 408-647-3746)
 * Fixed problem with ibcBusReadWord return status
 *
 * Revision 1.2  92/05/19 14:29:58 14:29:58  pean (Andrew Pearce 408-647-3746)
 * Added support for analog humidity sensor and 82C59 PIC
 *
 *
 * Revision 1.1  92/05/14 08:22:30 08:22:30  pean (Andrew Pearce 408-647-3746)
 * Initial revision
 *
*/
/****************************************************************************/

#pragma model(196)
#pragma nosignedchar

#include "C:/C96/INCLUDE/80C196.h"      /* 80C196 Register mapping          */
#include "C:/C96/INCLUDE/stddef.h"      /* C Standard Definitions           */
#include "const.h"                      /* Misc. constants - TRUE/FALSE etc */
#include "types.h"                      /* MBARI style guide declarations   */
#include "microdef.h"                   /* Microcontroller Definitions      */
#include "microlib.h"                   /* Microcontroller 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 "ibc_asm.h"                    /* IBC Assembly Language Functions  */
#include "cpu196.h"                     /* IBC CPU Board Functions          */
#include "pic.h"                        /* Intel 82C59 Interrupt Controller */
#include "applay.h"                     /* Application layer funcitions     */
#include "microCmd.h"                   /* Microcontroller commands         */

                                        /* Intel Interrupt Controller Addr  */
volatile Byte picBaseAddr;
volatile Byte picNextAddr;
volatile Byte picIntAckAddr;

#pragma locate(picBaseAddr   = PIC_BASE_ADDR)
#pragma locate(picNextAddr   = PIC_NEXT_ADDR)
#pragma locate(picIntAckAddr = PIC_INT_ACK_ADDR)

alarmParam humidityAlarm;               /* Humidity alarm                   */
MLocal IBC_BoardEntry cpu196Board;      /* CPU 196 Board Data Structure     */

                                        /* Forward declarations for MLocals */
MLocal Void ibcCpuInitializeAlarms( Void );

/****************************************************************************/
/* Function    : ibcBusReset                                                */
/* Purpose     : Assert IBC Bus Reset (INIT) signal for 20 milliseconds     */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
ibcBusReset( Void )
{
    writeIoport1(IBC_RESET_BIT, OR_PORT);   /* Set INIT to a 1              */
    taskDelay(2);                           /* Wait 20 milliseconds         */
    writeIoport1(~IBC_RESET_BIT, AND_PORT); /* Set INIT to a 0              */
} /* ibcBusReset() */

/****************************************************************************/
/* Function    : cpu196_BoardInit                                           */
/* Purpose     : IBC CPU196 Board Initialization routine                    */
/* Inputs      : Pointer to IBC Board Table, table size                     */
/* Outputs     : None                                                       */
/****************************************************************************/
    Int16
cpu196_BoardInit( IBC_BoardEntry *IBC_CardTable[], Int16 maxCards )
{
    if (maxCards <= 0)          /* No room in IBC Card Table                */
        return(0);              /* So return zero                           */

                                /* Fill out board entry structure           */
    cpu196Board.baseAddress = 0;
    cpu196Board.boardType   = CPU196;
    cpu196Board.intrLevel   = IBC_INT_LVL_OFF;

    ibcBusInitialize();         /* Initialize IBC Bus Timeout Functions     */
    ibcBusReset();              /* Bring IBC Bus out of power up reset state*/

    ibcCpuInitializeAlarms();   /* Initialize IBC CPU alarms                */

                                /* Add CPU196 data structure to IBC Table   */
    IBC_CardTable[0] = &cpu196Board;

    initializePIC();            /* Initialize CPU board Interrupt Controller*/

    return(1);                  /* Return number of boards "found"          */
} /* cpu196_BoardInit() */

    Void
cpu196_enableIbcIntr( Void )
{
    PIC_enable;                 /* Enable Interrupt from PIC to processor   */
} /* cpu196_initIbcIntr() */

    Void
IBC_BoardFindIntrLevel( IBC_BoardEntry *IBC_Board, Void (*boardIntrOn) (),
         Void (*boardIntrOff) () )
{
    Byte intLevel;
    Byte intStatus;
    Byte oldIntStatus;

    oldIntStatus = PIC_intStatus();     /* Read existing interrupt status   */
    boardIntrOn( IBC_Board );           /* Cause board to generate interrupt*/
                                        /* Calc interrupt status difference */
    intStatus = PIC_intStatus() ^ oldIntStatus;
    boardIntrOff( IBC_Board );          /* Clear board interrupt            */

    intLevel = -1;                      /* Convert bit vector to a level    */
    while (intStatus != 0)
    {
        intLevel++;
        intStatus = intStatus >> 1;
    } /* while */

    IBC_Board->intrLevel = intLevel;    /* Update Interrupt level entry     */
} /* IBC_BoardFindIntrLevel() */

/****************************************************************************/
/* Function    : ibcCpuInitializeAlarms                                     */
/* Purpose     : Initialize IBC CPU Alarm monitoring                        */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    MLocal Void
ibcCpuInitializeAlarms( Void )
{
    humidityAlarm.value            = 0;
    humidityAlarm.warnThresh       = HUMIDITY_WARN_THRESH;
    humidityAlarm.alarmThresh      = HUMIDITY_ALARM_THRESH;
    humidityAlarm.alarmStatus      = MICRO_ALARM_OK;
} /* ibcCpuInitializeAlarms() */

/****************************************************************************/
/* Function    : ibcCpuCheckHumidityAlarm                                   */
/* Purpose     : Monitor humidity sensor and check threshold                */
/* Inputs      : None                                                       */
/* Outputs     : None, but sends SRQ packet to serial port                  */
/****************************************************************************/
    MLocal Void
ibcCpuCheckHumidityAlarm( Void )
{                                   /* Read Humidity Sensor                 */
    humidityAlarm.value = readHumidity();

                                    /* Check if humidity has exceeded warn  */
                                    /* or alarm thresholds and send alarm   */
                                    /* SRQ's if necessary                   */
    if (alarmThresholdCheck(humidityAlarm.value,
            humidityAlarm.warnThresh, humidityAlarm.alarmThresh,
            HUMIDITY_HYSTERESIS, &humidityAlarm.alarmStatus ) == TRUE)

        writeServiceRequest(2, HUMIDITY_ALARM_SRQ, humidityAlarm.alarmStatus);
} /* ibcCpuCheckHumidityAlarm() */

/****************************************************************************/
/* Function    : cpu196_BoardFunctions                                      */
/* Purpose     : CPU196 board real-time loop functions                      */
/* Inputs      : CPU196 Board data structure                                */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
cpu196_BoardFunctions( IBC_BoardEntry *CPU196_Board )
{
    ibcCpuCheckHumidityAlarm();
} /* cpu196_BoardFunctions() */

