/*  ============================================================================
 *   Copyright (c) Texas Instruments Inc 2002, 2003, 2004, 2005
 *
 *   Use of this software is controlled by the terms and conditions found
 *   in the license agreement under which this software has been supplied.
 *   ===========================================================================
 */

/** @mainpage SPI
*
* @section Introduction
*
* @subsection xxx Purpose and Scope
* The purpose of this document is to identify a set of common CSL APIs for
* the SPI Module across various devices. The CSL developer is expected
* to refer to this document while designing APIs for these modules. Some
* of the listed APIs may not be applicable to a given SPI Module. While
* in other cases this list of APIs may not be sufficient to cover all the
* features of a particular SPI Module. The CSL developer should use his
* discretion in designing new APIs or extending the existing ones to cover
* these.
*
*
* @subsection aaa Terms and Abbreviations
*   -# CSL:  Chip Support Library
*   -# API:  Application Programmer Interface
*   -# SPI:  Serial Port Interface
*
* @subsection References
*    -# CSL 3.x Technical Requirements Specifications Version 0.5, dated
*       May 14th, 2003
*
*/

/** @file csl_spi.h
 *
 * @brief   Header file for functional layer of CSL
 *
 * Description
 *    - The defines inline function definitions
 *
 */

#ifndef _CSL_SPI_H_
#define _CSL_SPI_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <cslr.h>
#include <csl_error.h>
#include <csl_types.h>
#include <soc.h>
#include <cslr_spi.h>

/**************************************************************************\
* SPI global macro declarations
\**************************************************************************/


/**************************************************************************\
* SPI global typedef declarations
\**************************************************************************/

/** @brief Enumeration for control commands passed to @a CSL_spiHwControl()
 *
 * This is the set of commands that are passed to the @a CSL_spiHwControl()
 * with an optional argument type-casted to @a void* . The arguments to be
 * passed with each enumeration if any are specified next to the enumeration */
typedef enum {
	/**
	* @brief   reset the SPI
	* @param   (None)
	*/
	CSL_SPI_CMD_PRI_RESET       =  1,

	/**
	* @brief   enable DMA transaction capability for DMA in compatibility mode
	* @param   (None)
	*/
	CSL_SPI_CMD_CPT_DMA_ENABLE  =  2,

	/**
	* @brief   enable DMA transaction capability for DMA in compatibility mode
	* @param   (None)
	*/
	CSL_SPI_CMD_CPT_DMA_DISABLE =  3,

	/**
	* @brief   write data in argument to SPIDAT0 register for transmitting out
	* @param   Uint16*
	*/
	CSL_SPI_CMD_CPT_WRITE0      =  4,

	/**
	* @brief   write data in argument to SPIDAT1 register for transmitting out
	* @param   Uint16*
	*/
	CSL_SPI_CMD_CPT_WRITE1      =  5,

	/**
	* @brief   read the data in SPIBUF register to the argument
	* @param   CSL_SpiCptData*
	*/
	CSL_SPI_CMD_CPT_READ        =  6,

	/**
	* @brief   enable the interrupts in the bit-vector argument
	* @param   Uint16*
	*/
	CSL_SPI_CMD_INT_ENABLE      =  7,

	/**
	* @brief   disable the interrupts in the bit-vector argument
	* @param   Uint16*
	*/
	CSL_SPI_CMD_INT_DISABLE     =  8,

	/**
	* @brief   set value passed in argument over pins configured as GPIO
	* @param   Uint16*
	*/
	CSL_SPI_CMD_PINS_VALUE      =  9,

	/**
	* @brief   set pins passed in bit-vector argument if configured as GPIO
	* @param   Uint16*
	*/
	CSL_SPI_CMD_PINS_SET        =  10,

	/**
	* @brief   clear pins passed in bit-vector argument if configured as GPIO
	* @param   Uint16*
	*/
	CSL_SPI_CMD_PINS_CLEAR      =  11,

	/**
	* @brief   enable the data-transfer section of the SPI
	* @param   (None)
	*/
	CSL_SPI_CMD_XFER_ENABLE     =  12,
	/**
	* @brief   disable the data-transfer section of the SPI
	* @param   (None)
	*/
	CSL_SPI_CMD_XFER_DISABLE    =  13
} CSL_SpiHwControlCmd;


/** @brief Enumeration for queries passed to @a CSL_spiGetHwStatus()
 *
 * This is used to get the status of different operations or to get the
 * existing setup of SPI. The arguments to be passed with each enumeration
 * if any are specified next to the enumeration */
