/*********************************************************************
 *
 *                  SPI Legacy Library definitions
 *
 *********************************************************************
 * FileName:        spi_legacy.h
 * Dependencies:
 * Processor:       PIC32
 *
 * Compiler:        MPLAB XC32
 *                  MPLAB IDE
 * Company:         Microchip Technology Inc.
 *
 * Software License Agreement
 *
 * The software supplied herewith by Microchip Technology Incorporated
 * (the “Company”) for its PIC Microcontroller is intended
 * and supplied to you, the Company’s customer, for use solely and
 * exclusively on Microchip PIC Microcontroller products.
 * The software is owned by the Company and/or its supplier, and is
 * protected under applicable copyright laws. All rights are reserved.
 * Any use in violation of the foregoing restrictions may subject the
 * user to criminal sanctions under applicable laws, as well as to
 * civil liability for the breach of the terms and conditions of this
 * license.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 *
 *
 ********************************************************************/

#ifndef _SPI_LEGACY_H_
#define _SPI_LEGACY_H_



#include <xc.h>
#include <peripheral/int.h>

/*
*  WARNING: All the Peripheral Library (PLIB) functions, including those in this file,
*  will be removed from future releases of MPLAB XC32 C/C++ Compiler.
*  Please refer to the MPLAB Harmony Libraries for new projects.  For legacy support,
*  these PLIB Libraries will be available for download from: www.microchip.com/pic32_peripheral_lib
*/
#ifndef _SUPPRESS_PLIB_WARNING
  #warning The PLIB functions and macros in this file will be removed from the MPLAB XC32 C/C++ Compiler in future releases
#endif


#define SPI_CHANNEL1A   SPI_CHANNEL3
#define SPI_CHANNEL2A   SPI_CHANNEL2
#define SPI_CHANNEL3A   SPI_CHANNEL4

/*****************************************************
 *  Legacy SPI functions
 *  These functions are provided for backward compatibility only
 *  They are no longer maintained!
 *  New projects should not use them!
 *******************************************************/


// old configuration definitions
// configuration flags
typedef enum
{
    // master configuration
    SPI_CON_MSTEN =     _SPIxCON_MASK_(MSTEN_MASK), // set the Master mode
    SPI_CON_SMP =       _SPIxCON_MASK_(SMP_MASK),   // Master Sample Phase for the input bit at the end of the data out time. Otherwise data is sampled in the middle.

    // slave configuration
    SPI_CON_SLVEN =     0,              // set the Slave mode
    SPI_CON_SSEN =      _SPIxCON_MASK_(SSEN_MASK),  // enable the SS (Slave Select) input pin.

    // clocking configuration
    SPI_CON_CKP =       _SPIxCON_MASK_(CKP_MASK),   // set the clock polarity to (idle-high, active-low). Otherwise is (idle-low, active-high).
    SPI_CON_CKE =       _SPIxCON_MASK_(CKE_MASK),   // set the Clock Edge to transmit from active to idle. Otherwise transmit when clock goes from idle to active

    // data characters configuration
    SPI_CON_MODE8 =     0,              // set 8 bits/char
    SPI_CON_MODE16 =    _SPIxCON_MASK_(MODE16_MASK),    // set 16 bits/char
    SPI_CON_MODE32 =    _SPIxCON_MASK_(MODE32_MASK),    // set 32 bits/char

    // framed mode configuration
    SPI_CON_FRMEN =     _SPIxCON_MASK_(FRMEN_MASK), // Enable the Framed SPI support. Otherwise the Framed SPI is disabled.
    SPI_CON_FRMSYNC =   _SPIxCON_MASK_(FRMSYNC_MASK),   // Frame Sync Pulse (FSP) direction set to input (Frame Slave).
                                    // Otherwise the FSP is output and the SPI channel operates as a Frame Master.
    SPI_CON_FRMPOL =    _SPIxCON_MASK_(FRMPOL_MASK),    // FSP polarity set active high. Otherwise the FSP is active low.
    SPI_CON_SPIFE =     _SPIxCON_MASK_(SPIFE_MASK), // Set the Frame Sync Pulse (FSP) to coincide with the 1st bit clock.
                                    // Otherwise the FSP precedes the 1st bit clock

    // general configuration
    SPI_CON_DISSDO =    _SPIxCON_MASK_(DISSDO_MASK),    // disable the usage of the SDO pin by the SPI
    SPI_CON_SIDL =      _SPIxCON_MASK_(SIDL_MASK),  // enable the Halt in the CPU Idle mode. Otherwise the SPI will be still active when the CPU is in Idle mode.
    SPI_CON_ON =        _SPIxCON_MASK_(ON_MASK),    // turn ON the SPI (not used in SpiChnOpen)
}SpiCtrlFlags;  // control flags that can be used with SpiChnOpen.




/*********************************************************************
 * Function:        void SpiChnChgMode(SpiChannel chn, int isMaster, int isFrmMaster)
 *
 * PreCondition:    None
 *
 * Input:           chn         - the channel to set
 *                  isMaster    - master/slave mode
 *                  isFrmMaster - frame master/slave mode
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function changes the SPI channel mode on the fly.
 *
 * Note:            - The function blocks until the current transfer, if any, is completed.
 *                    Due to a bug in the PIC32_3XX_4xx and PIC32_5XX_6xx_7xx SPI implementation, the BUSY/SRMT flag is set one spi_clk earlier.
 *                    What it means is that the data is not available in the SPIRxBUFF/SPIRxFIFO at the moment that BUSY is cleared.
 *                    The function will wait for the BUSY to be cleared.
 *                    For high SPIxBRG and PBDIV values note that the number of CPU clock cycles that have to be spent in this function could be significant.
 *                  - isFrmMaster is relevant only if the SPI channel is operating in frame mode
 *                  - The SCK is properly configured as an digital I/O pin
 *                  - The SS is configured as a digital pin only if in frame mode or if the SSEN configuration bit is set.
 *
 * Example:         SpiChnChgMode(SPI_CHANNEL2A, TRUE, TRUE);
 ********************************************************************/
#define SpiChnChgMode(chn, isMaster, isFrmMaster)   SpiChnChangeMode(chn, isMaster, isFrmMaster, 1)


/******************************************************************************
 * Function:        int mSPIBRG(int pb_clk, int spi_clk)
 *
 * Description:     Calculates the BRG values needed for the SPI configuration
 *
 * PreCondition:    spi_clk <= pb_clk/2;
 *
 * Inputs:      pb_clk:     - the PB clock frequency, Hz
 *          spi_clk:    - the desired SPI clock frequency, Hz
 *
 * Output:          The proper BRG value
 *
 * Example: SpiChnSetBrg(SPI_CHANNEL1, mSPIBRG(72000000, 9000000));
 *
 *****************************************************************************/
#define     mSPIBRG     SpiBrgVal

/*********************************************************************
 * Function:        void mSpiChnSetBrg(int chn, UINT brg)
 *
 * PreCondition:    None
 *
 * Input:           chn - the channel to set
 *                  brg - value for the brg register
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This macro directly updates the values for the SPI channel brg.
 *
 * Note:            The channel parameter is directly used as a string in the macro call,
 *                  so it has to be one of: 1, 2, 1A, 2A, 3A
 *
 * Example:         mSpiChnSetBrg(1, 0x0);
 *                  mSpiChnSetBrg(2, 0x0);
 *                  mSpiChnSetBrg(3A, 2)
 ********************************************************************/
