#ifndef SPIDRIVER_H
#define SPIDRIVER_H

// Standar library includes
#include	<stdlib.h>	// Only for NULL define


//#include "SPI.h"
#include "pin.h"


#define		SPIX_MAX		0x02	// number of SPI modules
#define		SPIX_NEXT_FREE_MODULE	-1;


#define  DISABLE_SCK_PIN     	0xffff
#define  ENABLE_SCK_PIN      	0xefff

#define  DISABLE_SDO_PIN        0xffff
#define  ENABLE_SDO_PIN         0xf7ff

#define  SPI_MODE16_ON          0xffff
#define  SPI_MODE16_OFF         0xfbff

#define  SPI_SMP_ON             0xffff
#define  SPI_SMP_OFF            0xfdff

#define  SPI_CKE_ON             0xffff
#define  SPI_CKE_OFF            0xfeff

#define  SLAVE_ENABLE_ON        0xffff
#define  SLAVE_ENABLE_OFF       0xff7f

#define  CLK_POL_ACTIVE_LOW     0xffff
#define  CLK_POL_ACTIVE_HIGH    0xffbf

#define  MASTER_ENABLE_ON       0xffff
#define  MASTER_ENABLE_OFF      0xffdf

#define  SEC_PRESCAL_1_1        0xffff
#define  SEC_PRESCAL_2_1        0xfffb
#define  SEC_PRESCAL_3_1        0xfff7
#define  SEC_PRESCAL_4_1        0xfff3
#define  SEC_PRESCAL_5_1        0xffef
#define  SEC_PRESCAL_6_1        0xffeb
#define  SEC_PRESCAL_7_1        0xffe7
#define  SEC_PRESCAL_8_1        0xffe3

#define  PRI_PRESCAL_1_1        0xffff
#define  PRI_PRESCAL_4_1        0xfffe
#define  PRI_PRESCAL_16_1       0xfffd
#define  PRI_PRESCAL_64_1       0xfffc

#define  FRAME_ENABLE_ON        0xffff
#define  FRAME_ENABLE_OFF       0x7fff

#define  FRAME_SYNC_INPUT       0xffff
#define  FRAME_SYNC_OUTPUT      0xbfff

#define  FRAME_POL_ACTIVE_HIGH  0xffff
#define  FRAME_POL_ACTIVE_LOW   0xdfff

#define  FRAME_SYNC_EDGE_COINCIDE 0xffff
#define  FRAME_SYNC_EDGE_PRECEDE  0xfffd

#define  FIFO_BUFFER_ENABLE  	0xffff
#define  FIFO_BUFFER_DISABLE 	0xfffe

#define  SPI_ENABLE             0xffff
#define  SPI_DISABLE            0x7fff

#define  SPI_IDLE_CON           0xdfff
#define  SPI_IDLE_STOP          0xffff

#define  SPI_RX_OVFLOW_CLR      0xffbf

#define FIFO_BUF_LEN_1      	0xfff8
#define FIFO_BUF_LEN_2      	0xfff9
#define FIFO_BUF_LEN_3      	0xfffa
#define FIFO_BUF_LEN_4      	0xfffb
#define FIFO_BUF_LEN_5      	0xfffc
#define FIFO_BUF_LEN_6      	0xfffd
#define FIFO_BUF_LEN_7      	0xfffe
#define FIFO_BUF_LEN_8      	0xffff

#define  SPI_INT_EN             0xffff
#define  SPI_INT_DIS            0xfff7

#define  SPI_INT_PRI_0          0xfff8
#define  SPI_INT_PRI_1          0xfff9
#define  SPI_INT_PRI_2          0xfffa
#define  SPI_INT_PRI_3          0xfffb
#define  SPI_INT_PRI_4          0xfffc
#define  SPI_INT_PRI_5          0xfffd
#define  SPI_INT_PRI_6          0xfffe
#define  SPI_INT_PRI_7          0xffff


// Define SPIxSTAT BITS MASK
#define		SPIRBFMASK			0x0001
#define		SPITBFMASK			0x0002
#define		SISEL0MASK			0x0004
#define		SISEL1MASK			0x0008
#define		SISEL2MASK			0x0010
#define		SRXMPTMASK			0x0020
#define		SPIROVMASK			0x0040
#define		SRMPTMASK			0x0080
#define		SPIBEC0MASK			0x0100
#define		SPIBEC1MASK			0x0200
#define		SPIBEC2MASK			0x0400
#define		SPISIDLMASK			0x2000
#define		SPIENMASK			0x8000