typedef enum {
	/**
	* @brief   get the value present on the pins as a bit-vector
	* @param   Uint16*
	*/
	CSL_SPI_QUERY_PINS_VALUE        =  1,

	/**
	* @brief   get value of highest priority int that has occured on INT0 line
	* @param   CSL_SpiMbfInt*
	*/
	CSL_SPI_QUERY_INT_VECTOR0       =  2,

	/**
	* @brief   get value of highest priority int that has occured on INT1 line
	* @param   CSL_SpiMbfInt*
	*/
	CSL_SPI_QUERY_INT_VECTOR1       =  3,
                                        
	/**
	* @brief   get value of Flag status register
	* @param   Uint8t*
	*/    
    CSL_SPI_QUERY_EVT_STATUS        =  4,

	/**
	* @brief   get the bit-vector of interrupts that have been enabled
	* @param   Uint16*
	*/
	CSL_SPI_QUERY_INT_ENABLED       =  5,

	/**
	* @brief   get the status of whether DMA is enabled in compatibility mode
	* @param   CSL_SpiCptDma*
	*/
	CSL_SPI_QUERY_CPT_DMA_ENABLED   =  6
} CSL_SpiHwStatusQuery;

/** @brief enumeration for Spi general interrupts */
typedef enum {
	/** interrupt on successful receive */
	CSL_SPI_INT_RX       =  CSL_FMKT(SPI_SPIINT0_RXINTEN, ENABLE),
	/** interrupt on receiver overrun */
	CSL_SPI_INT_OVRN     =  CSL_FMKT(SPI_SPIINT0_OVRNINTEN, ENABLE),
	/** interrupt on bit error */
	CSL_SPI_INT_BITERR   =  CSL_FMKT(SPI_SPIINT0_BITERRENA, ENABLE),
	/** interrupt on loss of synchronization between master & slave */
	CSL_SPI_INT_DESYNC   =  CSL_FMKT(SPI_SPIINT0_DESYNCENA, ENABLE),
	/** interrupt on timeout error */
	CSL_SPI_INT_TIMEOUT  =  CSL_FMKT(SPI_SPIINT0_TIMEOUTENA, ENABLE)
} CSL_SpiInt;


/** @brief enumeration for Spi status bits */
typedef enum {
	/** indicates that a word has been received in SPIBUF */
	CSL_SPI_BUFSTATUS_RXINT   =  (1 << 7),
	/** indicates that receive BUF is empty */
	CSL_SPI_BUFSTATUS_RXEPTY  =  (1 << 6),
	/** indicates that overrun occured/not */
	CSL_SPI_BUFSTATUS_RXOVRN  =  (1 << 5),
	/** indicates that transmit BUF is full */
	CSL_SPI_BUFSTATUS_TXFULL  =  (1 << 4),
	/** indicates that a bit error occurred during transaction */
	CSL_SPI_BUFSTATUS_BITERR  =  (1 << 3),
	/** indicates that desynchronization with slave detected */
	CSL_SPI_BUFSTATUS_DESYNC  =  (1 << 2),
	/** indicates timeout */
	CSL_SPI_BUFSTATUS_TMOUT   =  (1 << 0)
} CSL_SpiBufStatus;


/** @brief enumeration to hold the chip select active between 2 transfers */
typedef enum {
	/** hold chip select active between consecutive transfers */
	CSL_SPI_CSHOLD_YES  =  CSL_SPI_SPIDAT1_CSHOLD_YES,
	/** chip select to be inactivated after the each transfer */
	CSL_SPI_CSHOLD_NO   =  CSL_SPI_SPIDAT1_CSHOLD_NO
} CSL_SpiCsHold;


/** @brief enumeration to control applying the format delay to consecutive
 * transfers */
typedef enum {
	/** enable format delay between 2 consecutive transfers */
	CSL_SPI_WDELAYEN_YES  =  CSL_SPI_SPIDAT1_WDEL_DELAY,
	/** disable format delay between 2 consecutive transfers */
	CSL_SPI_WDELAYEN_NO   =  CSL_SPI_SPIDAT1_WDEL_NODELAY
} CSL_SpiWDelayEn;


/** @brief enumeration to select the required data transfer format */
typedef enum {
	/** select format 0 */
	CSL_SPI_FMTSEL_0  =  CSL_SPI_SPIDAT1_DFSEL_FMT0,
	/** select format 1 */
	CSL_SPI_FMTSEL_1  =  CSL_SPI_SPIDAT1_DFSEL_FMT1,
	/** select format 2 */
	CSL_SPI_FMTSEL_2  =  CSL_SPI_SPIDAT1_DFSEL_FMT2,
	/** select format 3 */
	CSL_SPI_FMTSEL_3  =  CSL_SPI_SPIDAT1_DFSEL_FMT3
} CSL_SpiFmtSel;


/** @brief enumeration to control the dependence of transfer in ENA signal in
 * master mode */
typedef enum {
	/** if in master mode; wait for ENA signal from slave */
	CSL_SPI_WAITEN_YES  =  CSL_SPI_SPIFMT_WAITENA_YES,
	/** do not wait for ENA signal from slave */
	CSL_SPI_WAITEN_NO   =  CSL_SPI_SPIFMT_WAITENA_NO
} CSL_SpiWaitEn;