#define     mSpiChnSetBrg(c, brg)       (SPI##c##BRG=(brg))



/*****************************************
 *       Legacy Interrupt functions
 *       The functions in the int.h should be used instead.
 ***********************************************************/

/*********************************************************************
 * Function:        int SpiChnGetRovIntFlag(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the channel to check
 *
 * Output:          TRUE        - if overflow flag
 *                  FALSE       - otherwise
 * Side Effects:    None
 * Overview:        This function reads the SPI channel overflow interrupt flag.
 *
 * Note:            None.
 *
 * Example:         int chn=SPI_CHANNEL1; int isOvflFlag=SpiChnGetRovIntFlag(chn);
 *                  int isOvflFlag=mSpiChnGetRovIntFlag(1);
 ********************************************************************/
#define     SpiChnGetRovIntFlag(chn)    INTGetFlag((INT_SPI1E-1)+(chn))
#define     mSpiChnGetRovIntFlag(c)     (mSPI##c##EGetIntFlag())        // macro version


/*********************************************************************
 * Function:        void SpiChnClrRovIntFlag(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the channel to check
 *
 * Output:          None
 *
 * Side Effects:    None
 * Overview:        This function clears the SPI channel overflow interrupt flag.
 *
 * Note:            None.
 *
 * Example:        int chn=2; SpiChnClrRovIntFlag(chn);
 *                 mSpiChnClrRovIntFlag(2);
 ********************************************************************/
#define     SpiChnClrRovIntFlag(chn)    INTClearFlag((INT_SPI1E-1)+(chn))
#define     mSpiChnClrRovIntFlag(c)     (mSPI##c##EClearIntFlag())      // macro version


/*********************************************************************
 * Function:        int SpiChnGetRxIntFlag(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the channel to check
 *
 * Output:          TRUE        - if SPI Rx flag
 *                  FALSE       - otherwise
 * Side Effects:    None
 * Overview:        This function reads the SPI channel receive interrupt flag.
 *
 * Note:            None.
 *
 * Example:         int chn=SPI_CHANNEL1; int isRxEvent=SpiChnGetRxIntFlag(chn);
 *                  isRxEvent=mSpiChnGetRxIntFlag(1);
 ********************************************************************/
#define     SpiChnGetRxIntFlag(chn)     INTGetFlag((INT_SPI1RX-1)+(chn))
#define     mSpiChnGetRxIntFlag(c)      (mSPI##c##RXGetIntFlag())       // macro version



/*********************************************************************
 * Function:        void SpiChnClrRxIntFlag(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the channel to check
 *
 * Output:          None
 *
 * Side Effects:    None
 * Overview:        This function clears the SPI channel receive interrupt flag.
 *
 * Note:            None.
 *
 * Example:         int chn=1; SpiChnClrRxIntFlag(chn);
 *                  mSpiChnClrRxIntFlag(1);
 ********************************************************************/
#define     SpiChnClrRxIntFlag(chn)     INTClearFlag((INT_SPI1RX-1)+(chn))
#define     mSpiChnClrRxIntFlag(c)      (mSPI##c##RXClearIntFlag())     // macro version


/*********************************************************************
 * Function:        int SpiChnGetTxIntFlag(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the channel to check
 *
 * Output:          TRUE        - if SPI Tx flag
 *                  FALSE       - otherwise
 * Side Effects:    None
 * Overview:        This function reads the SPI channel transmit interrupt flag.
 *
 * Note:            None.
 *
 * Example:         int chn=SPI_CHANNEL1; int isTxEvent=SpiChnGetTxIntFlag(chn);
 *                  isTxEvent=mSpiChnGetTxIntFlag(2);
 ********************************************************************/
#define     SpiChnGetTxIntFlag(chn)     INTGetFlag((INT_SPI1TX-1)+(chn))
#define     mSpiChnGetTxIntFlag(c)      (mSPI##c##TXGetIntFlag())       // macro version

/*********************************************************************
 * Function:        void SpiChnClrTxIntFlag(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the channel to check
 *
 * Output:          None
 *
 * Side Effects:    None
 * Overview:        This function clears the SPI channel transmit interrupt flag.
 *
 * Note:            None.
 *
 * Example:         SpiChnClrTxIntFlag(SPI_CHANNEL1);
 *                  mSpiChnClrTxIntFlag(1);
 ********************************************************************/
#define     SpiChnClrTxIntFlag(chn)     INTClearFlag((INT_SPI1TX-1)+(chn))
#define     mSpiChnClrTxIntFlag(c)      (mSPI##c##TXClearIntFlag())     // macro version


/*********************************************************************
 * Function:        int SpiChnGetIntFlags(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the channel to check
 *
 * Output:          TRUE        - if any SPI flag occurred (Rx, Tx, OVFL)
 *                  FALSE       - otherwise
 *
 * Side Effects:    None
 *
 * Overview:        This function reads the SPI channel interrupt flags.
 *
 * Note:            None.
 *
 * Example:         int chn=1; int isRxTxEvent=SpiChnGetIntFlags(chn);
 *                  isRxTxEvent=mSpiChnGetIntFlags(1);
 ********************************************************************/
#define     SpiChnGetIntFlags(chn)  INTGetFlag((INT_SPI1-1)+(chn))
#define     mSpiChnGetIntFlags(c)   (mSPI##c##TXGetIntFlag() || mSPI##c##TXGetIntFlag() ||mSPI##c##EGetIntFlag())       // macro version


/*********************************************************************
 * Function:        void SpiChnClrIntFlags(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the channel to check
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function clears the SPI channel interrupt flags.
 *
 * Note:            None.
 *
 * Example:         int chn=1; SpiChnClrIntFlags(chn);
 *                  mSpiChnClrIntFlags(1);
 ********************************************************************/
#define     SpiChnClrIntFlags(chn)      INTClearFlag((INT_SPI1-1)+(chn))
#define     mSpiChnClrIntFlags(c)       (mSPI##c##ClearAllIntFlags())       // macro version


/*********************************************************************
 * Function:        void SpiChnRxIntEnable(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the requested SPI channel
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function enables the SPI channel receive interrupts.
 *
 * Note:            Clears existing interrupt flags.
 *
 * Example:         SpiChnSetRxIntEnable(SPI_CHANNEL1);
 *                  mSpiChnRxIntEnable(1);
 ********************************************************************/
#define     SpiChnRxIntEnable(chn)      do{INTClearFlag((INT_SPI1-1)+(chn)); INTEnable((INT_SPI1RX-1)+(chn), 1);}while(0)
#define     mSpiChnRxIntEnable(c)       (mSPI##c##ClearAllIntFlags(), mSPI##c##RXIntEnable(1))      // macro version



/*********************************************************************
 * Function:        void SpiChnRxIntDisable(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the requested SPI channel
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function disables the SPI channel receive interrupts.
 *
 * Note:            Clears existing interrupt flags.
 *
 * Example:         int chn=1; SpiChnRxIntDisable(chn);
 *                  mSpiChnRxIntDisable(1);
 ********************************************************************/
