/*******************************************************************
Analog Devices, Inc. All Rights Reserved.

This software is proprietary and confidential.  By using this software
you agree to the terms of the associated Analog Devices License Agreement.

Project Name:  	Power_On_Self_Test

Hardware:		ADSP-BF526 EZ-KIT Lite

Description:	This file is used to initialize everything necessary
				to access the M24C02 flash
*******************************************************************/

/*******************************************************************
*  include files
*******************************************************************/
#if defined(__ADSPBF537__)		/* __ADSPBF537__ */
#include <cdefBF537.h>
#elif defined(__ADSPBF526__)	/* __ADSPBF526__ */
#include <cdefBF526.h>
#elif defined(__ADSPBF518__)	/* __ADSPBF526__ */
#include <cdefBF518.h>
#else
#error *** Processor not supported ***		/* NOT DEFINED */
#endif

#include <ccblkfn.h>
#include <sys\exception.h>
#include "M24C02.h"


/*******************************************************************
*   Function:    m24c02_Reset_TWI
*   Description: reset the TWI interface
*******************************************************************/
void m24c02_Reset_TWI(void)
{
    /* RESET_TWI CONTROLLER */
	*pTWI_CONTROL = RESET_TWI;
	ssync();

	/* CLEAR ALL ERRONOUS CONDITIONS BEFORE ENABLING TWI */
	*pTWI_MASTER_STAT = BUFWRERR | BUFRDERR | LOSTARB | ANAK | DNAK;
	ssync();

	/* CLEAR ALL INTERRUPTS BEFORE ENABLING TWI */
	*pTWI_INT_STAT = SINIT | SCOMP | SERR | SOVF | MCOMP | MERR | XMTSERV | RCVSERV;
	ssync();

	/* FLUSH THE FIFOs - BOTH TX AND RX. */
	*pTWI_FIFO_CTL = XMTFLUSH | RCVFLUSH;
	ssync();
}

/*******************************************************************
*   Function:    SetM24C02Addr
*   Description: write the register address within the M24C02
*******************************************************************/
void SetM24C02Addr(unsigned char RegAddr)
{
	/* Put the address in the FIFO */
	*pTWI_XMT_DATA8 = RegAddr;
	ssync();

	/* Start transmission */
	*pTWI_MASTER_CTL |= MEN;
}

/*******************************************************************
*   Function:    WriteM24C02DataByte
*   Description: writes a byte of Data to the M24C02
*******************************************************************/
void WriteM24C02DataByte(unsigned char DataByte)
{
	/* wait until the FIFO is ready to take more data */
	while (*pTWI_FIFO_STAT == XMTSTAT)
		ssync();

	/* put another byte in the FIFO */
	*pTWI_XMT_DATA8 = DataByte;
	ssync();
}
/*******************************************************************
*   Function:    WriteM24C02
*   Description: do a master mode write to M24C02
*******************************************************************/
void WriteM24C02(unsigned int WriteAddr, unsigned char *TWI_Data_Pointer, unsigned short DataCount)
{
	int i, j;
	unsigned short TotalCount = DataCount + 1;			/* Count of data and device addr byte */
	unsigned char DeviceAddr = M24C02_ADDRESS | (WriteAddr >> 8);

    *pTWI_FIFO_CTL = 0;									/* Clear the bit manually */
	*pTWI_CONTROL = TWI_ENA | PRESCALE_VALUE;			/* PRESCALE = fsclk/10MHz */
	*pTWI_CLKDIV = ((CLKDIV_HI) << 8) | (CLKDIV_LO);	/* For 100KHz SCL speed */

	*pTWI_MASTER_ADDR = DeviceAddr;						/* Target address (7-bits plus the read/write bit the TWI controls */

	*pTWI_MASTER_CTL = (TotalCount<<6);					/* set the length of the entire transfer */

	SetM24C02Addr(WriteAddr);							/* write the M24C02 register address */

    /* start sending the data */
	for (j = 0; j < DataCount; j++)
	{
		WriteM24C02DataByte( TWI_Data_Pointer[j] );
	}

	/* Wait until transmission complete and MCOMP is set */
	while ((*pTWI_INT_STAT & MCOMP) == 0)
		ssync();

	/* service TWI for next transmission */
	*pTWI_INT_STAT = XMTSERV | MCOMP;


	asm("nop;");
	asm("nop;");
	asm("nop;");

}


/*******************************************************************
*   Function:    ReadM24C02
*   Description: do a master mode read of M24C02
*******************************************************************/
void ReadM24C02(unsigned int ReadAddr, unsigned char *TWI_Data_Pointer, unsigned short Count)
{
	int i, j;
	unsigned short usTempData;
	unsigned char DeviceAddr = M24C02_ADDRESS | (ReadAddr >> 8);

	/* First select the Register we will be reading */
	WriteM24C02( ReadAddr, NULL, 0 );

	/* do the read */
    *pTWI_FIFO_CTL = 0;									/* Clear the bit manually */
	*pTWI_CONTROL = TWI_ENA | PRESCALE_VALUE;			/* PRESCALE = fsclk/10MHz */
	*pTWI_CLKDIV = ((CLKDIV_HI) << 8) | (CLKDIV_LO);	/* For 100KHz SCL speed */

	*pTWI_MASTER_ADDR = DeviceAddr;						/* Target address (7-bits plus the read/write bit the TWI controls */

	*pTWI_MASTER_CTL = (Count << 6) | MEN | MDIR;		/* Start transmission */

	/* read our data */
	for (i = 0; i < Count; i++)
	{
		/* wait for data to be in FIFO */
		while (*pTWI_FIFO_STAT == RCV_EMPTY)
			ssync();

		/* read a byte of data from the FIFO */
		*TWI_Data_Pointer++ = *pTWI_RCV_DATA8;
		ssync();
	}

	/* Wait until transmission complete and MCOMP is set */
	while ((*pTWI_INT_STAT & MCOMP) == 0)
			ssync();

	/* service TWI for next transmission */
	*pTWI_INT_STAT = RCVSERV | MCOMP;

	asm("nop;");
	asm("nop;");
	asm("nop;");
}