/** @brief enumeration to control the polarity of serial clock */
typedef enum {
	/** clock is low when inactive */
	CSL_SPI_POLARITY_INACTIVELO = CSL_SPI_SPIFMT_POLARITY_INACTIVELO,
	/** clock is high when inactive */
	CSL_SPI_POLARITY_INACTIVEHI = CSL_SPI_SPIFMT_POLARITY_INACTIVEHI
} CSL_SpiClkPolarity;


/** @brief enumeration to control phase relationship between data & clock */
typedef enum {
	/** data & clock in phase */
	CSL_SPI_PHASE_IN   =  CSL_SPI_SPIFMT_PHASE_IN,
	/** data 1/2 cycle before clock */
	CSL_SPI_PHASE_OUT  =  CSL_SPI_SPIFMT_PHASE_OUT
} CSL_SpiClkPhase;


/** @brief enumeration to control direction of the word during transfer */
typedef enum {
	/** transfer MSB first */
	CSL_SPI_SHDIR_MSBFIRST  =  CSL_SPI_SPIFMT_SHIFTDIR_MSBFIRST,
	/** transfer LSB first */
	CSL_SPI_SHDIR_LSBFIRST  =  CSL_SPI_SPIFMT_SHIFTDIR_LSBFIRST
} CSL_SpiShDir;


/** @brief enumeration tocontrol the operating mode of Spi */
typedef enum {
	/** operate as master */
	CSL_SPI_OPMOD_MASTER  =  ((CSL_SPI_SPIGCR1_CLKMOD_MASTERMODE << 1) |
				 CSL_SPI_SPIGCR1_MASTER_YES),
	/** operate as slave */
	CSL_SPI_OPMOD_SLAVE   =  ((CSL_SPI_SPIGCR1_CLKMOD_SLAVEMODE << 1) |
				 CSL_SPI_SPIGCR1_MASTER_NO)
} CSL_SpiOpMod;


/** @brief enumeration to control the SPIENA status when inactive */
typedef enum {
	/** force SPIENA signal high-z when inactive */
	CSL_SPI_ENAHIZ_YES  =  CSL_SPI_SPIINT0_ENABLEHIGHZ_ENABLE,
	/** keep SPIENA signal a value when inactive */
	CSL_SPI_ENAHIZ_NO   =  CSL_SPI_SPIINT0_ENABLEHIGHZ_DISABLE
} CSL_SpiEnaHiZ;


typedef enum {
	/* operate on functionality register */
	CSL_SPI_GPIOTYPE_FUNC      =  0,
	/* operate on direction register */
	CSL_SPI_GPIOTYPE_DIR       =  1
} CSL_SpiGpioType;


/** @brief enumeartion for Spi serial communication pins */
typedef enum {
	/** SOMI pin */
	CSL_SPI_PINTYPE_SOMI  =  CSL_FMKT(SPI_SPIPC0_SOMIFUN, SPI),
	/** SIMO pin */
	CSL_SPI_PINTYPE_SIMO  =  CSL_FMKT(SPI_SPIPC0_SIMOFUN, SPI),
	/** CLK pin */
	CSL_SPI_PINTYPE_CLK   =  CSL_FMKT(SPI_SPIPC0_CLKFUN, SPI),
	/** ENA pin */
	CSL_SPI_PINTYPE_ENA   =  CSL_FMKT(SPI_SPIPC0_ENABLEFUN, SPI),
	/** SCS pin */
	CSL_SPI_PINTYPE_SCS  =  CSL_FMKT(SPI_SPIPC0_SCSFUN0, SPI)
} CSL_SpiPinType;


/** @brief enumeration to control DMA enabling in compatibility mode */
typedef enum {
	/** enable dma servicing in compatibility mode */
	CSL_SPI_CPTDMA_ENABLE   =  CSL_SPI_SPIINT0_DMAREQEN_ENABLE,
	/** disable dma servicing in compatibility mode */
	CSL_SPI_CPTDMA_DISABLE  =  CSL_SPI_SPIINT0_DMAREQEN_DISABLE
} CSL_SpiCptDma;


/** @brief enumeration to control reset of transfer mechnism of Spi */
typedef enum {
	/** enable spi to begin transfers */
	CSL_SPI_XFEREN_DISABLE  =  CSL_SPI_SPIGCR1_ENABLE_DISABLE,
	/** hold spi transfer mechanism in reset */
	CSL_SPI_XFEREN_ENABLE   =  CSL_SPI_SPIGCR1_ENABLE_ENABLE
} CSL_SpiXferEn;


/** @brief this object contains the reference to the instance of SPI
 * opened using the @a CSL_spiOpen()
 *
 * An object related to this structure is passed to all SPI CSL APIs
 * as the first argument */
