/*
 * GccApplication2.c
 *
 * Created: 12.10.2015 23:04:30
 *  Author: Ichich
 */ 

//I2C-Adresse,bzw TWI-Adresse
#define Mems3D_Addr 0b1101011 
#define Mems3D_Addr_Read 0b11010111
#define Mems3D_Addr_Write 0b11010110

//Registerdefinitionen
#define ACT_THS 0x04

#define ACT_DUR 0x05

#define INT_GEN_CFG_XL 0x06

#define WHO_AM_I 0x0F

#define CTRL_REG1_G 0x10
	#define ODR_G2 7
	#define ODR_G1 6
	#define ODR_G0 5
	#define FS_G1 4
	#define FS_G0 3
	#define BW_G1 1
	#define BW_G0 0

#define CTRL_REG6_XL 0x20
	#define ODR_XL2 7
	#define ODR_XL1 6
	#define ODR_XL0 5
	#define FS1_XL 4
	#define FS0_XL 3
	#define BW_SCAL_ODR 2
	#define BW_XL1 1
	#define BW_XL0 0

#define XHi_Reg 0x18
#define XLo_Reg 0x19

#define YHi_Reg 0x1A
#define YLo_Reg 0x1B

#define ZHi_Reg 0x1C
#define ZLo_Reg 0x1D

//TWSR-Statuscodes (TWSR = TWI-Status-Register)
#define Start_gesendet 0x08
#define RepeatetStart_gesendet 0x10
#define SLA_W_gesendet_SlaveACK 0x18
#define Data_gesendet_ACK 0x28



#define F_CPU 16000000

#ifndef F_CPU
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
   F_CPU im Makefile definiert werden, eine nochmalige Definition
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
   #ifndef/#endif 
 
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
   verwendet wird und dort eine andere, nicht zur Hardware passende 
   Taktrate eingestellt ist: Dann wird die folgende Definition 
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
   noch nicht definiert: */
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 16000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
                         // Ohne ergeben sich unten Fehler in der Berechnung
#endif
 
#define BAUD 9600UL      // Baudrate
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif


#include <avr/io.h>


void uart_init(void);
void TWI_WRITE(uint8_t adresse, uint8_t subadresse, uint8_t data);
uint8_t TWI_READ(uint8_t adresse, uint8_t subadresse);

int main(void)
{	
	uint16_t X = 1000;
	uint8_t Y = 10;
	uint8_t Lesewert = 0;
	
	
	uart_init();
	
	TWBR = 128;
	TWI_WRITE(Mems3D_Addr, CTRL_REG1_G, 0b11000000);
	TWI_WRITE(Mems3D_Addr, CTRL_REG6_XL, 0b11000000);
	
	while(1)
	{
		Lesewert = TWI_READ(Mems3D_Addr, WHO_AM_I);
		UDR0 = Lesewert;
		while(X > 0)
		{
			X--;
		}
		X = 1000;
		
		
		Lesewert = TWI_READ(Mems3D_Addr, XLo_Reg);
		UDR0 = Lesewert;
		while(X > 0)
		{
			X--;
		}
		X = 1000;
		
		Lesewert = TWI_READ(Mems3D_Addr, XHi_Reg);
		UDR0 = Lesewert;
		while(X > 0)
		{
			X--;
		}
		X = 1000;
		
		UDR0 = 13;
		while(X > 0)
		{
			X--;
		}
		X = 1000;
	
	}
}

void TWI_WRITE(uint8_t adresse, uint8_t subadresse, uint8_t data)
{
	TWCR = (1 << TWINT) | (1 << TWSTA) | (1<<TWEN);		//Send START condition
	
	while ( !( TWCR & (1<<TWINT) ) )					//Wait for TWINT Flag set. This	indicates that the START condition has been transmitted
	{
		
	}
	
	if( (TWSR & 0xF8) != Start_gesendet)				//Fehlerbehandlung 
	{
		
	}
	
	adresse = (adresse << 1) | 0;
	TWDR = adresse;
	TWCR = (1<<TWINT) |	(1<<TWEN);						//Load SLA_	W into TWDR	Register. Clear TWINT bit in TWCR to start transmission of address
	
	while (!( TWCR & (1<<TWINT) ))						//Wait for TWINT Flag set. This	indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
	{
		
	}
	
	if ( (TWSR & 0xF8) != SLA_W_gesendet_SlaveACK)					//Fehlerbehandlung
	{
		
	}
	
	TWDR = subadresse;
	TWCR = (1<<TWINT) |	(1<<TWEN);
	
	while( !( TWCR & (1<<TWINT) ) )
	{
		
	}
	
	TWDR = data;
	TWCR = (1<<TWINT) |	(1<<TWEN);
	
	while( !( TWCR & (1<<TWINT) ) )
	{
		
	}
	
	if( (TWSR & 0xF8) != Data_gesendet_ACK)							//Fehlerbehandlung
	{
		
	}
	
	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);				//Transmit STOP condition
}

uint8_t TWI_READ(uint8_t adresse, uint8_t subadresse)
{
	uint8_t wert = 0;
	
	
	TWCR = (1 << TWINT) | (1 << TWSTA) | (1<<TWEN);		//Send START condition
	
	while ( !( TWCR & (1<<TWINT) ) )					//Wait for TWINT Flag set. This	indicates that the START condition has been transmitted
	{
		
	}
	
	if( ( (TWSR & 0xF8) != Start_gesendet ) && ( (TWSR & 0xF8) != RepeatetStart_gesendet ) )				//Fehlerbehandlung
	{
		
	}
	
	adresse = (adresse << 1) | 0;						//SAD+W
	TWDR = adresse;
	TWCR = (1<<TWINT) |	(1<<TWEN);	
	while ( !( TWCR & (1<<TWINT) ) )					//Wait for TWINT Flag set. This	indicates that the START condition has been transmitted
	{
		
	}
	
	TWDR = subadresse;
	TWCR = (1<<TWINT) |	(1<<TWEN);	
	while ( !( TWCR & (1<<TWINT) ) )					//Wait for TWINT Flag set. This	indicates that the START condition has been transmitted
	{
		
	}
	
	TWCR = (1 << TWINT) | (1 << TWSTA) | (1<<TWEN);		//Send Repeated START condition
	
	while ( !( TWCR & (1<<TWINT) ) )					//Wait for TWINT Flag set. This	indicates that the START condition has been transmitted
	{
		
	}
	
	if( ( (TWSR & 0xF8) != Start_gesendet ) && ( (TWSR & 0xF8) != RepeatetStart_gesendet ) )					//Fehlerbehandlung
	{
		
	}
	
	adresse += 1;										//SAD+R
	TWDR = adresse;
	TWCR = (1<<TWINT) |	(1<<TWEN);	
	while ( !( TWCR & (1<<TWINT) ) )					//Wait for TWINT Flag set. This	indicates that the START condition has been transmitted
	{
		
	}
	
	//TWCR |= (1 << TWEA);
	
	wert = TWDR;
	
	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);				//Transmit STOP condition
	//TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
	
	//TWCR = (1 << TWINT) | (1 << TWEN);
	return wert;
	
}

void uart_init(void)
{
	UBRR0 = UBRR_VAL;
	UCSR0B |= (1<<TXEN0);
	// Frame Format: Asynchron 8N1
	UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}