/*************************************************************
SPI.C

This program contains SPI routines.

Written for Hi-Tech PICC compiler vX.XX
**************************************************************/
#include <pic.h>
#include "SPI.H"

/********************************************************************
*   Function Name:  OpenSPI                                         *
*   Return Value:   void                                            *
*   Parameters:     SSP peripheral setup bytes                      *
*   Description:    This function sets up the SSP1 module on a      * 
*                   PIC16 device for use with a Microchip SPI			  *
*                   EEPROM device or SPI bus device.                *
********************************************************************/
void OpenSPI( unsigned char sync_mode, unsigned char bus_mode, unsigned char smp_phase)
{
  SSPSTAT &= 0x3F;        // power on state 
  SSPCON = 0x00;          // power on state
  SSPCON |= sync_mode; 	  // select serial mode 
  SSPSTAT |= smp_phase;   // select data input sample phase

  switch( bus_mode )
  {
    case 0:               // SPI1 bus mode 0,0
      CKE = 1;       			// data transmitted on rising edge
      CKP = 0;       			// clock idle state low
      break;         			
    case 2:          		  // SPI1 bus mode 1,0 (Not used in the MCP23X17)
      CKE = 1;       			// data transmitted on falling edge
      CKP = 1;       			// clock idle state high
      break;         			
    case 3:		      		  // SPI1 bus mode 1,1
      CKE = 0;		   			// data transmitted on rising edge
      CKP = 1;    	 			// clock idle state high
      break;
    default:              // default SPI1 bus mode 0,1
      break;
  }
  SSPCON |= SSPENB;       // enable synchronous serial port 
}

/********************************************************************
*     Function Name:    WriteSPI                                    *
*     Return Value:     Status byte for WCOL detection.             *
*     Parameters:       Single data byte for SPI bus.               *
*     Description:      This routine writes a single byte to the    * 
*                       SPI bus.                                    *
********************************************************************/
unsigned char WriteSPI( unsigned char data_out )
{
  SSPBUF = data_out;      // write byte to SSPBUF register
  if ( SSPCON & 0x80 )    // test if write collision occurred
   return ( -1 );         // if WCOL bit is set return negative #
  else
  {
    while( !BF );         // wait until bus cycle complete 
  }
  SSPIF = 0;
  return ( 0 );           // if WCOL bit is not set return non-negative#
}

/********************************************************************
*     Function Name:    ReadSPI                                     *
*     Return Value:     contents of SSPBUF register                 *
*     Parameters:       void                                        *
*     Description:      Read single byte from SPI bus.              *
********************************************************************/
unsigned char ReadSPI( void )
{
  SSPBUF = 0x00;          // initiate bus cycle
  while ( !BF );          // wait until cycle complete
  return ( SSPBUF );      // return with byte read 
}