typedef struct CSL_SpiObj {
	/** This is a pointer to the registers of the instance of SPI referred
	* to by this object */
	CSL_SpiRegsOvly  regs;
	/** This is the instance of SPI being referred to by this object */
	CSL_InstNum       perNum;
} CSL_SpiObj;


/** @brief This will have the base-address information for the peripheral
 *  instance
 */
typedef struct {
	/** Base-address of the Configuration registers of SPI.
	*/
	CSL_SpiRegsOvly regs;
} CSL_SpiBaseAddress;

/** @brief SPI specific parameters. Present implementation doesn't have
 *  any specific parameters.
 */
typedef struct {
	/** Bit mask to be used for module specific parameters.
	*  The below declaration is just a place-holder for future
	*  implementation.
	*/
	CSL_BitMask16   flags;
} CSL_SpiParam;

/** @brief SPI specific context information. Present implementation doesn't
 *  have any Context information.
 */

typedef struct {
	/** Context information of SPI.
	*  The below declaration is just a place-holder for future
	*  implementation.
	*/
	Uint16  contextInfo;
} CSL_SpiContext;


typedef struct  {
	volatile Uint32 SPIGCR0;
	volatile Uint32 SPIGCR1;
	volatile Uint32 SPIINT0;
	volatile Uint32 SPILVL;
	volatile Uint32 SPIFLG;
	volatile Uint32 SPIPC0;
	volatile Uint32 SPIPC1;
	volatile Uint32 SPIPC2;
	volatile Uint32 SPIPC3;
	volatile Uint32 SPIPC4;
	volatile Uint32 SPIPC5;
	volatile Uint32 SPIDAT0;
	volatile Uint32 SPIDAT1;
	volatile Uint32 SPIBUF;
	volatile Uint32 SPIEMU;
	volatile Uint32 SPIDELAY;
	volatile Uint32 SPIDEF;
	volatile Uint32 SPIFMT[4];
	volatile Uint32 TGINTVEC[2];
} CSL_SpiConfig;

/** Default Values for Config structure */
#define CSL_SPI_CONFIG_DEFAULTS {     \
        CSL_SPI_SPIGCR0_RESETVAL,     \
        CSL_SPI_SPIGCR1_RESETVAL,     \
        CSL_SPI_SPIINT0_RESETVAL,     \
        CSL_SPI_SPILVL_RESETVAL,      \
        CSL_SPI_SPIFLG_RESETVAL,      \
        CSL_SPI_SPIPC0_RESETVAL,      \
        CSL_SPI_SPIPC1_RESETVAL,      \
        CSL_SPI_SPIPC2_RESETVAL,      \
        CSL_SPI_SPIPC3_RESETVAL,      \
        CSL_SPI_SPIPC4_RESETVAL,      \
        CSL_SPI_SPIPC5_RESETVAL,      \
        CSL_SPI_SPIDAT0_RESETVAL,     \
        CSL_SPI_SPIDAT1_RESETVAL,     \
        CSL_SPI_SPIBUF_RESETVAL,      \
        CSL_SPI_SPIEMU_RESETVAL       \
        CSL_SPI_SPIDELAY_RESETVAL,    \
        CSL_SPI_SPIDEF_RESETVAL,      \
        CSL_SPI_SPIFMT_RESETVAL,      \
        CSL_SPI_TGINTVEC_RESETVAL     \
}

/** @brief a pointer to @a CSL_SpiObj; this is passed to all SPI CSL
 * APIs */
typedef struct CSL_SpiObj *CSL_SpiHandle;


/** @brief sets up the properties if the pins of Spi
 *
 * This object is used to setup or get the setup of the pins in Spi */
typedef struct CSL_SpiHwSetupPins {
	/** decides if the pins will be Spi or GPIO */
	Uint16  func;
	/** if GPIO, decides the directions of the pins */
	Uint16  dir;
} CSL_SpiHwSetupPins;


/** @brief sets up the format selection for a set of transfers
 *
 * This object is used to setup or get the setup of the format selection
 * for a set of transfers */
typedef struct CSL_SpiHwSetupFmtCtrl {
	/** decides if chip select is to be held active between transfers */
	CSL_SpiCsHold    csHold;
	/** decides if delay specified in the selected format must be allowed
	* between 2 consecutive transfers */
	CSL_SpiWDelayEn  wDel;
	/** decides which format to select */
	CSL_SpiFmtSel    fmtSel;
	/** defines the chip select that will be activated for the transfer */
	Uint8               cSel;
} CSL_SpiHwSetupFmtCtrl;


/** @brief sets up the Spi for compatibility mode
 *
 * This structure is used to setup or get the setup of Spi in comaptibility
 * mode */