#define     SpiChnRxIntDisable(chn)     do{INTClearFlag((INT_SPI1-1)+(chn)); INTEnable((INT_SPI1RX-1)+(chn), 0);}while(0)
#define     mSpiChnRxIntDisable(c)      (mSPI##c##ClearAllIntFlags(), mSPI##c##RXIntEnable(0))      // macro version



/*********************************************************************
 * Function:        void SpiChnTxIntEnable(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the requested SPI channel
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function enables the SPI channel transmit interrupts.
 *
 * Note:            Clears existing interrupt flags.
 *
 * Example:         SpiChnTxIntEnable(SPI_CHANNEL1);
 *                  mSpiChnTxIntEnable(1);
 ********************************************************************/
#define     SpiChnTxIntEnable(chn)  do{INTClearFlag((INT_SPI1-1)+(chn)); INTEnable((INT_SPI1TX-1)+(chn), 1);}while(0)
#define     mSpiChnTxIntEnable(c)   (mSPI##c##ClearAllIntFlags(), mSPI##c##TXIntEnable(1))      // macro version


/*********************************************************************
 * Function:        void SpiChnTxIntDisable(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the requested SPI channel
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function disables the SPI channel transmit interrupts.
 *
 * Note:            Clears existing interrupt flags.
 *
 * Example:         int chn=2; SpiChnTxIntDisable(chn);
 *                  mSpiChnTxIntDisable(2);
 ********************************************************************/
#define     SpiChnTxIntDisable(chn) do{INTClearFlag((INT_SPI1-1)+(chn));INTEnable((INT_SPI1TX-1)+(chn), 0);}while(0)
#define     mSpiChnTxIntDisable(c)  (mSPI##c##ClearAllIntFlags(), mSPI##c##TXIntEnable(0))      // macro version



/*********************************************************************
 * Function:        void SpiChnRxTxIntEnable(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the requested SPI channel
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function enables the SPI channel transmit/receive interrupts.
 *
 * Note:            Clears existing interrupt flags.
 *
 * Example:         int chn=SPI_CHANNEL1; SpiChnRxTxIntEnable(chn);
 *                  mSpiChnRxTxIntEnable(1);
 ********************************************************************/
#define     SpiChnRxTxIntEnable(chn)    do{INTClearFlag((INT_SPI1-1)+(chn));INTEnable((INT_SPI1TX-1)+(chn), 1); \
                                        INTEnable((INT_SPI1RX-1)+(chn), 1);}while(0)
#define     mSpiChnRxTxIntEnable(c)     (mSPI##c##ClearAllIntFlags(), mSPI##c##TXIntEnable(1), mSPI##c##RXIntEnable(1)) // macro version



/*********************************************************************
 * Function:        void SpiChnRxTxIntDisable(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the requested SPI channel
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function disables the SPI channel transmit/receive interrupts.
 *
 * Note:            Clears existing interrupt flags.
 *
 * Example:         int chn=2; SpiChnRxTxIntDisable(chn);
 *                  mSpiChnRxTxIntDisable(2);
 ********************************************************************/
#define     SpiChnRxTxIntDisable(chn)   do{INTClearFlag((INT_SPI1-1)+(chn));INTEnable((INT_SPI1TX-1)+(chn), 0); \
                                            INTEnable((INT_SPI1RX-1)+(chn), 0);}while(0)
#define     mSpiChnRxTxIntDisable(c)        (mSPI##c##ClearAllIntFlags(), mSPI##c##TXIntEnable(0), mSPI##c##RXIntEnable(0)) // macro version



/*********************************************************************
 * Function:        void SpiChnFaultIntEnable(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the requested SPI channel
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function enables the SPI channel fault interrupts.
 *
 * Note:            Clears an existing fault interrupt flag.
 *
 * Example:         int chn=SPI_CHANNEL2; SpiChnFaultIntEnable(chn);
 *                  mSpiChnFaultIntEnable(2);
 ********************************************************************/
#define     SpiChnFaultIntEnable(chn)   do{INTClearFlag((INT_SPI1-1)+(chn));INTEnable((INT_SPI1E-1)+(chn), 1);}while(0)
#define     mSpiChnFaultIntEnable(c)    (mSPI##c##ClearAllIntFlags(), mSPI##c##EIntEnable(1))       // macro version



/*********************************************************************
 * Function:        void SpiChnFaultIntDisable(int chn)
 *
 * PreCondition:    None
 * Input:           chn         - the requested SPI channel
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function disables the SPI channel fault interrupts.
 *
 * Note:            Clears an existing fault interrupt flag.
 *
 * Example:         int chn=2; SpiChnFaultIntDisable(chn);
 *                  mSpiChnFaultIntDisable(2);
 ********************************************************************/
#define     SpiChnFaultIntDisable(chn)      do{INTClearFlag((INT_SPI1-1)+(chn));INTEnable((INT_SPI1E-1)+(chn), 0);}while(0)
#define     mSpiChnFaultIntDisable(c)       (mSPI##c##ClearAllIntFlags(), mSPI##c##EIntEnable(0))       // macro version


/*********************************************************************
 * Function:        void SpiChnSetIntPriority(int chn, int pri, int subPri)
 *
 * PreCondition:    pri     - valid priority 0-7
 *                  subPri  - valid subpriority 0-3
 *
 * Input:           chn         - the requested SPI channel
 *                  pri         - the interrupt priority
 *                  subPri      - the interrupt sub-priority
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function sets the SPI channel interrupt priority.
 *
 * Note:            None.
 *
 * Example:         int chn, pri, subPri; chn=SPI_CHANNEL1, pri=2, subPri=3; SpiChnSetIntPriority(chn, pri, subPri);
 *                  mSpiChnSetIntPriority(1, 2, 3);
 ********************************************************************/
#define     SpiChnSetIntPriority(chn, pri, subPri) do{INTSetPriority((INT_SPI1-1)+(chn), (pri)); \
                            INTSetSubPriority((INT_SPI1-1)+(chn), (subPri));}while(0)
#define     mSpiChnSetIntPriority(c, pri, sPri) (mSPI##c##SetIntPriority(pri), mSPI##c##SetIntSubPriority(sPri))    // macro version

/*********************************************************************
 * Function:        int SpiChnGetIntPriority(int chn)
 *
 * PreCondition:    chn     - valid SPI channel
 *
 * Input:           chn         - the requested SPI channel
 *
 * Output:          The current interrupt priority for the selected channel
 *
 * Side Effects:    None
 *
 * Overview:        This function reads the SPI channel interrupt priority in the INT controller.
 *
 * Note:            None.
 *
 * Example:         int chn=2; int currPri=SpiChnGetIntPriority(chn);
 *                  currPri=mSpiChnGetIntPriority(2);
 ********************************************************************/
#define     SpiChnGetIntPriority(chn)       INTGetPriority((INT_SPI1-1)+(chn))
#define     mSpiChnGetIntPriority(c)        (mSPI##c##GetIntPriority())     // macro version

