/*****************************************************************************
*
*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*       FOR A PARTICULAR PURPOSE.
*
*       (c) Copyright 2002 Xilinx Inc.
*       All rights reserved.
*
*****************************************************************************/
/*****************************************************************************/
/**
*
* @file xps2.h
*
* This driver supports the following features:
*
* - Polled mode
* - Interrupt driven mode
*
* <b>Interrupts</b>
*
* The device does not have any way to disable the receiver such that the
* receiver may contain unwanted data. The IP is reset driver is initialized, 
*
* The driver defaults to no interrupts at initialization such that interrupts
* must be enabled if desired. An interrupt is generated for any of the following
* conditions.
*
* - Data in the receiver
* - Any receive status error detected
* - Data byte transmitted
* - Any transmit status error detected
*
* The application can control which interrupts are enabled using the SetOptions
* function.
*
* In order to use interrupts, it is necessary for the user to connect the 
* driver interrupt handler, XPs2_InterruptHandler(), to the interrupt system of
* the application. This function does not save and restore the processor 
* context such that the user must provide it. A handler must be set for the 
* driver such that the handler is called when interrupt events occur. The
* handler is called from interrupt context and is designed to allow application
*  specific processing to be performed.
*
* The functions, XPs2_Send() and Ps2_Recv(), are provided in the driver to
* allow data to be sent and received. They are designed to be used in polled 
* or interrupt modes.
*
* @note
*
* None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ch   06/18/02 First release
* </pre>
*
******************************************************************************/

#ifndef XPS2_H /* prevent circular inclusions */
#define XPS2_H /* by using protection macros */

/***************************** Include Files ********************************/

#include "xbasic_types.h"
#include "xstatus.h"
#include "xps2_l.h"

/************************** Constant Definitions ****************************/

/* 
 * These constants specify the handler events that are passed to
 * a handler from the driver. These constants are not bit masks suuch that 
 * only one will be passed at a time to the handler
 */
#define XPS2_EVENT_RECV_DATA    1
#define XPS2_EVENT_RECV_ERROR   2
#define XPS2_EVENT_RECV_OVF     3
#define XPS2_EVENT_SENT_DATA    4
#define XPS2_EVENT_SENT_NOACK   5
#define XPS2_EVENT_TIMEOUT      6

/*
 * These constants specify the errors  that may be retrieved from the driver
 * using the XPs2_GetLastErrors function. All of them are bit masks, except
 * no error, such that multiple errors may be specified.
 */
#define XPS2_ERROR_NONE            0x00
#define XPS2_ERROR_WDT_TOUT_MASK   0x01
#define XPS2_ERROR_TX_NOACK_MASK   0x02
#define XPS2_ERROR_RX_OVF_MASK     0x08
#define XPS2_ERROR_RX_ERR_MASK     0x10

/**************************** Type Definitions ******************************/

/*
 * This typedef contains configuration information for the device
 */
typedef struct
{
    Xuint16 DeviceId;       /* Unique ID  of device */
    Xuint32 BaseAddress;    /* Base address of device */
} XPs2_Config;

/*
 * The following data type is used to manage the buffers that are handled
 * when sending and receiving data in the interrupt mode
 */
typedef struct
{
    Xuint8 *NextBytePtr;
    unsigned int RequestedBytes;
    unsigned int RemainingBytes;
} XPs2Buffer;

/*
 * This data type defines a handler which the application must define
 * when using interrupt mode.  The handler will be called from the driver in an
 * interrupt context to handle application specific processing.
 *
 * @param CallBackRef is a callback reference passed in by the upper layer
 *        when setting the handler, and is passed back to the upper layer when
 *        the handler is called.
 * @param Event contains one of the event constants indicating why the handler
 *        is being called.
 * @param EventData contains the number of bytes sent or received at the time 
*         of the call.
*/
typedef void (*XPs2_Handler)(void *CallBackRef, Xuint32 Event, 
                             unsigned int EventData);
/*
 * PS/2 statistics
 */
typedef struct
{
    Xuint16 TransmitInterrupts;
    Xuint16 ReceiveInterrupts;
    Xuint16 CharactersTransmitted;
    Xuint16 CharactersReceived;
    Xuint16 ReceiveErrors;
    Xuint16 ReceiveOverflowErrors;
    Xuint16 TransmitErrors;
} XPs2Stats;

/*
 * The PS/2 driver instance data. The user is required to allocate a
 * variable of this type for every PS/2 device in the system.     
 * If the last byte of a message was received then call the application
 * handler, this code should not use an else from the previous check of
 * the number of bytes to receive because the call to receive the buffer
 * updates the bytes to receive
 * A pointer to a variable of this type is then passed to the driver API
 * functions
 */
typedef struct
{
    XPs2Stats Stats;            /* Component Statistics */
    Xuint32 BaseAddress;        /* Base address of device (IPIF) */
    Xuint32 IsReady;            /* Device is initialized and ready */
    Xuint8  LastErrors;         /* the accumulated errors */

    XPs2Buffer SendBuffer;
    XPs2Buffer ReceiveBuffer;

    XPs2_Handler Handler;
    void *CallBackRef;           /* Callback reference for control handler */
} XPs2;

/***************** Macros (Inline Functions) Definitions ********************/

/************************** Function Prototypes *****************************/

/*
 * required functions is xps2.c
 */
XStatus XPs2_Initialize(XPs2 *InstancePtr, Xuint16 DeviceId);

unsigned int XPs2_Send(XPs2 *InstancePtr, Xuint8 *BufferPtr,
                       unsigned int NumBytes);
unsigned int XPs2_Recv(XPs2 *InstancePtr, Xuint8 *BufferPtr,
                       unsigned int NumBytes);
XPs2_Config *XPs2_LookupConfig(Xuint16 DeviceId);

/*
 * options functions in xps2_options.c
 */
Xuint8 XPs2_GetLastErrors(XPs2 *InstancePtr);
Xboolean XPs2_IsSending(XPs2 *InstancePtr);

/*
 * interrupt functions in xps2_intr.c
 */
void XPs2_SetHandler(XPs2 *InstancePtr, XPs2_Handler FuncPtr,
                     void *CallBackRef);
void XPs2_InterruptHandler(XPs2 *InstancePtr);
void XPs2_EnableInterrupt(XPs2 *InstancePtr);
void XPs2_DisableInterrupt(XPs2 *InstancePtr);

#endif            /* end of protection macro */