typedef struct CSL_SpiHwSetupCpt {
	/** selects if interrupts should go to lines INT0 or INT1 */
	Uint32                    *lvl;
	/** selects the format & associated controls */
	CSL_SpiHwSetupFmtCtrl  *fmtCtrlPtr;
} CSL_SpiHwSetupCpt;


/** @brief sets up the a formatting for an outgoing word
 *
 * This object is used to set up or get the setup of the format registers in
 * Spi */
typedef struct CSL_SpiHwSetupPriFmt {
	/** delay between 2 consecutive words */
	Uint8             wDelay;
	/** the factor with which to multiply functional clock in order to get the
	* serial clock */
	Uint8             preScale;
	/** the length of the word to be transmitted and/or received */
	Uint8             charLen;
	/** if in master mode; whether Spi should wait for ENA from slave */
	CSL_SpiWaitEn  waitEna;
	/** whether clock should be high or low when inactive */
	CSL_SpiClkPolarity  polarity;
	/** whether data should be in phase of 1/2 cycle ahead of the clock */
	CSL_SpiClkPhase   phase;
	/** whether LSB or MSB should be shifted first */
	CSL_SpiShDir   shiftDir;
} CSL_SpiHwSetupPriFmt;


/** @brief sets up the parameters to be setup in priority mode
 *
 * This object is used to setup or get the setup of the parameters to be setup
 * in priority mode */
typedef struct CSL_SpiHwSetupPri {
	/** array of pointers to structures of formats of an outgoing word */
	CSL_SpiHwSetupPriFmt  *fmt[4];
} CSL_SpiHwSetupPri;


/** @brief sets up the parameters that are needed by multi-buffer as well as
 * compatibility modes
 *
 * This objetc is used to set up or get the setup of parameters that are needed
 * by multi-buffer as well as compatibility modes */
typedef struct CSL_SpiHwSetupGen {
	/** master or slave mode */
	CSL_SpiOpMod      opMode;
	/** whether ENA signal should be tristated when inactive or if it should
	* bear a value */
	CSL_SpiEnaHiZ     enaHiZ;
	/** the default value on Chip select when inactive */
	Uint8                csDefault;
	/** Chip-select-active-to-transmit-start-delay */
	Uint8                c2tDelay;
	/** Transmit-end-to-chip-select-inactive-delay */
	Uint8                t2cDelay;
	/** Transmit-data-finished-to-ENA-pin-inactive-time-out */
	Uint8                t2eTmout;
	/** Chip-select-active-to-ENA-signal-active-time-out */
	Uint8                c2eTmout;
} CSL_SpiHwSetupGen;


/** @brief main structure that is used to setup the SPI
 *
 * This structure is used to setup or obtain the existing setup of SPI
 * using @a CSL_spiHwSetup() & @a CSL_spiGetHwStatus() functions
 * respectively. If a particular member pointer is null, then these functions
 * do not setup or get the setup of the corresponding part of SPI
 * respectively */
typedef struct CSL_SpiHwSetup {
	/** This pointer to @a CSL_SpiHwSetupCommon is used to hold
	* information on the common part of the SPI setup */
	CSL_SpiHwSetupGen   *genPtr;
	/** This pointer to @a CSL_SpiHwSetupFifo is used to hold information
	* on the data FIFO part of the SPI setup */
	CSL_SpiHwSetupPri   *priPtr;
	/** This pointer to @a CSL_SpiHwSetupSdio is used to hold information
	* on the SDIO part of the SPI setup */
	CSL_SpiHwSetupCpt   *cptPtr;
	/** This pointer to @a CSL_SpiHwSetupSdio is used to hold information
	* on the SPI part of the SPI setup */
	CSL_SpiHwSetupPins  *pinsPtr;
} CSL_SpiHwSetup;


/** @brief gets the information for interrupt vectors */
typedef struct CSL_SpiIntVec {
	/** interrupt vector number */
	Uint8  intVal;
} CSL_SpiIntVec;


/** @brief gets the status of buffer after a transfer */
typedef struct CSL_SpiBufStat {
	/** status as a bit-vector of the different events */
	Uint8  status;
} CSL_SpiBufStat;


typedef struct CSL_SpiCptData {
	/** Place to hold the data */
	Uint16            data;
	/** Place to hold the status */
	CSL_SpiBufStat *bufStat;
} CSL_SpiCptData;


/** default setting for @a CSL_SpiHwSetup */
#define CSL_SPI_HWSETUP_DEFAULTS { 		\
	NULL,                             	\
	NULL,                             	\
	NULL,                             	\
	NULL                              	\
}


/** default setting for @a CSL_SpiHwSetupGen */
#define CSL_SPI_HWSETUP_GEN_DEFAULTS {		\
	CSL_SPI_OPMOD_SLAVE,               	\
	CSL_SPI_ENAHIZ_NO,                 	\
	0,                                  	\
	0,                                  	\
	0,                                  	\
	0,                                  	\
	0                                   	\
}