/*********************************************************************
 * Function:        int SpiChnGetIntSubPriority(int chn)
 *
 * PreCondition:    chn     - valid SPI channel
 *
 * Input:           chn         - the requested SPI channel
 *
 * Output:          The current interrupt subpriority for the selected channel
 *
 * Side Effects:    None
 *
 * Overview:        This function reads the SPI channel interrupt subpriority in the INT controller.
 *
 * Note:            None.
 *
 * Example:         int chn=2; int currSubPri=SpiChnGetIntSubPriority(chn);
 *                  currSubPri=mSpiChnGetIntSubPriority(2);
 ********************************************************************/
#define     SpiChnGetIntSubPriority(chn)    INTGetSubPriority((INT_SPI1-1)+(chn))
#define     mSpiChnGetIntSubPriority(c)     (mSPI##c##GetIntSubPriority())      // macro version







/*****************************************
 *       Legacy channel oriented functions
 *       The new functions taking the channel number parameter from spi.h should be used instead.
 ***********************************************************/


/* List of SFRs for SPI */
/* This list contains the SFRs with default (POR) values to be used for configuring SPI */
/* The user can modify this based on the requirement */
#define SPI1STAT_VALUE         0x00000000
#define SPI2STAT_VALUE         0x00000000
#define SPI1CON_VALUE          0x00000000
#define SPI2CON_VALUE          0x00000000
#define SPI1BUF_VALUE          0x00000000
#define SPI2BUF_VALUE          0x00000000



// OpenSPI config1 word structure
typedef union
{
    struct
    {
        unsigned PPRE:      2;      // primary prescaler
        unsigned SPRE:      3;      // secondary prescaler
        unsigned MSTEN:     1;      // master mode enable
        unsigned CKP:       1;      // clock polarity
        unsigned SSEN:      1;      // slave select
        unsigned CKE:       1;      // clock edge
        unsigned SMP:       1;      // sample phase
        unsigned MODE16:    1;      // word/hword/byte communication select
        unsigned MODE32:    1;      // word/hword/byte communication select
        unsigned DISSDO:    1;      // disable SDO pin
        unsigned:           17;     // reserved
        unsigned FRMSYNC:   1;      // frame sync direction
        unsigned FRMEN:     1;      // framed SPI
    };                              // field access
    unsigned int            w;      // word access
}SpiOpenConfig1;


#define  FRAME_ENABLE_ON        (0x80000000)        /* Frame SPI support enable */
#define  FRAME_ENABLE_OFF       (0x00000000)  /* Frame SPI support Disable */

#define  FRAME_SYNC_INPUT       (0x40000000)        /* Frame sync pulse Input (slave) */
#define  FRAME_SYNC_OUTPUT      (0x00000000) /* Frame sync pulse Output (master) */

#define  ENABLE_SCK_PIN         (0x00000000)            /* SCK pin is not handled here */
#define  DISABLE_SCK_PIN        (0x00000000)    /* SCK pin is not handled here */

#define  DISABLE_SDO_PIN        (0x00001000)        /* SDO pin is not used by module */
#define  ENABLE_SDO_PIN         (0x00000000)    /* SDO pin is  used by module */

#define  SPI_MODE32_ON          (0x00000800)            /* Communication is 32 bits wide */
#define  SPI_MODE32_OFF         (0x00000000)        /* Communication is selected by SPI_MODE16_ON/OFF */

#define  SPI_MODE16_ON          (0x00000400)            /* If SPI_MODE32_OFF, Communication is 16 bits wide */
#define  SPI_MODE16_OFF         (0x00000000)            /* If SPI_MODE32_OFF, Communication is 8 bits wide */

#define  SPI_MODE8_ON           (0x00000000)            /* If SPI_MODE32_OFF and SPI_MODE16_OFF, Communication is 8 bits wide */

#define  SPI_SMP_ON             (0x00000200)        /* Input data sampled at end of data output time */
#define  SPI_SMP_OFF            (0x00000000)    /* Input data sampled at middle of data output time */

#define  SPI_CKE_ON             (0x00000100)        /* Transmit happens from active clock state to idle clock state*/
#define  SPI_CKE_OFF            (0x00000000)    /* Transmit happens on transition from idle clock state to active clock state */

#define  SLAVE_ENABLE_ON        (0x00000080)            /* Slave Select enbale */
#define  SLAVE_ENABLE_OFF       (0x00000000)    /* Slave Select not used by module */

#define  CLK_POL_ACTIVE_LOW     (0x00000040)                /* Idle state for clock is high, active is low */
#define  CLK_POL_ACTIVE_HIGH    (0x00000000)    /* Idle state for clock is low, active is high */

#define  MASTER_ENABLE_ON       (0x00000020)            /* Master Mode */
#define  MASTER_ENABLE_OFF      (0x00000000)    /* Slave Mode */

#define  SEC_PRESCAL_1_1        (0x0000001c)        /* Secondary Prescale 1:1   */
#define  SEC_PRESCAL_2_1        (0x00000018)        /* Secondary Prescale 2:1   */
#define  SEC_PRESCAL_3_1        (0x00000014)        /* Secondary Prescale 3:1   */
#define  SEC_PRESCAL_4_1        (0x00000010)        /* Secondary Prescale 4:1   */
#define  SEC_PRESCAL_5_1        (0x0000000c)        /* Secondary Prescale 5:1   */
#define  SEC_PRESCAL_6_1        (0x00000008)        /* Secondary Prescale 6:1   */
#define  SEC_PRESCAL_7_1        (0x00000004)        /* Secondary Prescale 7:1   */
#define  SEC_PRESCAL_8_1        (0x00000000)        /* Secondary Prescale 8:1   */

#define  PRI_PRESCAL_1_1        (0x00000003)        /* Primary Prescale 1:1     */
#define  PRI_PRESCAL_4_1        (0x00000002)        /* Primary Prescale 4:1     */
#define  PRI_PRESCAL_16_1       (0x00000001)        /* Primary Prescale 16:1    */
#define  PRI_PRESCAL_64_1       (0x00000000)        /* Primary Prescale 64:1    */



// OpenSPI config2 word structure
typedef union
{
    struct
    {
        unsigned:           6;      // reserved
        unsigned SPIROV:    1;      // receiver overflow
        unsigned:           6;      // reserved
        unsigned SIDL:      1;      // stop in idle
        unsigned:           1;      //
        unsigned ON:        1;      // enable peripheral
        unsigned:           1;      // reserved
        unsigned SPIFE:     1;      // frame edge select
        unsigned:           11;     //
        unsigned FRMPOL:    1;      // frame sync polarity
    };                              // field access
    unsigned int            w;      // word access
}SpiOpenConfig2;


#define  SPI_ENABLE             (0x00008000)            /* Enable module */
#define  SPI_DISABLE            (0x00000000)        /* Disable module */

#define  SPI_IDLE_STOP          (0x00002000)        /* Discontinue module operation in idle mode */
#define  SPI_IDLE_CON           (0x00000000)        /* Continue module operation in idle mode */

#define  SPI_RX_OVFLOW          (0x00000040)            /* receive overflow bit */
#define  SPI_RX_OVFLOW_CLR      (0x00000000)    /* Clear receive overflow bit */