// Define SPIxCON1 BITS MASK
#define		PPRE0MASK			0x0001
#define		PPRE1MASK			0x0002
#define		SPRE0MASK			0x0004
#define		SPRE1MASK			0x0008
#define		SPRE2MASK			0x0010
#define		MSTENMASK			0x0020
#define		CKPMASK				0x0040
#define		SSENMASK			0x0080
#define		CKEMASK				0x0100
#define		SMPMASK				0x0200
#define		MODE16MASK			0x0400
#define		DISSDOMASK			0x0800
#define		DISSCKMASK			0x1000

// Define SPIxCON2 BITS MASK
#define		SPIBENMASK			0x0001
#define		SPIFEMASK			0x0002
#define		SPIFPOLMASK			0x2000
#define		SPIFSDMASK			0x4000
#define		FRMENMASK			0x8000

/*
// these macros are declared as a functions.
#define		EnableIntSPIX( this )					( this.pIE |= (this.IEMAKS) )		//(IEC0bits.SPI1IE = 1)
#define		DisableIntSPIX( this )					( this.pIE &= ~(this.IEMASK) )	//(IEC0bits.SPI1IE = 0)
#define		SPIX_Intr_Flag( this )					( this.pIF & (this.IFMASK) )		//SPI1STATbits.SPI1IF
#define		SetPriorityIntSPIX( this, priority )	( *this.pIPC |= ~(*this.pIPC & (0x7<<this->IPCoffset)) | ((priority &0x0007)<<this->IPCoffset ) ) //(IPC2bits.SPI1IP = priority)
#define		SPIX_Clear_Intr_Status_Bit( this )		( this.pIF &= ~(this.IFMASK) )	//(IFS0bits.SPI1IF = 0)
#define		getcSPIX								ReadSPIX
#define		putcSPIX								WriteSPIX
#define		SPIX_Clear_Recv_OV( this )				( (this.pstat) &= ~(0x01<<6) )		//SPI1STATbits.SPIROV = 0
#define		SPIX_Tx_Buf_Full( this )				( this.pstat & (0x01<<1) )			//SPI1STATbits.SPITBF
#define		SPIX_Rx_Buf_Full( this )				( this.pstat & (0x01<<0) )			//SPI1STATbits.SPIRBF
*/



typedef struct{	// cambiar offset por mask
	int moduleID;
	PIN MOSI;
	PIN MISO;
	PIN SCK;
	PIN SS;
	volatile unsigned int *pIPC;
	unsigned int IPCoffset;
	volatile unsigned int *pIE;
	unsigned int IEMASK;
	volatile unsigned int *pIF;
	unsigned int IFMASK;
//	volatile unsigned int *pIFF;			// SPF1 bit is no implemented
//	unsigned int IFFoffset;
	volatile unsigned int *pstat;
	volatile unsigned int *pcon1;
	volatile unsigned int *pcon2;
	volatile unsigned int *pbuf;
}SPIX;


SPIX *SPIXConstruct( int moduleID, PIN *pins );
void SPIXDestruct( SPIX *this );

void SPIXOpen( SPIX *this, unsigned int config1, unsigned int config2, unsigned int config3 );   
void SPIXClose( SPIX *this ) ;
unsigned int SPIXRead(  SPIX *this );
void SPIXWrite( SPIX *this, unsigned int data_out );

unsigned int SPIXGets( SPIX *this, unsigned int length, unsigned int *rdptr, unsigned int spi_data_wait );
void SPIXPuts( SPIX *this, unsigned int length, unsigned int *wrptr );

char SPIXDataRdy( SPIX *this );   
void SPIXConfigInt( SPIX *this, unsigned int config ) ;

void EnableIntSPIX( SPIX *this );
void DisableIntSPIX( SPIX *this );
int SPIX_Intr_Flag( SPIX *this );
void SetPriorityIntSPIX( SPIX *this, int priority );
void SPIX_Clear_Intr_Status_Bit( SPIX *this );
void SPIX_Clear_Recv_OV( SPIX *this );
int SPIX_Tx_Buf_Full( SPIX *this );
int SPIX_Rx_Buf_Full( SPIX *this );

//void _SPIISR()

#endif	// SPIDRIVER_H