/** default setting for @a CSL_SpiHwSetupPri */
#define CSL_SPI_HWSETUP_PRI_DEFAULTS { 	\
	NULL,                           \
	NULL,                           \
	NULL,                           \
	NULL                            \
}
	

/** default setting for @a CSL_SpiHwSetupPriFmt */
#define CSL_SPI_HWSETUP_PRI_FMT_DEFAULTS { \
	0,                                     \
	0,                                     \
	0,                                     \
	CSL_SPI_WAITEN_NO,                     \
	CSL_SPI_PHASE_IN,                      \
	CSL_SPI_SHDIR_LSBFIRST                 \
}


/** default setting for @a CSL_SpiHwSetupCpt */
#define CSL_SPI_HWSETUP_CPT_DEFAULTS { 		\
	NULL,                             	\
	NULL                                	\
}


/** default setting for @a CSL_SpiHwSetupFmtCtrl */
#define CSL_SPI_HWSETUP_FMTCTRL_DEFAULTS { 	\
	CSL_SPI_CSHOLD_NO,                     	\
	CSL_SPI_WDELAYEN_NO,                   	\
	CSL_SPI_FMTSEL_0,                      	\
	0,                                     	\
}


/** default setting for @a CSL_SpiHwSetupPins */
#define CSL_SPI_HWSETUP_PINS_DEFAULTS { 	\
	NULL,                               	\
	NULL                                	\
}

/** ===========================================================================
 *   @func CSL_spiOpen
 *
 *   @desc
 *        This function populates the peripheral data object for the instance
 *        and returns a handle to the instance.
 *        The open call sets up the data structures for the particular instance
 *        of SPI device. The device can be re-opened anytime after it has been
 *        normally closed if so required. SPI Hardware setup will be performed
 *        at the end of the open call only if the HwSetup Pointer supplied was
 *        non-NULL. The handle returned by this call is input as an essential
 *        argument for rest of the APIs described for this module.
 *
 *   @arg pSpiObj
 *        Pointer to the SPI instance object
 *
 *   @arg spiNum
 *        Instance of the SPI to be opened.
 *
 *   @arg pSpiParam
 *        Pointer to module specific parameters
 *
 *   @arg pStatus
 *        pointer for returning status of the function call
 *
 *   @ret CSL_SpiHandle
 *        Valid SPI instance handle will be returned if status value is
 *        equal to CSL_SOK.
 *
 *   @eg
 *        CSL_Status        status;
 *        CSL_SpiObj        spiObj;
 *        CSL_SpiHandle     hSpi;
 *
 *        hSpi = CSL_spiOpen (&spiObj,
 *                            CSL_SPI_0,
 *                            NULL,
 *                            &status
 *                            );
 *
 * ===========================================================================
 */
/** @brief opens if possible the instance of SPI requested */
CSL_SpiHandle CSL_spiOpen(
	/** pointer to the object that holds reference to the instance of SPI
	* requested after the call */
	CSL_SpiObj                            *hSpiObj,
	/** instance of SPI to which a handle is requested */
	CSL_InstNum                           spiNum,
	/** specifies if SPI should be opened with excusive or share access to
	* the associate pins */
	CSL_SpiParam                          *pSpiParam,
	/** This returns the status (success/errors) of the call */
	CSL_Status                            *status
);

/** ===========================================================================
 *   @func CSL_spiClose
 *
 *   @b Description
 *   @n Unreserves the SPI identified by the handle.
 *
 *   @arg  hSpi
           Handle to the Spi instance
 *
 *   @ret CSL_Status
 *         CSL_SOK            - Close successful
 *         CSL_ESYS_BADHANDLE - Invalid handle
 *
 *   <b> Pre Condition </b>
 *   @n  Both @a CSL_spiInit() and @a CSL_spiOpen() must be called successfully
 *       in that order before @a CSL_spiClose() can be called.
 *
 *   <b> Post Condition </b>
 *   @n  None.
 *
 *   @b Example
 *   @verbatim
        CSL_SpiHandle       hSpi;
        ...
        status = CSL_spiClose (hSpi);
        ...
     @endverbatim
 * =============================================================================
 */
CSL_Status  CSL_spiClose(
    /** Pointer to the object that holds reference to the
    *  instance of SPI requested after the call
    */

    CSL_SpiHandle                         hSpi
);

