#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include "i2c.h"     // Device Headerfile and Examples Include File

void InitI2CGpio()
{

   EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled disabled by the user.  
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

	GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;    // Enable pull-up for GPIO32 (SDAA)
	GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;	   // Enable pull-up for GPIO33 (SCLA)

/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

	GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;  // Asynch input GPIO32 (SDAA)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;  // Asynch input GPIO33 (SCLA)

/* Configure SCI pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be I2C functional pins.
// Comment out other unwanted lines.

	GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;   // Configure GPIO32 for SDAA operation
	GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;   // Configure GPIO33 for SCLA operation
	
    EDIS;
}


void I2CA_Init(void)
{
	InitI2CGpio();

//	Initialize I2C
	I2caRegs.I2CSAR = 0x0050;		// Slave address - EEPROM control code

 	I2caRegs.I2CMDR.bit.IRS = 0;	// IPSC must be initialized while the I2C module is in reset (IRS = 0 in I2CMDR).
   #if (CPU_FRQ_150MHZ)             // Default - For 150MHz SYSCLKOUT
        I2caRegs.I2CPSC.all = 14;   // Prescaler - need 7-12 Mhz on module clk (150/15 = 10MHz)
   #endif
   #if (CPU_FRQ_100MHZ)             // For 100 MHz SYSCLKOUT
     I2caRegs.I2CPSC.all = 9;	    // Prescaler - need 7-12 Mhz on module clk (100/10 = 10MHz)
   #endif

	I2caRegs.I2CCLKL = 10;			// NOTE: must be non zero
	I2caRegs.I2CCLKH = 5;			// NOTE: must be non zero

	I2caRegs.I2CMDR.all = 0x0000;

	I2caRegs.I2CMDR.bit.MST = 1;

	I2caRegs.I2CMDR.bit.IRS = 1;	// Take I2C out of reset
   									// Stop I2C when suspended
   return;
}


Uint16 I2CA_WriteData(unsigned int Addr, int Data)
{

//	Wait until the STP bit is cleared from any previous master communication.
//	Clearing of this bit by the module is delayed until after the SCD bit is
//	set. If this bit is not checked prior to initiating a new message, the
//	I2C could get confused.
	if (I2caRegs.I2CMDR.bit.STP == 1)
	{
		return I2C_STP_NOT_READY_ERROR;
	}

//	Check if bus busy
	if (I2caRegs.I2CSTR.bit.BB == 1)
	{
		return I2C_BUS_BUSY_ERROR;
	}

//	Setup number of bytes to send
//	MsgBuffer + Address
	I2caRegs.I2CCNT = 4;

//	Send start as master transmitter
	I2caRegs.I2CMDR.all = 0x6E20;

//	Setup data to send
	I2caRegs.I2CDXR = (Addr*2)>>8;
	while(!I2caRegs.I2CSTR.bit.XRDY);
	I2caRegs.I2CDXR = (Addr*2);
	while(!I2caRegs.I2CSTR.bit.XRDY);
	I2caRegs.I2CDXR = Data>>8;
	while(!I2caRegs.I2CSTR.bit.XRDY);
	I2caRegs.I2CDXR = Data;
	while(!I2caRegs.I2CSTR.bit.XRDY);
	while(I2caRegs.I2CMDR.bit.STP == 1);
	while(I2caRegs.I2CSTR.bit.BB == 1);

	return I2C_SUCCESS;
}

#define I2CWAIT 0x0000FFFF;

int I2CA_ReadData(unsigned int Addr)
{
  WORDE data;
  unsigned long I2Cwait;

//	Wait until the STP bit is cleared from any previous master communication.
//	Clearing of this bit by the module is delayed until after the SCD bit is
//	set. If this bit is not checked prior to initiating a new message, the
//	I2C could get confused.
	if (I2caRegs.I2CMDR.bit.STP == 1)
	{
		return I2C_STP_NOT_READY_ERROR;
	}

//	Check if bus busy
	if (I2caRegs.I2CSTR.bit.BB == 1)
	{
		return I2C_BUS_BUSY_ERROR;
	}

	I2caRegs.I2CCNT = 2;
	I2caRegs.I2CMDR.all = 0x6E20;			// Send data to setup EEPROM address 0x6620
	I2caRegs.I2CDXR = (Addr*2)>>8;
	I2Cwait = I2CWAIT;
	while(!I2caRegs.I2CSTR.bit.XRDY && I2Cwait--);
	I2caRegs.I2CDXR = (Addr*2);
	I2Cwait = I2CWAIT;
	while(I2caRegs.I2CMDR.bit.STP == 1 && I2Cwait--);

	I2caRegs.I2CCNT = 2;
	I2caRegs.I2CMDR.all = 0x6C20;			// Send restart as master receiver

	I2Cwait = I2CWAIT;
	while(!I2caRegs.I2CSTR.bit.RRDY && I2Cwait--);
	data.byt.byte_1 = I2caRegs.I2CDRR;
	I2Cwait = I2CWAIT;
	while(!I2caRegs.I2CSTR.bit.RRDY && I2Cwait--);
	data.byt.byte_0 = I2caRegs.I2CDRR;

   return data.all;
}

void I2CA_ReadBlock(unsigned int Addr, unsigned int * Destino, int Cuant)
{
  int i;

	for(i=0;i<Cuant;i++)
	{
		Destino[i] = I2CA_ReadData(Addr++);
		DSP28x_usDelay(500);
	}
}


//===========================================================================
// No more.
//===========================================================================