#define  FRAME_POL_ACTIVE_HIGH  (0x20000000)                    /* Frame pulse active high */
#define  FRAME_POL_ACTIVE_LOW   (0x00000000)    /* Frame pulse active low */

#define FRAME_SYNC_EDGE_COINCIDE (0x00020000)                   /* frame pulse coincides with the first bit clock */
#define FRAME_SYNC_EDGE_PRECEDE (0x00000000)    /* frame pulse precedes the first bit clock */

#define FIFO_BUFFER_ENABLE      (0x00000000)                    /* no enhanced buffer functionality */
#define FIFO_BUFFER_DISABLE (0x00000000)        /* ineffective */




    /* SPI Interrupt defines */

// ConfigIntSPI word structure
typedef union
{
    struct
    {
        unsigned ipl:       3;      // interrupt priority level
        unsigned ispl:      2;      // interrupt sub-priority level
        unsigned fie:       1;      // fault interrupt enable/disable
        unsigned txie:      1;      // tx interrupt enable/disable
        unsigned rxie:      1;      // rx interrupt enable/disable
    };                              // field access
    unsigned int            w;      // word access
}SpiConfigInt;


#define  SPI_FAULT_INT_EN       (0x00000020)  /* SPI Fault Interrupt Enable     */
#define  SPI_FAULT_INT_DIS      (0x00000000)  /* SPI Fault Interrupt Disable    */

#define  SPI_TX_INT_EN			(0x00000040)  /* SPI Tx Interrupt Enable */
#define  SPI_TX_INT_DIS         (0x00000000)  /* SPI Tx Interrupt Disable    */

#define  SPI_RX_INT_EN			(0x00000080)  /* SPI Rx Interrupt Enable */
#define  SPI_RX_INT_DIS			(0x00000000)  /* SPI Rx Interrupt Disable    */

#define  SPI_INT_EN             (SPI_TX_INT_EN | SPI_RX_INT_EN)  /* SPI Interrupt Enable: tx+rx */
#define  SPI_INT_DIS            (0x00000000)  /* SPI Interrupt Disable    */


#define  SPI_INT_SUB_PRI_0     (0x00000000)  /* SPI Interrupt Sub-Prior Level_0 */
#define  SPI_INT_SUB_PRI_1     (0x00000008)  /* SPI Interrupt Sub-Prior Level_1 */
#define  SPI_INT_SUB_PRI_2     (0x00000010)  /* SPI Interrupt Sub-Prior Level_2 */
#define  SPI_INT_SUB_PRI_3     (0x00000018)  /* SPI Interrupt Sub-Prior Level_3 */


#define  SPI_INT_PRI_0          (0x00000000)  /* SPI Interrupt Prior Level_0 */
#define  SPI_INT_PRI_1          (0x00000001)  /* SPI Interrupt Prior Level_1 */
#define  SPI_INT_PRI_2          (0x00000002)  /* SPI Interrupt Prior Level_2 */
#define  SPI_INT_PRI_3          (0x00000003)  /* SPI Interrupt Prior Level_3 */
#define  SPI_INT_PRI_4          (0x00000004)  /* SPI Interrupt Prior Level_4 */
#define  SPI_INT_PRI_5          (0x00000005)  /* SPI Interrupt Prior Level_5 */
#define  SPI_INT_PRI_6          (0x00000006)  /* SPI Interrupt Prior Level_6 */
#define  SPI_INT_PRI_7          (0x00000007)  /* SPI Interrupt Prior Level_7 */





/* FUNCTION PROTOTYPES */