/** ============================================================================
 *   @n@b CSL_spiHwSetup
 *
 *   @b Description
 *   @n It configures the SPI registers as per the values passed
 *      in the hardware setup structure.
 *
 *   @b Arguments
 *   @verbatim
            hSpi            Handle to the Spi instance
 
            setup         Pointer to harware setup structure
 
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                    CSL_SOK             - Hardware setup successful
 *   @li                    CSL_ESYS_BADHANDLE  - Invalid handle
 *   @li                    CSL_ESYS_INVPARAMS  - Hardware structure is not
                                                  properly initialized
 *
 *   <b> Pre Condition </b>
 *   @n  None
 *
 *   <b> Post Condition </b>
 *   @n  SPI controller registers are configured according 
 *       to the hardware setup parameters
 *
 *   @b Modifies
 *   @n SPI controller registers
 *
 *   @b Example
 *   @verbatim
            CSL_SpiHandle   hSpi;
            CSL_SpiHwSetup  hwSetup;
            CSL_status      status;

            ...
            
            status = CSL_spiHwSetup(hSpi, &hwSetup);
            
            
     @endverbatim
 * ===========================================================================
 */
/** @brief programs the SPI to a useful state as specified */
CSL_Status  CSL_spiHwSetup(
    /** pointer to the object that holds reference to the instance of SPI
    * requested after the call */
    CSL_SpiHandle                         hSpi,
    /** pointer to setup structure which contains the information to program
    * SPI to a useful state */
    CSL_SpiHwSetup                        *setup
);

/** ============================================================================
 *   @n@b CSL_spiGetHwSetup
 *
 *   @b Description
 *   @n It retrives the hardware setup parameters of the SPI instance
 *      specified by the given handle.
 *
 *   @b Arguments
 *   @verbatim
            hSpi        Handle to the SPI intance
 
            hwSetup      Pointer to the harware setup structure
 
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                    CSL_SOK             - Retrieving the hardware setup
 *                                                parameters is successful
 *   @li                    CSL_ESYS_BADHANDLE  - The handle is passed is
 *                                                invalid
 *   @li                    CSL_ESYS_INVPARAMS  - Invalid parameter
 *
 *   <b> Pre Condition </b>
 *   @n  None
 *
 *   <b> Post Condition </b>
 *   @n  Hardware setup parameters are returned in the hwSetup variable
 *
 *   @b Modifies
 *   @n hwSetup variables
 *
 *   @b Example
 *   @verbatim
            CSL_SpiHandle   hSpi;
            CSL_SpiHwSetup  hwSetup;

            ...
            
            status = CSL_SpiGetHwSetup(hSpi, &hwSetup);
            
            ...
            
     @endverbatim
 * ===========================================================================
 */
CSL_Status  CSL_spiGetHwSetup(
    /** pointer to the object that holds reference to the
    * instance of SPI requested after the call */
    CSL_SpiHandle                         hSpi,
    /** the query to this API which indicates the status/setup
    * to be returned */
    CSL_SpiHwSetup                        *setup
);

/** ============================================================================
 *   @n@b CSL_spiHwControl
 *
 *   @b Description
 *   @n Takes a command of SPI with an optional argument & implements it.
 *
 *   @b Arguments
 *   @verbatim
            hSpi        Handle to the SPI instance

            cmd             The command to this API indicates the action to be
                            taken on SPI.

            arg             An optional argument.

     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li         CSL_SOK               - Status info return successful.
 *   @li         CSL_ESYS_BADHANDLE    - Invalid handle
 *   @li         CSL_ESYS_INVCMD       - Invalid command
 *   @li         CSL_ESYS_INVPARAMS    - Invalid parameter
 *   @li         CSL_ESYS_NOTSUPPORTED - Action Not Supported
 *
 *   <b> Pre Condition </b>
 *   @n  None
 *
 *   <b> Post Condition </b>
 *   @n  None
 *
 *   @b Modifies
 *   @n The hardware registers of SPI.
 *
 *   @b Example
 *   @verbatim
        CSL_SpiHandle         hSpi;
        CSL_SpiHwControlCmd   cmd=CSL_SPI_CMD_CPT_DMA_ENABLE;
        void                      arg;

        status = CSL_spiHwControl (hSpi, cmd, &arg);

     @endverbatim
 * =============================================================================
 */
/** @brief controls the different operations that can be performed by
 * SPI */
CSL_Status  CSL_spiHwControl(
    /** pointer to the object that holds reference to the instance of SPI
    * requested after the call */
    CSL_SpiHandle                         hSpi,
    /** the command to this API which indicates the action to be taken */
    CSL_SpiHwControlCmd                   cmd,
    /** an optional argument @a void* casted */
    void                                     *arg
);


/** ============================================================================
 *   @n@b CSL_spiInit
 *
 *   @b Description
 *   @n This is the initialization function for the SPI. This function is 
 *   idempotent in that calling it many times is same as calling it once. This 
 *   function does not modify any registers or check status. It returns status 
 *   CSL_SOK. It has been kept for future use.
 *
 *   @b Arguments
     @verbatim
            pContext   Context information for the instance. Should be NULL
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                    CSL_SOK - Always returns
 *
 *   <b> Pre Condition </b>
 *   @n  CSL_sysInit() must be called. 
 *
 *   <b> Post Condition </b>
 *   @n  None
 *
 *   @b Modifies
 *   @n  None
 *
 *   @b Example
 *   @verbatim
		
	CSL_Status 	Status		
	Status = CSL_spiInit();

   @endverbatim
 *  ===========================================================================
 */
