/*
 * acc_mma7455_avr.c
 *
 * Created: 25/11/2014 05:00:01 PM
 *  Author: Avinash
 */ 

#include "acc_mma7455_avr.h"
#include "i2c_avr.h"

uint8_t MMA7455Init(uint8_t range)
{
	//Initialize I2C Bus
	I2CInit();
	
	uint8_t res; //Result of commands (success or fail)
	
	//Bring device out of standby to measurement mode
	res=MMA7455SetMode(MMA7455_MODE_MEASURE);
	
	//operation failed
	if(res==FALSE) return FALSE;
	
	//Set range
	res=MMA7455SetRange(range);
	
	//operation failed
	if(res==FALSE) return FALSE;
	
	return TRUE;	
}

uint8_t MMA7455ReadReg	(uint8_t address,uint8_t *data)
{
	uint8_t res;	//result
	
	//Start
	I2CStart();
	
	//SLA+W (for dummy write to set register pointer)
	res=I2CWriteByte(MMA7455_ADDRESS<<1);	//DS1307 address + W
	
	//Error
	if(!res)	return FALSE;
	
	//Now send the address of required register
	res=I2CWriteByte(address);
	
	//Error
	if(!res)	return FALSE;
	
	//Repeat Start
	I2CStart();
	
	//SLA + R
	res=I2CWriteByte((MMA7455_ADDRESS<<1)|1);	//DS1307 Address + R
	
	//Error
	if(!res)	return FALSE;
	
	//Now read the value with NACK
	res=I2CReadByte(data,0);
	
	//Error
	if(!res)	return FALSE;
	
	//STOP
	I2CStop();
	
	return TRUE;
	
}

uint8_t MMA7455WriteReg	(uint8_t address,uint8_t data)
{
	uint8_t res;	//result
	
	//Start
	I2CStart();
	
	//SLA+W
	res=I2CWriteByte(MMA7455_ADDRESS<<1);	//DS1307 address + W
	
	//Error
	if(!res)	return FALSE;
	
	//Now send the address of required register
	res=I2CWriteByte(address);
	
	//Error
	if(!res)	return FALSE;
	
	//Now write the value
	res=I2CWriteByte(data);
	
	//Error
	if(!res)	return FALSE;
	
	//STOP
	I2CStop();
	
	return TRUE;
	
}

uint8_t MMA7455SetMode(uint8_t mode)
{
	uint8_t MCR;
	
	uint8_t res;	//result of register read/write operation
	
	res=MMA7455ReadReg(MMA7455_REG_MCR,&MCR);
	
	//operation failed
	if(res==FALSE) return FALSE;
	
	switch(mode)
	{
		case MMA7455_MODE_STANDBY:
			MCR&=~((1<<MMA7455_BIT_MODE1)|(1<<MMA7455_BIT_MODE0));
			break;
		
		case MMA7455_MODE_MEASURE:
				MCR&=~(1<<MMA7455_BIT_MODE1);//clear
				MCR|=(1<<MMA7455_BIT_MODE0);//set
			break;
			
		case MMA7455_MODE_LEVEL:
			MCR|=(1<<MMA7455_BIT_MODE1);//SET
			MCR&=~(1<<MMA7455_BIT_MODE0);//CLEAR
			break;
		
		case MMA7455_MODE_PULSE:
			MCR|=((1<<MMA7455_BIT_MODE1)|(1<<MMA7455_BIT_MODE0));//set
			break;
	}
	
	res=MMA7455WriteReg(MMA7455_REG_MCR,MCR);
	
	//operation failed
	if(res==FALSE) return FALSE;
	
	return TRUE;
}

uint8_t MMA7455SetRange(uint8_t range)
{
	uint8_t MCR;
	
	uint8_t res;	//result of register read/write operation
	
	res=MMA7455ReadReg(MMA7455_REG_MCR,&MCR);
	
	//operation failed
	if(res==FALSE) return FALSE;
	
	switch(range)
	{
		case MMA7455_RANGE_2G:
			MCR|=(1<<MMA7455_BIT_GLVL0);	//set
			MCR&=~(1<<MMA7455_BIT_GLVL1);	//clear
		break;
		
		case MMA7455_RANGE_4G:
			MCR&=~(1<<MMA7455_BIT_GLVL0);	//clear
			MCR|=(1<<MMA7455_BIT_GLVL1);	//set
		break;
		
		case MMA7455_RANGE_8G:
			MCR&=~((1<<MMA7455_BIT_GLVL1)|(1<<MMA7455_BIT_GLVL0));
		break;
	}
	
	res=MMA7455WriteReg(MMA7455_REG_MCR,MCR);
	
	//operation failed
	if(res==FALSE) return FALSE;
	
	return TRUE;
}

uint8_t MMA7455IsDataReady()
{
	uint8_t STATUS;
	MMA7455ReadReg(MMA7455_REG_STATUS,&STATUS);
	
	return(STATUS & (1<<MMA7455_BIT_DRDY));
}

int8_t MMA7455GetX()
{
	uint8_t x;
	MMA7455ReadReg(0x06,&x);
	x=x+10;
	return x;
}

int8_t MMA7455GetY()
{
	uint8_t y;
	MMA7455ReadReg(0x07,&y);
	y=y+21;
	return y;
}

int8_t MMA7455GetZ()
{
	uint8_t z;
	MMA7455ReadReg(0x08,&z);
	z=z-2;
	return z;
}

