/*! \file 
*	\details SRF08 functions and subroutines library file.
*
*	\ingroup WheelchairControl
*	@{
*
*	\ingroup SRF08
*	@{
*/

//Includes
#include "SRF08.h"

//Functions
void I2C_Init(void)	//initializes I2C
{  
  TWSR = 0x00;                         	//prescaler set to 0;
  TWBR = ((F_CPU/SCL_CLOCK)-16)/2;		//F_CPU=16 MHZ, SCL_CLOCK=50 kHz
}

uint8_t I2C_Start(uint8_t address)	//sends start sequence and addresses device
{
	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);	//send START

	while(!(TWCR & (1<<TWINT)));	//wait until START is sent

	if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) //check status register (must mask prescaler bits)
	{
		return TRUE;
	}

	TWDR = address;	//load address

	TWCR = (1<<TWINT) | (1<<TWEN);	//transmit address

	while(!(TWCR & (1<<TWINT)));	//wait until address transmission is completed

	if (((TW_STATUS & 0xF8) != TW_MT_SLA_ACK) && ((TW_STATUS & 0xF8) != TW_MR_SLA_ACK) ) //check status register (with masked prescaler bits)
	{
		return TRUE;
	}

	return FALSE;
}

void I2C_Stop(void)	//sends stop sequence
{
	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); //send STOP
	
	while(TWCR & (1<<TWSTO));	//wait until TWSTO (stop flag) is set
}

uint8_t I2C_Write( uint8_t data )	//writes data to the previously addressed device
{	    
	TWDR = data;	//load data

	TWCR = (1<<TWINT) | (1<<TWEN);	//start data transmission

	while(!(TWCR & (1<<TWINT)));	//wait until transmission is complete

	if((TW_STATUS & 0xF8) != TW_MT_DATA_ACK) //check status register (mask prescaler bits)
	{
		return TRUE;
	}

	return FALSE;
}

uint8_t I2C_ReadAck(void)	//reads data from the previously addressed device, generates ACK bit
{
	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);	//start reading with ACK enabled (TWEA bit is set)

	while(!(TWCR & (1<<TWINT)));    //wait until transmission is complete

    return TWDR;
}

uint8_t I2C_ReadNak(void)	//reads data from the previously addressed device, generates NACK bit
{
	TWCR = (1<<TWINT) | (1<<TWEN);	//start reading with ACK enabled (TWEA bit is set to 0)

	while(!(TWCR & (1<<TWINT)));	//wait until transmission is complete
	
    return TWDR;
}

uint8_t SRF08_Write(uint8_t address, uint8_t reg, uint8_t data)	//writes data to the register of the assigned device; returns FALSE if write is successful / TRUE if write fails 	
{

#ifndef DEBUG

	uint8_t status = I2C_Start(address);       // initialize transmission 

	if (status) 	//status = TRUE -> writing error, wrong connection or unplugged device
	{
        I2C_Stop();			//end of transmission
	}
	else 
	{
        I2C_Write(reg);		//send address of register to be written to
        I2C_Write(data);	//data to be written
        I2C_Stop();   		//end of transmission
	}	

	return status;

#else

	return FALSE;

#endif

}

uint8_t SRF08_Read(uint8_t address, uint8_t reg)	//reads data from the register of the assigned device; returns data / 0 on error
{

#ifndef DEBUG

	uint8_t data;

	data = I2C_Start(address);       // initialize transmission 

	if (data)	//data = 1 -> writing error, wrong connection or unplugged device
	{
        I2C_Stop();			//end of transmission

		return FALSE;
	}
	else 
	{
        I2C_Write(reg);             // write address of the register to write to
        I2C_Start(address + 1);     // set device address and read bit
        data = I2C_ReadNak();      	// read one byte
        I2C_Stop();	
	}	

	return data;

#else

	return FALSE;

#endif

}