CSL_Status  CSL_spiInit(
    CSL_SpiContext * pContext
);


/** ===========================================================================
 *   @func CSL_spiHwSetupRaw
 *
 *   @desc
 *       This function configures the registers of SPI as per the values given
 *       in the Config structure.
 *
 *   @arg hSpi
 *        Handle to the SPI instance
 *
 *   @arg hwConfig
 *        Pointer to SPI config structure
 *
 *   @ret CSL_Status
 *         CSL_SOK             - Configuration successful
 *         CSL_ESYS_BADHANDLE  - Invalid handle
 *
 *   @eg
 *
 *        CSL_Status            status;
 *        CSL_SpiConfig     hwConfig;
 *
 *        status = CSL_spiHwsetupRaw (hSpi, &hwConfig);
 *
 * ===========================================================================
 */

extern CSL_Status  CSL_spiHwSetupRaw (
    CSL_SpiHandle           hSpi,
    CSL_SpiConfig *         config
);

/** ============================================================================
 *   @n@b CSL_spiGetHwStatus
 *
 *   @b Description
 *   @n Gets the status of the different settings of SPI instance.
 *
 *   @b Arguments
 *   @verbatim
            hSpi      Handle to the SPI instance

            query      The query to this API of SPI which indicates the
                       status to be returned.

            response   Placeholder to return the status.

     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                    CSL_SOK             - Status info return successful
 *   @li                    CSL_ESYS_BADHANDLE   - Invalid handle
 *   @li                    CSL_ESYS_INVQUERY    - Invalid query command
 *   @li                    CSL_ESYS_INVPARAMS   - Invalid parameter
 *   @li                    CSL_ESYS_NOTSUPPORTED- Action Not Supported
 *  
 *   <b> Pre Condition </b>
 *   @n  None
 *
 *   <b> Post Condition </b>
 *   @n  None
 *
 *   @b Modifies
 *   @n None
 *
 *   @b Example
 *   @verbatim
        CSL_SpiHandle          hSpi;
        CSL_SpiHwStatusQuery   query=CSL_SPI_QUERY_INT_VECTOR0;
        CSL_SpiIntVec                   reponse;

        status = CSL_spiGetHwStatus (hSpi, query, &response);

     @endverbatim
 * =============================================================================
 */
CSL_Status  CSL_spiGetHwStatus(
    /** pointer to the object that holds reference to the instance of SPI
    * requested after the call */
    CSL_SpiHandle                         hSpi,
    /** the query to this API which indicates the status/setup to be
    * returned */
    CSL_SpiHwStatusQuery                  query,
    /** placeholder to return the status; @a void* casted */
    void                                     *response
);

/** ===========================================================================
 *   @n@b CSL_spiGetBaseAddress
 *
 *   @b Description
 *   @n  Function to get the base address of the peripheral instance.
 *       This function is used for getting the base address of the peripheral
 *       instance. This function will be called inside the CSL_spiOpen()
 *       function call. This function is open for re-implementing if the user
 *       wants to modify the base address of the peripheral object to point to
 *       a different location and there by allow CSL initiated write/reads into
 *       peripheral MMR's go to an alternate location.
 *
 *   @b Arguments
 *   @verbatim
            spiNum          Specifies the instance of SPI to be opened.

            pSpiParam       Module specific parameters.

            pBaseAddress    Pointer to baseaddress structure containing base
                            address details.

     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                    CSL_OK             Open call is successful
 *   @li                    CSL_ESYS_FAIL      The instance number is invalid.
 *	 @li					CSL_ESYS_INVPARAMS Invalid Parameters passed
 *
 *   <b> Pre Condition </b>
 *   @n  None
 *
 *   <b> Post Condition </b>
 *   @n  Base Address structure is populated
 *
 *   @b Modifies
 *   @n    1. The status variable
 *
 *         2. Base address structure is modified.
 *
 *   @b Example
 *   @verbatim
        CSL_Status              status;
        CSL_SpiBaseAddress  baseAddress;

       ...
      status = CSL_spiGetBaseAddress(CSL_SPI_0, NULL, &baseAddress);

    @endverbatim
 * ============================================================================
 */
extern CSL_Status   CSL_spiGetBaseAddress (
    CSL_InstNum            spiNum,
    CSL_SpiParam *         pSpiParam,
    CSL_SpiBaseAddress *   pBaseAddress
);

#ifdef __cplusplus
}
#endif

#endif /* _CSL_SPI_H_ */