#ifdef _SPI1

    /* OpenSPI */
    /*********************************************************************
     * Function:        void OpenSPI1(unsigned int config1,unsigned int config2)
     *
     * Condition:       None
     *
     * Input:           config1 - sets the module behavior using the SpiOpenConfig1 bits:
     *                      typedef union
     *                      {
     *                          struct
     *                          {
     *                              unsigned PPRE:      2;      // primary prescaler
     *                              unsigned SPRE:      3;      // secondary prescaler
     *                              unsigned MSTEN:     1;      // master mode enable
     *                              unsigned CKP:       1;      // clock polarity
     *                              unsigned SSEN:      1;      // slave select
     *                              unsigned CKE:       1;      // clock edge
     *                              unsigned SMP:       1;      // sample phase
     *                              unsigned MODE16:    1;      // word/hword/byte communication select
     *                              unsigned MODE32:    1;      // word/hword/byte communication select
     *                              unsigned DISSDO:    1;      // disable SDO pin
     *                              unsigned:           17;     // reserved
     *                              unsigned FRMSYNC:   1;      // frame sync direction
     *                              unsigned FRMEN:     1;      // framed SPI
     *                          };                              // field access
     *                          unsigned int            w;      // word access
     *                      }SpiOpenConfig1;
     *
     *                  config2 - sets the module behavior using the SpiOpenConfig2 bits:
     *                      typedef union
     *                      {
     *                          struct
     *                          {
     *                              unsigned:           6;      // reserved
     *                              unsigned SPIROV:    1;      // receiver overflow
     *                              unsigned:           6;      // reserved
     *                              unsigned SIDL:      1;      // stop in idle
     *                              unsigned:           1;      //
     *                              unsigned ON:        1;      // enable peripheral
     *                              unsigned:           1;      // reserved
     *                              unsigned SPIFE:     1;      // frame edge select
     *                              unsigned:           11;     //
     *                              unsigned FRMPOL:    1;      // frame sync polarity
     *                          };                              // field access
     *                          unsigned int            w;      // word access
     *                      }SpiOpenConfig2;
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function initializes and enables the SPI module.
     *
     * Note:            The format of configuration words is chosen for backward compatibility reasons.
     *                  The config words don't reflect the actual register bits.
     *
     * Example:         OpenSPI1(SPI_MODE32_ON|SPI_SMP_ON|MASTER_ENABLE_ON|SEC_PRESCAL_1_1|PRI_PRESCAL_1_1, SPI_ENABLE);
     ********************************************************************/
    void    OpenSPI1(unsigned int config1, unsigned int config2);


    /* CloseSPI. Disables SPI module */
    /*********************************************************************
     * Function:        void CloseSPI1(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This routine disables the SPI module and clears its interrupt bits.
     *
     * Note:            None
     *
     * Example:         CloseSPI1();
     ********************************************************************/
    #define CloseSPI1() (SPI1CONCLR=_SPI2CON_ON_MASK, mSPI1IntDisable(), mSPI1ClearAllIntFlags())
                        // disable the module; disable all ints; clear any existing event

    /* ConfigIntSPI. Configure Interrupt enable and priorities */
    /*********************************************************************
     * Function:        void ConfigIntSPI1( unsigned int config)
     *
     * PreCondition:    None
     *
     * Input :          config  - SpiConfigInt value having the following fields:
     *                              - ipl:  3       the interrupt priority level
     *                              - ispl: 2       the interrupt sub-priority level
     *                              - fie:  1       fault interrupt enable/disable
     *                              - txie: 1       tx interrupt enable/disable
     *                              - rxie: 1       rx interrupt enable/disable
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function Configures Interrupt and sets the Interrupt Priority
     *
     * Note:            None
     *
     * Example:         ConfigIntSPI1(SPI_FAULT_INT_EN|SPI_INT_EN|SPI_INT_PRI_0|SPI_INT_SUB_PRI_2);
     ********************************************************************/
    #define ConfigIntSPI1(config) (mSPI1IntDisable(), mSPI1ClearAllIntFlags(), mSPI1SetIntPriority((config)&0x7), \
                mSPI1SetIntSubPriority(((config)&0x18)>>3), mSPI1SetIntEnable(((config)&0xe0)>>5))
                            // disable all ints, clear any existing event, set new priority, sub-priority, set (rxie, txie, fie)



    /* Enable/Disable interrupts and set Interrupt priority of SPI */

    /*********************************************************************
     * Macro:        EnableIntSPI1
     *
     * PreCondition:    None
     *
     * Input :          None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function enables the receive and transmit interrupts for SPI 1
     *
     * Note:            None
     *
     * Example:         EnableIntSPI1;
     ********************************************************************/
    #define EnableIntSPI1   (mSPI1ClearAllIntFlags(), mSPI1RXIntEnable(1), mSPI1TXIntEnable(1) )
                            // clear int flags, enable rx and tx interrupts


    /*********************************************************************
     * Macro:        DisableIntSPI1
     *
     * PreCondition:    None
     *
     * Input :          None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function disables the receive and transmit interrupts for SPI 1
     *
     * Note:            None
     *
     * Example:         DisableIntSPI1;
     ********************************************************************/
    #define DisableIntSPI1  (mSPI1ClearAllIntFlags(), mSPI1RXIntEnable(0), mSPI1TXIntEnable(0) )
                            // clear int flags, disable rx and tx interrupts



    /*********************************************************************
     * Function:        void SetPriorityIntSPI1(int priority)
     *
     * PreCondition:    None
     *
     * Input :          priority    - new priority for the SPI channel:
     *                          0ne of the values SPI_INT_PRI_0 to SPI_INT_PRI_7
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function sets the priority interrupt for SPI channel 1
     *
     * Note:            None
     *
     * Example:         SetPriorityIntSPI1(SPI_INT_PRI_0);
     ********************************************************************/
    #define SetPriorityIntSPI1(priority)    (mSPI1SetIntPriority(priority))

    /*********************************************************************
     * Function:        void SetSubPriorityIntSPI1(int subPriority)
     *
     * PreCondition:    None
     *
     * Input :          subPriority - new sub-priority for the SPI channel:
     *                          0ne of the values SPI_INT_SUB_PRI_0 to SPI_INT_SUB_PRI_3
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function sets the sub-priority interrupt for SPI channel 1
     *
     * Note:            None
     *
     * Example:         SetSubPriorityIntSPI1(SPI_INT_SUB_PRI_3);
     ********************************************************************/
    #define SetSubPriorityIntSPI1(subPriority)  (mSPI1SetIntSubPriority(((subPriority)&0x18)>>3))


    /* DataRdySPI. Test if receive data available */
    /*********************************************************************
     * Function:        int DataRdySPI1(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          TRUE if data is available (Receiver Buffer Full), FALSE otherwise
     *
     * Side Effects:    None
     *
     * Overview:        Determine if there is a data to be read from the SPIBUF register.
     *
     * Note:            None
     *
     * Example:         if(DataRdySPI1()){...}
     ********************************************************************/
    #define DataRdySPI1() (SPI1STATbits.SPIRBF)



    /* TxBufFullSPI. Test if transmit buffer is full */
    /*********************************************************************
     * Function:        int TxBufFullSPI1(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          TRUE if SPI buffer is full and data cannot be written to device, in order to be serialized, FALSE otherwise
     *
     * Side Effects:    None
     *
     * Overview:        Determine if the data can be written to the SPIBUF register without overwriting
     *                  the previous, unsent data.
     *
     * Note:            None
     *
     * Example:         if(!TxBufFullSPI1()){WriteSPI1('a');}
     ********************************************************************/
    #define TxBufFullSPI1() (!SPI1STATbits.SPITBE)



    /* ReadSPI.Read byte/word from SPIBUF register */
    /*********************************************************************
     * Function:         unsigned int ReadSPI1(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          Returns the contents of SPIBUF register in byte/hword/word format
     *
     * Side Effects:    None
     *
     * Overview:        This function will read single byte/half word/word from SPI receive register.
     *
     * Note:            User interface is always 32 bits.
     *
     * Example:         int data=ReadSPI1();
     ********************************************************************/
    #define ReadSPI1()  (SPI1BUF)

    /* WriteSPI. Write byte/word directly to SPIBUF register */
    /*********************************************************************
     * Function:         void WriteSPI1(unsigned int data_out)
     *
     * PreCondition:    None
     *
     * Input:           data_out    - Single data byte/half word/word for SPI bus
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This routine writes a single byte/half word/word to the SPI bus.
     *
     * Note:            None.
     *
     * Example:         WriteSPI1(0x4433);
     ********************************************************************/
    #define WriteSPI1(data_out) (SPI1BUF=(data_out))


    /* getcSPI. Wait character available and read from SPIBUF register */
    /*********************************************************************
     * Function:         unsigned int getcSPI1(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          the contents of SPIBUF register in byte/hword/word format
     *
     * Side Effects:    None
     *
     * Overview:        This function waits for receive data to be available.
     *                  It will then read single byte/half word/word from SPI bus.
     *
     * Note:            byte/hword/word accesses will perform correctly.
     *
     *                  When a new data word has been shifted into shift register SPIxSR and
     *                  the previous contents of receive register SPIxRXB have not been read
     *                  by the user software, then SPIROV bit (SPIxSTAT<6>) will be set.The
     *                  module will not transfer the received data from SPIxSR to the SPIxRXB.
     *                  Further data reception is disabled until the SPIROV bit is cleared.
     *                  The SPIROV bit is not cleared automatically by the module and must be
     *                  cleared by the user software.
     *
     * Example:         int data=getcSPI1();
     ********************************************************************/
    unsigned int getcSPI1(void);


    /* putcSPI. Wait for buffer empty and write byte/word to SPIBUF register */
    /*********************************************************************
     * Function:         void putcSPI1(unsigned int data_out)
     *
     * PreCondition:    None
     *
     * Input:           data_out    - Single data byte/half word/word for SPI bus
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This routine writes a single byte/half word/word to the SPI bus.
     *                  It waits so that it doesn't overwrite the previous untransmitted data.
     *
     * Note:            byte/hword/word accesses will perform correctly.
     *
     * Example:         putcSPI1(0xaa);
     ********************************************************************/
    #define putcSPI1(data_out)  do{while(!SPI1STATbits.SPITBE); SPI1BUF=(data_out); }while(0)


    /* getsSPI.Read string from SPIBUF */
    /*********************************************************************
     * Function:        unsigned int getsSPI1(unsigned int length, unsigned int *rdptr,
     *                                          unsigned int spi_data_wait)
     *
     * PreCondition:    rdptr   - valid pointer
     *
     * Input:           length          - The length of data expected
     *                  rdptr           - the received data to be recorded to this array
     *                  spi_data_wait   - timeout value
     *
     * Output:          number of data bytes yet to be received
     *
     * Side Effects:    None
     *
     * Overview:        This routine reads a string from the SPI receive buffer.
     *                  The number of byte/word to be read is determined by parameter 'length'.
     *
     * Note:            rdptr is considered to be 8/16/32 bits data pointer, according to the
     *                  current SPI mode!
     *                  When a new data word has been shifted into shift register SPIxSR and
     *                  the previous contents of receive register SPIxRXB have not been read
     *                  by the user software, then SPIROV bit (SPIxSTAT<6>) will be set.The
     *                  module will not transfer the received data from SPIxSR to the SPIxRXB.
     *                  Further data reception is disabled until the SPIROV bit is cleared.
     *                  The SPIROV bit is not cleared automatically by the module and must be
     *                  cleared by the user software.
     *
     * Example:         getsSPI1(sizeof(buff), buff, 1000);
     ********************************************************************/
    unsigned int    getsSPI1(unsigned int length, unsigned int *rdptr, unsigned int spi_data_wait);


    /* putsSPI Write string to SPIBUF */
    /*********************************************************************
     * Function:        void putsSPI1(unsigned int length, unsigned int *wrptr)
     *
     * PreCondition:    wrptr   - valid pointer
     *
     * Input:           length  - length of bytes/words to be written
     *                  wrptr   - address of buffer storing the data to be transmitted.
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function writes the specified length of data words/bytes
     *                  from the specified buffer.
     *
     * Note:            wrptr is considered to be 8/16/32 bits data pointer, according to the
     *                  current SPI mode!
     *
     * Example:         putsSPI1(sizeof(buf), buf);
     ********************************************************************/
    void    putsSPI1(unsigned int length, unsigned int *wrptr);

#endif  // _SPI1

#ifdef _SPI2
    /* OpenSPI */
    /*********************************************************************
     * Function:        void OpenSPI2(unsigned int config1,unsigned int config2)
     *
     * Condition:       None
     *
     * Input:           config1 - sets the module behavior using the SpiOpenConfig1 bits:
     *                      typedef union
     *                      {
     *                          struct
     *                          {
     *                              unsigned PPRE:      2;      // primary prescaler
     *                              unsigned SPRE:      3;      // secondary prescaler
     *                              unsigned MSTEN:     1;      // master mode enable
     *                              unsigned CKP:       1;      // clock polarity
     *                              unsigned SSEN:      1;      // slave select
     *                              unsigned CKE:       1;      // clock edge
     *                              unsigned SMP:       1;      // sample phase
     *                              unsigned MODE16:    1;      // word/hword/byte communication select
     *                              unsigned MODE32:    1;      // word/hword/byte communication select
     *                              unsigned DISSDO:    1;      // disable SDO pin
     *                              unsigned:           17;     // reserved
     *                              unsigned FRMSYNC:   1;      // frame sync direction
     *                              unsigned FRMEN:     1;      // framed SPI
     *                          };                              // field access
     *                          unsigned int            w;      // word access
     *                      }SpiOpenConfig1;
     *
     *                  config2 - sets the module behavior using the SpiOpenConfig2 bits:
     *                      typedef union
     *                      {
     *                          struct
     *                          {
     *                              unsigned:           6;      // reserved
     *                              unsigned SPIROV:    1;      // receiver overflow
     *                              unsigned:           6;      // reserved
     *                              unsigned SIDL:      1;      // stop in idle
     *                              unsigned:           1;      //
     *                              unsigned ON:        1;      // enable peripheral
     *                              unsigned:           1;      // reserved
     *                              unsigned SPIFE:     1;      // frame edge select
     *                              unsigned:           11;     //
     *                              unsigned FRMPOL:    1;      // frame sync polarity
     *                          };                              // field access
     *                          unsigned int            w;      // word access
     *                      }SpiOpenConfig2;
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function initializes and enables the SPI module.
     *
     * Note:            The format of configuration words is chosen for backward compatibility reasons.
     *                  The config words don't reflect the actual register bits.
     *
     * Example:         OpenSPI2(SPI_MODE32_ON|SPI_SMP_ON|MASTER_ENABLE_ON|SEC_PRESCAL_1_1|PRI_PRESCAL_1_1, SPI_ENABLE);
     ********************************************************************/
    void    OpenSPI2(unsigned int config1, unsigned int config2 );


    /* CloseSPI. Disables SPI module */
    /*********************************************************************
     * Function:        void CloseSPI2(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This routine disables the SPI module and its interrupt bits.
     *
     * Note:            None
     *
     * Example:         CloseSPI2();
     ********************************************************************/
    #define CloseSPI2() (SPI2CONCLR=_SPI2CON_ON_MASK, mSPI2IntDisable(), mSPI2ClearAllIntFlags())
                         // disable the module; disable all ints; clear any existing event



    /* ConfigIntSPI. Configure Interrupt enable and priorities */
    /*********************************************************************
     * Function:        void ConfigIntSPI2( unsigned int config)
     *
     * PreCondition:    None
     *
     * Input :          config  - SpiConfigInt value having the following fields:
     *                              - ipl:  3       the interrupt priority level
     *                              - ispl: 2       the interrupt sub-priority level
     *                              - fie:  1       fault interrupt enable/disable
     *                              - txie: 1       tx interrupt enable/disable
     *                              - rxie: 1       rx interrupt enable/disable
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function Configures Interrupt and sets the Interrupt Priority
     *
     * Note:            None
     *
     * Example:         ConfigIntSPI2(SPI_FAULT_INT_EN|SPI_INT_EN|SPI_INT_PRI_0|SPI_INT_SUB_PRI_3);
     ********************************************************************/
    #define ConfigIntSPI2(config) (mSPI2IntDisable(), mSPI2ClearAllIntFlags(), mSPI2SetIntPriority((config)&0x7), \
                    mSPI2SetIntSubPriority(((config)&0x18)>>3), mSPI2SetIntEnable(((config)&0xe0)>>5) )
                            // disable all ints, clear any existing event, set new priority, sub-priority, set (rxie, txie, fie)

    /* Enable/Disable interrupts and set Interrupt priority of SPI */
    /*********************************************************************
     * Macro:        EnableIntSPI2
     *
     * PreCondition:    None
     *
     * Input :          None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function enables the receive and transmit interrupts for SPI 2
     *
     * Note:            None
     *
     * Example:         EnableIntSPI2;
     ********************************************************************/
    #define EnableIntSPI2   (mSPI2ClearAllIntFlags(), mSPI2RXIntEnable(1), mSPI2TXIntEnable(1) )
                            // clear int flags, enable rx and tx interrupts

    /*********************************************************************
     * Macro:        DisableIntSPI2
     *
     * PreCondition:    None
     *
     * Input :          None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function disables the receive and transmit interrupts for SPI 2
     *
     * Note:            None
     *
     * Example:         DisableIntSPI2;
     ********************************************************************/
    #define DisableIntSPI2  (mSPI2ClearAllIntFlags(), mSPI2RXIntEnable(0), mSPI2TXIntEnable(0) )
                            // clear int flags, disable rx and tx interrupts

    /*********************************************************************
     * Function:        void SetPriorityIntSPI2(int priority)
     *
     * PreCondition:    None
     *
     * Input :          priority    - new priority for the SPI channel:
     *                          0ne of the values SPI_INT_PRI_0 to SPI_INT_PRI_7
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function sets the priority interrupt for SPI channel 2
     *
     * Note:            None
     *
     * Example:         SetPriorityIntSPI2(SPI_INT_PRI_0);
     ********************************************************************/
    #define SetPriorityIntSPI2(priority)    (mSPI2SetIntPriority(priority))


    /*********************************************************************
     * Function:        void SetSubPriorityIntSPI2(int subPriority)
     *
     * PreCondition:    None
     *
     * Input :          subPriority - new sub-priority for the SPI channel:
     *                          0ne of the values SPI_INT_SUB_PRI_0 to SPI_INT_SUB_PRI_3
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function sets the sub-priority interrupt for SPI channel 2
     *
     * Note:            None
     *
     * Example:         SetSubPriorityIntSPI2(SPI_INT_SUB_PRI_3);
     ********************************************************************/
    #define SetSubPriorityIntSPI2(subPriority)  (mSPI2SetIntSubPriority(((subPriority)&0x18)>>3))


    /* DataRdySPI. Test if receive data available */
    /*********************************************************************
     * Function:        int DataRdySPI2(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          TRUE if data is available (Receiver Buffer Full), FALSE otherwise
     *
     * Side Effects:    None
     *
     * Overview:        Determine if there is a data to be read from the SPIBUF register.
     *
     * Note:            None
     *
     * Example:         if(DataRdySPI2()){...}
     ********************************************************************/
    #define DataRdySPI2() (SPI2STATbits.SPIRBF)

    /* TxBufFullSPI. Test if transmit buffer is full */
    /*********************************************************************
     * Function:        int TxBufFullSPI2(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          TRUE if SPI buffer is full and data cannot be written to device, in order to be serialized, FALSE otherwise
     *
     * Side Effects:    None
     *
     * Overview:        Determine if the data can be written to the SPIBUF register without overwriting
     *                  the previous, unsent data.
     *
     * Note:            None
     *
     * Example:         if(!TxBufFullSPI2()){WriteSPI2('a');}
     ********************************************************************/
    #define TxBufFullSPI2() (!SPI2STATbits.SPITBE)


    /* ReadSPI.Read byte/word from SPIBUF register */
    /*********************************************************************
     * Function:         unsigned int ReadSPI2(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          Returns the contents of SPIBUF register in byte/hword/word format
     *
     * Side Effects:    None
     *
     * Overview:        This function will read single byte/half word/word from SPI receive register.
     *
     * Note:            User interface is always 32 bits.
     *
     * Example:         int data=ReadSPI2();
     ********************************************************************/
    #define ReadSPI2()  (SPI2BUF)

    /* WriteSPI. Write byte/word directly to SPIBUF register */
    /*********************************************************************
     * Function:         void WriteSPI2(unsigned int data_out)
     *
     * PreCondition:    None
     *
     * Input:           data_out    - Single data byte/half word/word for SPI bus
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This routine writes a single byte/half word/word to the SPI bus.
     *
     * Note:            None.
     *
     * Example:         WriteSPI2(0x4433);
     ********************************************************************/
    #define WriteSPI2(data_out) (SPI2BUF=(data_out))

    /* getcSPI. Wait character available and read from SPIBUF register */
    /*********************************************************************
     * Function:         unsigned int getcSPI2(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          the contents of SPIBUF register in byte/hword/word format
     *
     * Side Effects:    None
     *
     * Overview:        This function waits for receive data to be available.
     *                  It will then read single byte/half word/word from SPI bus.
     *
     * Note:            byte/hword/word accesses will perform correctly.
     *
     *                  When a new data word has been shifted into shift register SPIxSR and
     *                  the previous contents of receive register SPIxRXB have not been read
     *                  by the user software, then SPIROV bit (SPIxSTAT<6>) will be set.The
     *                  module will not transfer the received data from SPIxSR to the SPIxRXB.
     *                  Further data reception is disabled until the SPIROV bit is cleared.
     *                  The SPIROV bit is not cleared automatically by the module and must be
     *                  cleared by the user software.
     *
     * Example:         int data=getcSPI2();
     ********************************************************************/
    unsigned int    getcSPI2(void);

    /* putcSPI. Wait for buffer empty and write byte/word to SPIBUF register */
    /*********************************************************************
     * Function:         void putcSPI2(unsigned int data_out)
     *
     * PreCondition:    None
     *
     * Input:           data_out    - Single data byte/half word/word for SPI bus
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This routine writes a single byte/half word/word to the SPI bus.
     *                  It waits so that it doesn't overwrite the previous untransmitted data.
     *
     * Note:            byte/hword/word accesses will perform correctly.
     *
     * Example:         putcSPI2(0xaa);
     ********************************************************************/
    #define putcSPI2(data_out)  do{while(!SPI2STATbits.SPITBE); SPI2BUF=(data_out); }while(0)

    /* getsSPI.Read string from SPIBUF */
    /*********************************************************************
     * Function:        unsigned int getsSPI2(unsigned int length, unsigned int *rdptr,
     *                                          unsigned int spi_data_wait)
     *
     * PreCondition:    rdptr   - valid pointer
     *
     * Input:           length          - The length of data expected
     *                  rdptr           - the received data to be recorded to this array
     *                  spi_data_wait   - timeout value
     *
     * Output:          number of data bytes yet to be received
     *
     * Side Effects:    None
     *
     * Overview:        This routine reads a string from the SPI receive buffer.
     *                  The number of byte/word to be read is determined by parameter 'length'.
     *
     * Note:            rdptr is considered to be 8/16/32 bits data pointer, according to the
     *                  current SPI mode!
     *                  When a new data word has been shifted into shift register SPIxSR and
     *                  the previous contents of receive register SPIxRXB have not been read
     *                  by the user software, then SPIROV bit (SPIxSTAT<6>) will be set.The
     *                  module will not transfer the received data from SPIxSR to the SPIxRXB.
     *                  Further data reception is disabled until the SPIROV bit is cleared.
     *                  The SPIROV bit is not cleared automatically by the module and must be
     *                  cleared by the user software.
     *
     * Example:         getsSPI2(sizeof(buff), buff, 1000);
     ********************************************************************/
    unsigned int    getsSPI2(unsigned int length, unsigned int *rdptr, unsigned int spi_data_wait);


    /* putsSPI Write string to SPIBUF */
    /*********************************************************************
     * Function:        void putsSPI2(unsigned int length, unsigned int *wrptr)
     *
     * PreCondition:    wrptr   - valid pointer
     *
     * Input:           length  - length of bytes/words to be written
     *                  wrptr   - address of buffer storing the data to be transmitted.
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function writes the specified length of data words/bytes
     *                  from the specified buffer.
     *
     * Note:            wrptr is considered to be 8/16/32 bits data pointer, according to the
     *                  current SPI mode!
     *
     * Example:         putsSPI2(sizeof(buf), buf);
     ********************************************************************/
    void    putsSPI2(unsigned int length, unsigned int *wrptr);

#endif  // _SPI2




#endif /*_SPI_LEGACY_H_*/

