diff --git a/csl/stm32f042/Src/imp_i2c.c b/csl/stm32f042/Src/imp_i2c.c
index 387c055..02e9109 100644
--- a/csl/stm32f042/Src/imp_i2c.c
+++ b/csl/stm32f042/Src/imp_i2c.c
@@ -1,17 +1,18 @@
-
 #include "i2c.h"
+#include "usart.h"
 
-#define I2C_BASE ((I2C_TypeDef*)i2cBase_Addr_List[i2cHardware->channelNo])
+#define I2C_BASE ((I2C_TypeDef*)i2cBase_Addr_List[i2c_dev->channelNo])
 
 uint8_t temp8 = 0;
 uint16_t temp16 = 0;
 
-void i2cEnableHardware(i2c_t *i2cHardware)
+void i2c_hardware_enable(i2c_t *i2c_dev)
 {
-	i2cHardwareReset(i2cHardware);
+	i2c_hardware_reset(i2c_dev);		
 
 	// Enables the i2c bus
-	RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2cHardware->channelNo]);
+	RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2c_dev->channelNo]);
+	i2c_dev->hardwareState = i2c_hw_enabled;
 	
 	pinInit(pinA9);
 	pinInit(pinA10);
@@ -19,52 +20,55 @@ void i2cEnableHardware(i2c_t *i2cHardware)
 	pinConfig(pinA10, alternate, openDrain, pullUp, fast);// I2C CSA
 	pinSetAlternate(pinA9, 4); 
 	pinSetAlternate(pinA10, 4);
+	i2c_dev->hardwareState = i2c_hw_ready;
 }	
 
-void i2cHardwareReset(i2c_t *i2cHardware) 
+// Resets the I2C hardware using the reset registers,
+// This will init the device to it's defualt configuration established by STM
+void i2c_hardware_reset(i2c_t *i2c_dev)
 {
-	// Resete the I2C hardware using the reset registers,
-	RCC->APB1RSTR |= (1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
-	RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
+	RCC->APB1RSTR |= (1 << i2cBus_Rst_bitPos[i2c_dev->channelNo]);
+	RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2c_dev->channelNo]); 
+	i2c_dev->hardwareState = i2c_hw_reset;
 }
 
-
-void i2cEnablePeriferal(i2c_t *i2cHardware)
+//enables periferal
+void i2c_periferal_enable(i2c_t *i2c_dev)
 {
 	I2C_BASE->CR1 |= I2C_CR1_PE;
+	i2c_dev->periferalState = i2c_perif_enabled;
+	//Wait untill periferal is ready for communication
+	while(!i2c_is_perif_ready(i2c_dev));
+	i2c_dev->periferalState = i2c_perif_ready;
 }	
 
-void i2cDisablePeriferal(i2c_t *i2cHardware)
+void i2c_periferal_disable(i2c_t *i2c_dev)
 {
 	I2C_BASE->CR1 &= ~I2C_CR1_PE;
+	i2c_dev->periferalState = i2c_perif_disabled;
 }
 
 
-void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode)
+void i2c_set_mode(i2c_t *i2c_dev, i2c_mode_t mode)
 {
 	//This device will set himself automatically to master mode
-	if(i2cHardware->mode == i2cModeMaster)
+	if(i2c_dev->mode == i2c_mode_master)
 	{
 		//Automatic end mode (master mode) disabled Enablede as default 
 		I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND; 
 		//I2C_BASE->CR2 |= I2C_CR2_AUTOEND; 
 	}
-	else if(i2cHardware->mode == i2cModeSlave)
+	else if(i2c_dev->mode == i2c_mode_slave)
 	{
 		// to be written. 
 	}
 }
 
-void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress)
+void i2c_set_address_lenght(i2c_t *i2c_dev, i2c_address_size_t size)
 {
-
-}
-
-void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size)
-{
-	if(i2cHardware->mode == i2cModeMaster)
+	if(i2c_dev->mode == i2c_mode_master)
 	{
-		if(i2cHardware->addressSize == i2cAddressSizeTenBits)
+		if(i2c_dev->addressSize == i2c_address_size_10b)
 		{
 			I2C_BASE->CR2 |= I2C_CR2_ADD10; // 10 Bit addressing
 			I2C_BASE->CR2 &= ~I2C_CR2_HEAD10R; // 7 Bit header read turned on DEFAULT
@@ -75,42 +79,42 @@ void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size)
 			I2C_BASE->CR2 |= I2C_CR2_HEAD10R; // 7 Bit header read turned off DEFAULT
 		}
 	}
-	else if(i2cHardware->mode == i2cModeSlave)
+	else if(i2c_dev->mode == i2c_mode_slave)
 	{
 		// to be written. 
 	}
 }
 
-void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching)
+void i2c_set_clk_stretch(i2c_t *i2c_dev, i2c_clk_stretching_t stretching)
 {
-	if(i2cHardware->stretching == i2cClockStretchingEnable)
+	if(i2c_dev->stretching == i2c_clk_stretching_enable)
 	{
 		I2C_BASE->CR1 &=~ I2C_CR1_NOSTRETCH; 
 	}
-	else if(i2cHardware->stretching == i2cClockStretchingDisable)
+	else if(i2c_dev->stretching == i2c_clk_stretching_disable)
 	{
 		I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH; 
 	}
 }
 
-void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed)
+void i2c_set_clk_speed(i2c_t *i2c_dev, i2c_clk_speed_t speed)
 {
 	switch(speed)
 	{
-		case i2cSpeedStandart:
+		case i2c_clk_speed_standart:
 			I2C_BASE->TIMINGR = 0x2000090E; 
 			break; 
 
-		case i2cSpeedFast:
+		case i2c_clk_speed_fast:
 			break; 
 
-		case i2cSpeedFastPlus:
+		case i2c_clk_speed_fastPlus:
 			break; 
 			
-		case i2cSpeedHightSpeed:
+		case i2c_clk_speed_hightSpeed:
 			break; 
 
-		case i2cSpeedUltraFast:
+		case i2c_clk_speed_ultraFast:
 			break; 
 
 		default: 
@@ -118,213 +122,261 @@ void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed)
 	}
 }
 
-void i2cConfigureFilters(i2c_t *i2cHardware)
+void i2c_set_filter(i2c_t *i2c_dev, uint8_t enable)
 {
-	//Anlalog filter is on
-	I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF; 
+	if(enable)
+	{
+		//Anlalog filter is on
+		I2C_BASE->CR1 &= ~I2C_CR1_ANFOFF; 
+	}
+	else
+	{
+		//Anlalog filter is on
+		I2C_BASE->CR2 |= I2C_CR2_START; 	
+	}
 }	
 
-
 /**************************************************************************************************
 	I2C Hardware functions
 ***************************************************************************************************/
-
-void i2cGenerateStart(i2c_t *i2cHardware)
+void i2c_send_start(i2c_t *i2c_dev)
 {
 	I2C_BASE->CR2 &=~ I2C_CR2_STOP; 
 	I2C_BASE->CR2 |= I2C_CR2_START; 	
-	//Wait until the start condition in generated. 
+	
+	//Wait until the start condition in generated.
+	//Bit 15BUSY: Bus busy
+	//This flag indicates that a communication is in progress on the bus. It is set by hardware when a
+	//START condition is detected. It is cleared by hardware when a Stop condition is detected, or
+	//when PE=0.
 	while(!(I2C_BASE->ISR & (I2C_ISR_BUSY)));
-	i2cHardware->hardwareState = i2cHwStartGenerated;
+	
+	i2c_dev->hardwareState = i2c_hw_sent_start; 
 }
 
-void i2cGenerateStop(i2c_t *i2cHardware)
+void i2c_send_stop(i2c_t *i2c_dev)
 {
 	// Send stop command	
 	I2C_BASE->CR2 |= I2C_CR2_STOP; 
 	I2C_BASE->CR2 &=~ I2C_CR2_START; 
-	i2cHardware->hardwareState = i2cHwStopGenerated;		
+	i2c_dev->hardwareState = i2c_hw_sent_stop; 
 }
 
-void i2cIsPeriferalReady(i2c_t *i2cHardware)
+uint8_t i2c_is_perif_ready(i2c_t *i2c_dev)
 {
-	if((I2C_BASE->ISR & (I2C_ISR_BUSY))!=I2C_ISR_BUSY)
-	{
-		i2cHardware->periferalState = i2cPerifReady;
-	}
+	return ((I2C_BASE->ISR & (I2C_ISR_BUSY))!=I2C_ISR_BUSY);
 }
 
-void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count)
+void i2c_set_tx_counter(i2c_t *i2c_dev, uint8_t count)
 {
 	I2C_BASE->CR2 &= ~(0xFF << I2C_CR2_NBYTES_Pos);
 	I2C_BASE->CR2 |= (count << I2C_CR2_NBYTES_Pos);
 }
 
-void i2cSendSlaveAddressWrite(i2c_t *i2cHardware, uint16_t *slaveAddress)
+void i2c_init_write_command(i2c_t *i2c_dev)
 {
-	// The Slave addrress is automatically place on the output buffer (must be done before the start condition)
-	I2C_BASE->CR2 |= (*slaveAddress & 0xff) << 1; // The bit no 0 is not taken in concideration in 7bit mode	
+	I2C_BASE->CR2 &= ~I2C_CR2_RD_WRN;
+	i2c_dev->hardwareState = i2c_hw_send_write;
+}
+
+void i2c_init_read_command(i2c_t *i2c_dev)
+{
+	I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
+	i2c_dev->hardwareState =i2c_hw_send_read;
+}
+
+
+void i2c_send_address_for_write(i2c_t *i2c_dev, uint16_t *slaveAddress)
+{
+	// Arch nemesis ! We send only one byte of data which is the register adress.
+	i2c_set_tx_counter(i2c_dev,1); 	
 	
 	// On This chip this shoudl be done before the start condition
-	i2cInitiateWriteCommand(i2cHardware);
+	i2c_init_write_command(i2c_dev);
 	
-	i2cGenerateStart(i2cHardware);
+	// The Slave addrress is automatically place on the output buffer (must be done before the start condition)
+	I2C_BASE->CR2 |= (*slaveAddress & 0xff) << 1; // The bit no 0 is not taken in concideration in 7bit mode		
 
 	// This device places the salve address automaticaly in the output buffer before sending the star condition
-	i2cHardware->hardwareState = i2cHwOutputBufferFull;
+	i2c_send_start(i2c_dev);
+	i2c_dev->hardwareState = i2c_hw_out_buff_full;
 	
-	// Wait until the data in the ouput buffer is put to the i2c BUS	
-	while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
-	{
-		i2cIsOutputBufferEmpty(i2cHardware);
-	}		
+	while(i2c_is_output_buffer_full(i2c_dev)); 
+
+	i2c_dev->periferalState = i2c_perif_address_sent;
 	
-	if(i2cCheckNack(i2cHardware))
-	{
-		i2cHardware->hardwareState = i2cHwGotNack;
-		i2cThrowError(i2cHardware->hardwareState);
+	if(i2c_check_nack(i2c_dev)) 
+	{ 
+		i2c_dev->hardwareState = i2c_hw_got_nack;
+		i2c_throw_error(i2c_dev,i2c_dev->hardwareState);
 	}
-	i2cHardware->hardwareState = i2cHwGotAck;
+	i2c_dev->hardwareState = i2c_hw_got_ack;
 }
 
-void i2cSendSlaveAddressRead(i2c_t *i2cHardware, uint16_t *slaveAddress)
+void i2c_send_address_for_read(i2c_t *i2c_dev, uint16_t *slaveAddress)
 {
-	// The Slave addrress is automatically place on the output buffer (must be done before the start condition)
-	I2C_BASE->CR2 |= (*slaveAddress & 0xff) << 1; // The bit no 0 is not taken in concideration in 7bit mode	
+	// Arch nemesis ! We only setn the address
+	// but the counter allso socunt the bits that we have recieved
+	// and we want to read one byte 
+	// every transaction counts
+	i2c_set_tx_counter(i2c_dev,1); 	
 	
 	// On This chip this shoudl be done before the start condition
-	i2cInitiateReadCommand(i2cHardware);
+	i2c_init_read_command(i2c_dev);
 	
-	i2cGenerateStart(i2cHardware);
-
+	// The Slave addrress is automatically place on the output buffer (must be done before the start condition)
+	I2C_BASE->CR2 |= (*slaveAddress & 0xff) << 1; // The bit no 0 is not taken in concideration in 7bit mode		
 	// This device places the salve address automaticaly in the output buffer before sending the star condition
-	i2cHardware->hardwareState = i2cHwOutputBufferFull;
+	i2c_send_start(i2c_dev);
+	i2c_dev->hardwareState = i2c_hw_out_buff_full;
 	
-	while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
-	{
-		i2cIsOutputBufferEmpty(i2cHardware);
-	}		
+	while(i2c_is_output_buffer_full(i2c_dev)); 
+
+	i2c_dev->periferalState = i2c_perif_address_sent;
 	
-	if(i2cCheckNack(i2cHardware))
-	{
-		i2cHardware->hardwareState = i2cHwGotNack;
-		i2cThrowError(i2cHardware->hardwareState);
+	if(i2c_check_nack(i2c_dev)) 
+	{ 
+		i2c_dev->hardwareState = i2c_hw_got_nack;
+		i2c_throw_error(i2c_dev,i2c_dev->hardwareState);
 	}
-	i2cHardware->hardwareState = i2cHwGotAck;
+	i2c_dev->hardwareState = i2c_hw_got_ack;
 }
 
-void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t *registerAddress)
+uint8_t i2c_is_output_buffer_full(i2c_t *i2c_dev)
 {
-	i2cSendData(i2cHardware,registerAddress);
+	/*
+	Bit 0 TXE: Transmit data register empty (transmitters)
+	This bit is set by hardware when the I2C_TXDR register is empty. It is cleared when the next
+	data to be sent is written in the I2C_TXDR register.
+	This bit can be written to ‘1’ by software in order to flush the transmit data register I2C_TXDR.
+	Note: This bit is set by hardware when PE=0. 
+	*/
+	if(I2C_BASE->ISR & I2C_ISR_TXE)
+	{
+		i2c_dev->hardwareState = i2c_hw_out_buff_empty;
+		return 0;
+	}
+	else
+	{
+		i2c_dev->hardwareState = i2c_hw_out_buff_full;
+		return 1;
+	}
 }
 
-void i2cInitiateWriteCommand(i2c_t *i2cHardware)
+void i2c_send_reg_address(i2c_t *i2c_dev, uint8_t *registerAddress)
 {
-	I2C_BASE->CR2 &= ~I2C_CR2_RD_WRN;
+	i2c_send_data(i2c_dev,registerAddress);
 }
 
-void i2cInitiateReadCommand(i2c_t *i2cHardware)
+void i2c_send_data(i2c_t *i2c_dev, uint8_t *data)
 {
-	I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
+	I2C_BASE->TXDR = *data; 
+	i2c_dev->hardwareState = i2c_hw_out_buff_full;
+	while(i2c_is_output_buffer_full(i2c_dev));
 }
 
-void i2cSendData(i2c_t *i2cHardware, uint8_t *registerAddress)
+uint8_t i2c_is_tx_complete(i2c_t *i2c_dev)
 {
-	while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
+	/*
+	TC: Transfer Complete (master mode)
+	This flag is set by hardware when RELOAD=0, AUTOEND=0 and NBYTES data have been
+	transferred. It is cleared by software when START bit or STOP bit is set.
+	Note: This bit is cleared by hardware when PE=0.
+	*/
+
+	if(I2C_BASE->ISR & I2C_ISR_TC)
 	{
-		i2cIsOutputBufferEmpty(i2cHardware);
-	}
-	
-	i2cSetOutputRegister(i2cHardware,registerAddress);
-	
-	while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
-	{
-		i2cIsOutputBufferEmpty(i2cHardware);
+		i2c_dev->periferalState = i2c_perif_tx_done;		
+		return 1;
 	}
-	if(i2cCheckNack(i2cHardware))
+	else
 	{
-		i2cHardware->hardwareState = i2cHwGotNack;
-		i2cThrowError(i2cHardware->hardwareState);
+		i2c_dev->periferalState = i2c_perif_tx_ongoing;		
+		return 0;
 	}
-	i2cHardware->hardwareState = i2cHwGotAck;
 }
 
-void i2cIsOutputBufferEmpty(i2c_t *i2cHardware)
+uint8_t i2c_is_input_buffer_full(i2c_t *i2c_dev)
 {
-	if((i2cHardware->periferalState) == i2cPerifTransmitting)
+	if(I2C_BASE->ISR & I2C_ISR_RXNE)
 	{
-		if((I2C_BASE->ISR & (I2C_ISR_TXIS)) == I2C_ISR_TXIS)
-		{
-			i2cHardware->hardwareState = i2cHwOutputBufferEmpty;		
-		}
-		else
-		{
-			i2cHardware->hardwareState = i2cHwOutputBufferFull;		
-		}
+		i2c_dev->hardwareState = i2c_hw_in_buff_full;		
+		return 1;
 	}
-	else if((i2cHardware->periferalState) == i2cPerifRecieving)
+	else
 	{
-		if((I2C_BASE->ISR & (I2C_ISR_TXE)) == I2C_ISR_TXE)
-		{
-			i2cHardware->hardwareState = i2cHwOutputBufferEmpty;		
-		}
-		else
-		{
-			i2cHardware->hardwareState = i2cHwOutputBufferFull;		
-		}
+		i2c_dev->hardwareState = i2c_hw_in_buff_empty;
+		return 0;
 	}
 }
 
-void i2cIsInputBufferEmpty(i2c_t *i2cHardware)
+void i2c_get_input_register(i2c_t *i2c_dev, uint8_t *data)
+{
+	*data = I2C_BASE->RXDR;	
+}
+
+void i2c_send_nack(i2c_t *i2c_dev)
 {
-	if((I2C_BASE->ISR & (I2C_ISR_RXNE)) == I2C_ISR_RXNE)
+	if(i2c_dev->mode == i2c_mode_master)
 	{
-		i2cHardware->hardwareState = i2cHwInputBufferFull;		
+		//IN master mode this ic geretes NACK's otomatically
+		i2c_dev->hardwareState = i2c_hw_sent_nack;		
 	}
-	else
+	else if(i2c_dev->mode == i2c_mode_slave)
 	{
-		i2cHardware->hardwareState = i2cHwInputBufferEmpty;		
+		// to be written. 
 	}
 }
 
-
-void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data)
+/*
+void i2cSendSlaveAddressRead(i2c_t *i2c_dev, uint16_t *slaveAddress)
 {
-	*data = I2C_BASE->RXDR;	
+	I2C_BASE->CR2 &= ~I2C_CR2_AUTOEND; 
+	// The Slave addrress is automatically place on the output buffer (must be done before the start condition)
+	I2C_BASE->CR2 |= (*slaveAddress & 0xff) << 1; // The bit no 0 is not taken in concideration in 7bit mode	
+	
+	// On This chip this shoudl be done before the start condition
+	i2cInitiateReadCommand(i2c_dev);
+	
+	i2cGenerateStart(i2c_dev);
+
+	// This device places the salve address automaticaly in the output buffer before sending the star condition
+	i2c_dev->hardwareState = i2cHwOutputBufferFull;
+	
+	while((i2c_dev->hardwareState =! i2cHwOutputBufferEmpty))
+	{
+		i2cIsOutputBufferEmpty(i2c_dev);
+	}			
 }
 
-void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data)
+
+
+
+
+
+
+
+void i2cSetOutputRegister(i2c_t *i2c_dev, uint8_t *data)
 {
-	I2C_BASE->TXDR = *data; 
-	i2cHardware->hardwareState = i2cHwOutputBufferFull;		
+	i2c_dev->hardwareState = i2cHwOutputBufferFull;		
 }
 
-void i2cIsTransferComplete(i2c_t *i2cHardware)
+void i2cIsTransferComplete(i2c_t *i2c_dev)
 {
 	if((I2C_BASE->ISR & (I2C_ISR_TC)) == I2C_ISR_TC)
 	{
-		i2cHardware->periferalState = i2cPerifTransferComplete;		
+		i2c_dev->periferalState = i2cPerifTransferComplete;		
 	}
 	else
 	{
-		i2cHardware->periferalState = i2cPerifTransferOngoign; 
+		i2c_dev->periferalState = i2cPerifTransferOngoign; 
 	}
 }
 
-void i2cGenerateNack(i2c_t *i2cHardware)
-{
-	if(i2cHardware->mode == i2cModeMaster)
-	{
-		//IN master mode this ic geretes NACK's otomatically
-		i2cHardware->hardwareState = i2cHwSentNack;		
-	}
-	else if(i2cHardware->mode == i2cModeSlave)
-	{
-		// to be written. 
-	}
 }
+*/
 
-uint8_t i2cCheckNack(i2c_t *i2cHardware)
+uint8_t i2c_check_nack(i2c_t *i2c_dev)
 {
 	if((I2C_BASE->ISR & (I2C_ISR_NACKF)))
 	{
@@ -332,3 +384,7 @@ uint8_t i2cCheckNack(i2c_t *i2cHardware)
 	}
 	return 0;	
 }
+
+void i2c_set_address(i2c_t *i2c_dev, uint16_t address){}
+void i2c_set_address_second(i2c_t *i2c_dev, uint16_t address){}
+
diff --git a/peripherals/i2c.c b/peripherals/i2c.c
index 9bb46bb..5a6cb93 100644
--- a/peripherals/i2c.c
+++ b/peripherals/i2c.c
@@ -1,61 +1,63 @@
 #include "i2c.h"
 #include "usart.h"
 
-//uint32_t i2cCR1;
-//uint32_t i2cCR2;
-//uint32_t i2cISR;
 
-void i2cInit(	i2c_t *i2cHardware,					
-				i2cCh_t channelNo,						
-				i2cMode_t mode,						
-				uint16_t mainAddress,				 
-				uint16_t secondAddress,				
-				i2cAddressCount_t addressCount,		 
-				i2cAddressSize_t addressSize,		
-				i2cSpeed_t speed,					  
-				i2cOpperationMode_t opperationMode,	
-				i2cClockStretching_t stretching,	
-				i2cWakeUpTypes_t wakeOn)			
+void i2c_init(	i2c_t *i2c_dev,						/*!< Pointer to I2C hardware Object						*/
+				i2cCh_t channelNo,					/*!< The harware channel to be used						*/	
+				i2c_mode_t mode,					/*!< Master, Slave or Multymaster Modes					*/
+				uint16_t mainAddress,				/*!< First and Main address of the device				*/ 
+				uint16_t secondAddress,				/*!< Second address if dual addresse mode is configured	*/
+				i2c_address_count_t addressCount,	/*!< Single or multiple									*/ 
+				i2c_address_size_t addressSize,		/*!< 10 or 7 bit address size							*/
+				i2c_clk_speed_t speed,				/*!< Bus Speed											*/  
+				i2c_clk_stretching_t stretching,	/*!< Clock Stretching enable onyl in slave mode			*/
+				i2c_wake_types_t wakeOn				/*!< Wake up condition									*/
+		)
 {
-	i2cHardware->channelNo = channelNo;
-	i2cHardware->mode = mode;
-	i2cHardware->mainAddress = mainAddress;				 
-	i2cHardware->secondAddress = secondAddress;
-	i2cHardware->addressCount = addressCount; 
-	i2cHardware->addressSize = addressSize;
-	i2cHardware->speed = speed; 														
-	i2cHardware->opperationMode = opperationMode; 
-	i2cHardware->stretching = stretching;
-	i2cHardware->wakeOn = wakeOn;
-	i2cHardware->hardwareState = i2cHwIdle;
-	i2cHardware->periferalState = i2cPerifNotInitialized;
-
-	i2cEnableHardware(i2cHardware);	
-	i2cDisablePeriferal(i2cHardware);	
-	i2cConfigureFilters(i2cHardware);
-	i2cSetClockStretch(i2cHardware, stretching);
-	i2cSetSpeed(i2cHardware, speed);
-	i2cSetMode(i2cHardware, opperationMode);
-	i2cSetAddressLenght(i2cHardware, addressSize);
-	i2cSetAddress(i2cHardware, mainAddress, secondAddress);
-	i2cEnablePeriferal(i2cHardware);	
+	i2c_dev->channelNo = channelNo;
+	i2c_dev->mode = mode;
+	i2c_dev->mainAddress = mainAddress;				 
+	i2c_dev->secondAddress = secondAddress;
+	i2c_dev->addressCount = addressCount; 
+	i2c_dev->addressSize = addressSize;
+	i2c_dev->speed = speed; 														
+	i2c_dev->stretching = stretching;
+	i2c_dev->wakeOn = wakeOn;
 	
-	while(i2cHardware->periferalState != i2cPerifReady)
-	{
-		i2cIsPeriferalReady(i2cHardware);
-	}
-
-	i2cHardware->periferalState = i2cPerifInitialized;
+	//Initial state States
+	i2c_dev->hardwareState = i2c_hw_disabled;
+	i2c_dev->periferalState = i2c_perif_disabled;
+	
+	i2c_hardware_enable(i2c_dev);	
+	i2c_periferal_disable(i2c_dev); // Just to be sure as periferal configuration can not be dont when active. 
+	i2c_set_filter(i2c_dev,1);
+	i2c_set_clk_stretch(i2c_dev, stretching);
+	i2c_set_clk_speed(i2c_dev, speed);
+	i2c_set_mode(i2c_dev, mode);
+	i2c_set_address_lenght(i2c_dev, addressSize);
+	i2c_set_address(i2c_dev, mainAddress);
+	i2c_set_address_second(i2c_dev, mainAddress);
+	i2c_periferal_enable(i2c_dev);			
+	print_Usart(usart2, "I2C -> periferal enabled\n\r"); 
 }
 
-
-void i2cDeInit(i2c_t *i2cHardware)
+void i2c_read(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
 {
+	i2c_send_address_for_write(i2c_dev, slaveAddress);	
+	i2c_send_reg_address(i2c_dev, registerAddress);
+	while(!i2c_is_tx_complete(i2c_dev));
+	i2c_send_address_for_read(i2c_dev, slaveAddress);	
+	while(!i2c_is_input_buffer_full(i2c_dev));
+	i2c_get_input_register(i2c_dev, data);	
+	while(!i2c_is_tx_complete(i2c_dev));
+	i2c_send_nack(i2c_dev);
+	i2c_send_stop(i2c_dev);
+	print_Usart(usart2, "I2C -> Read Done\n\r"); 
+}
+void i2c_write(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght){}
 
-}	
-
-
-void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
+/*
+void i2cRead(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
 {	
 
 //
@@ -63,54 +65,67 @@ void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddres
 // Send Address
 // Wait For ACK
 //
-	i2cSetTransferCounter(i2cHardware,1); 
-	i2cSendSlaveAddressWrite(i2cHardware, slaveAddress);	
-	i2cHardware->periferalState = i2cPerifTransmitting;
-	
-	i2cSendRegisterAddress(i2cHardware,registerAddress);
+	uint8_t nbytes = 0; 
 
-	while(i2cHardware->periferalState != i2cPerifTransferComplete)
+	i2c_dev->periferalState = i2cPerifTransmitting;
+	
+	i2cSetTransferCounter(i2c_dev,1); 
+	i2cSendSlaveAddressWrite(i2c_dev, slaveAddress);	
+	i2cSendRegisterAddress(i2c_dev,registerAddress);
+	
+	while(i2c_dev->periferalState != i2cPerifTransferComplete)
 	{
-		i2cIsTransferComplete(i2cHardware);
+		i2cIsTransferComplete(i2c_dev);
 	}
 	
-	i2cSendSlaveAddressRead(i2cHardware, slaveAddress);
-	i2cHardware->periferalState = i2cPerifRecieving;
+	i2c_dev->periferalState = i2cPerifRecieving;
+	i2cSendSlaveAddressRead(i2c_dev, slaveAddress);
 	
-	while(i2cHardware->periferalState != i2cPerifTransferComplete)
+	
+	while(i2c_dev->periferalState != i2cPerifTransferComplete)
 	{
-		i2cIsTransferComplete(i2cHardware);
+		i2cIsTransferComplete(i2c_dev);
 	}
 
-	i2cGenerateNack(i2cHardware);
-	i2cGenerateStop(i2cHardware);
+	i2cGenerateNack(i2c_dev);
+	i2cGenerateStop(i2c_dev);
+	
+	i2cReadInputRegister(i2c_dev, data);
 	
-	i2cReadInputRegister(i2cHardware, data);
+	print_Usart(usart2, "\n\rI2C Read completed\n\r"); 
 
-	while(i2cHardware->periferalState != i2cPerifReady)
+	while(i2c_dev->periferalState != i2cPerifReady)
 	{
-		i2cIsPeriferalReady(i2cHardware);
+		i2cIsPeriferalReady(i2c_dev);
 	}
-	i2cHardware->periferalState = i2cPerifReady;
-	i2cHardware->hardwareState = i2cHwIdle;
+	i2c_dev->periferalState = i2cPerifReady;
+	i2c_dev->hardwareState = i2cHwIdle;
 }
 
-void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
+void i2cWrite(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
 {
-	i2cSetTransferCounter(i2cHardware,0); 
-	i2cSendSlaveAddressWrite(i2cHardware, slaveAddress);	
-	i2cHardware->periferalState = i2cPerifTransmitting;
-	i2cSendRegisterAddress(i2cHardware,registerAddress);
-	i2cHardware->periferalState = i2cPerifTransmitting;
-	i2cSendData(i2cHardware,data);
-	while(i2cHardware->periferalState != i2cPerifTransferComplete)
+	i2cSetTransferCounter(i2c_dev,2); 
+	i2cSendSlaveAddressWrite(i2c_dev, slaveAddress);	
+	i2cSendRegisterAddress(i2c_dev,registerAddress);
+	while((i2c_dev->hardwareState =! i2cHwOutputBufferEmpty))
 	{
-		i2cIsTransferComplete(i2cHardware);
+		i2cIsOutputBufferEmpty(i2c_dev);
 	}
+	i2cSendData(i2c_dev,data);
+	
+	i2cGenerateStop(i2c_dev);
+	print_Usart(usart2, "\n\rI2C Transfer completed\n\r"); 
 }
 
-void i2cThrowError(int16_t error)
+*/
+void i2c_throw_error(i2c_t *i2c_dev, int16_t error)
 {
-	print_Usart(usart2, "I2C Error Detected : "); 
+	print_Usart(usart2, "\n\r"); 
+	print_Usart(usart2, "\n\r"); 
+	print_Usart(usart2, "I2C Error Detected : "); 	
+	print_Usart(usart2, "\n\r"); 
+	print_Usart(usart2, "I2C Error No: "); 
 	usartSendChar(usart2, error + 0x30); 
+	print_Usart(usart2, "\n\r"); 
+	print_Usart(usart2, "\n\r"); 
 }
diff --git a/peripherals/i2c.h b/peripherals/i2c.h
old mode 100755
new mode 100644
index 2f38353..d666764
--- a/peripherals/i2c.h
+++ b/peripherals/i2c.h
@@ -1,566 +1,522 @@
-/**
-  **************************************************************************************************
-  * @file		i2c.h
-  * @author		Kerem Yollu & Edwin Koch
-  * @date		18.07.2022
-  * @version	1.01
-  ************************************************************************************************** 
-  * @brief		I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips : 
-  *				following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA		
-  *				This will also not have a I3C support for the forseable futrue. 
-  *				
-  * **Detailed Description :**
-  * 
-  *	I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips : 
-  *	following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA		
-  *	This will also not have a I3C support for the forseable futrue. 
-  *
-  * @todo 
-  * - 26.07.2021 : Implement the DMA  
-  * - 26.07.2021 : Implement the Interrupt  
-  * - 26.07.2021 : Implement the Sleep/WakeUp  
-  * - 26.07.2021 : Implement the Slave opperation  
-  **************************************************************************************************
-*/
-
-#ifndef _I2C_H_
-#define _I2C_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "hardwareDescription.h"
-#include "pin.h"
-
-
-
-/*! Enum of possible I2C opperation modes */
-typedef enum{
-	i2cModeMaster,			/*!< Master mode : In Master mode, the I2C interface initiates 
-							  a data transfer and generates the clock signal. **DEFAULT**			*/ 
-	i2cModeMultyMaster,		/*!< Multimaster Mode : In case if more than one master are present 
-							  in one I2C bus. In such case each device needs to be able to 
-							  cooperate knowing that another device could talking 
-							  therefore the bus is busy (Arbirtation). 
-							  For More information : https://www.i2c-bus.org/multimaster/		*/
-	i2cModeSlave			/*!< Slave mode : A slave device has to always be ready to detect and 
-							  process a start condition and to recognize its address			*/
-}i2cMode_t; 
-	
-/*! Enum of possible I2C speeds */
-typedef enum{
-	i2cSpeedStandart,	/*!< SM 100 kbits/s Standart i2c Speed **DEFAULT**	*/ 
-	i2cSpeedFast,		/*!< FM 400 kbits/s									*/
-	i2cSpeedFastPlus,	/*!< FM+ 1 Mbits/s									*/
-	i2cSpeedHightSpeed, /*!< HS 3.4 Mbits/s									*/
-	i2cSpeedUltraFast	/*!< UFM 5 Mbits/s									*/
-}i2cSpeed_t;
-
-/*! Enum of possible I2C Adress sizes */
-typedef enum{
-	i2cAddressSizeSevenBits,	/*!< 7 Bits address size **DEFAULT**	*/ 
-	i2cAddressSizeTenBits		/*!< 10 Bits address size				*/
-}i2cAddressSize_t;
-
-/*! Enum of possible I2C Address count */
-typedef enum{
-	i2cAddressCountSingle,	/*!< Only one address for communication **DEFAULT**					*/ 
-	i2cAddressCountDual		/*!< Dual addresses for one device respondng to two addresses			*/
-}i2cAddressCount_t;
-
-/*! Enum for clock strechning activation. Can only be implmented as Slave 
- * for more information : https://www.i2c-bus.org/clock-stretching/								*/
-typedef enum{
-	i2cClockStretchingDisable,	/*!< We assume that the master and slave have compatible 
-								  Clock frequencies	**DEFAULT**									*/
-	i2cClockStretchingEnable	/*!< In situations where an I2C slave is not able to co-operate 
-								  with the clock speed given by the master and needs to slow down. 
-								  This is done by a mechanism referred to as clock stretching.	*/ 
-}i2cClockStretching_t;
-
-/*! Enum for diffenrent wake up methodes wehnin sleep mode */
-typedef enum{
-	i2cWakeUpDisabled,		/*!< No wake up is possible this is the default mode also means that 
-							  the sleep function is not implmentes **DEFAULT**					*/
-	i2cWakeUpOnAddressMatch	/*!< Wakes up on address match, this can be harware dependent		*/
-}i2cWakeUpTypes_t;
-
-/*! Enum operation mode of the i2c channel */
-typedef enum{
-	i2cOpperationPolling,	/*!< Polling mode Blocking, i2c communication states are constantly 
-							  checked on polling mode so it can be stoped 
-							  when interrupts occures **DEFAULT**								*/
-	i2cOpperationInt,		/*!< Interrut Mode Non-blocking, i2c communications state changes 	
-							  generates an interrupt and can be handeled this way				*/
-	i2cOpperationDma		/*!< DMA Mode Non-blocking, I2C communication satets are managed 
-							  via Inteerupts and with Direct Memory Access						*/
-}i2cOpperationMode_t;
-
-/*! typedef for the i2c states*/
-typedef enum
-{
-	i2cHwIdle,					/*!< Hardware is in Idle Mode  **DEFAULT**				*/
-	i2cHwStartGenerated,		/*!< Generated the star condition						*/
-	i2cHwOutputBufferFull,		/*!< The output buffer of the I2C Periferal is Full		*/
-	i2cHwOutputBufferEmpty,		/*!< The output buffer of the I2C Periferal is Empty	*/
-	i2cHwInputBufferFull,		/*!< The input buffer of the I2C Periferal Is Full		*/
-	i2cHwInputBufferEmpty,		/*!< The input buffer of the I2C Periferal Is Empty		*/
-	i2cHwSentRead,				/*!< Sent read request									*/
-	i2cHwSentWrite,				/*!< Sent write request									*/
-	i2cHwGotAck,				/*!< Recieved ACK										*/
-	i2cHwGotNack,				/*!< Recieved NACK										*/
-	i2cHwSentAck,				/*!< Sent ACK											*/
-	i2cHwSentNack,				/*!< Sent NACK											*/
-	i2cHwStopGenerated,			/*!< Generated the star condition						*/
-	i2cHwError					/*!< Error												*/
-} i2cHardwareState_t;
-
-typedef enum
-{
-	i2cPerifNotInitialized,				/*!< Default Peripheral is not yet Initialized **DEFAULT**		*/
-	i2cPerifInitialized,				/*!< I2C CHannle is initilized but not neceserly ready			*/
-	i2cPerifSlaveAddressSent,			/*!< The Salve Address Was Sent to the bus						*/
-	i2cPerifTransferComplete,			/*!< A full communication process is complete (wire or Read)	*/
-	i2cPerifTransferOngoign,			/*!< A full communication process is in progress (wire or Read)	*/
-	i2cPerifReady,						/*!< Peripheral Initialized and ready for use					*/
-	i2cPerifSlaveNotFound,				/*!< Desired Slave was not able to be found 					*/
-	i2cPerifTransmitting,				/*!< Data Transmission process is ongoing						*/
-	i2cPerifRecieving,					/*!< Data Reception process is ongoing							*/
-	i2cPerifListening,					/*!< Address Listen Mode is ongoing								*/
-	i2cPerifListeningAndTransmitting,	/*!< Address Listen Mode and ongoing Data Transmission			*/
-	i2cPerifListeningAndRecieveing,		/*!< Address Listen Mode and ongoing Data Reception				*/
-	i2cPerifAbort,						/*!< Abort user request ongoing									*/
-	i2cPerifTimeout,					/*!< Timeout state												*/
-	i2cPerifError						/*!< Error														*/
-} i2cPeriferalState_t;
-/*! Struture a an i2c channel with all the required propereties*/
-typedef struct i2c_t
-{
-	i2cCh_t channelNo;					/*!< The harware channel to be used						*/	
-	i2cMode_t mode;						/*!< Master, Slave or Multymaster Modes					*/
-	uint16_t mainAddress;				/*!< First and Main address of the device				*/ 
-	uint16_t secondAddress;				/*!< Second address if dual addresse mode is configured	*/
-	i2cAddressCount_t addressCount;		/*!< Single or multiple									*/ 
-	i2cAddressSize_t addressSize;		/*!< 10 or 7 bit address size							*/
-	i2cSpeed_t speed;					/*!< Bus Speed											*/  
-	i2cOpperationMode_t opperationMode;	/*!< Blocking or non blocking polling, Int or DMA		*/
-	i2cClockStretching_t stretching;	/*!< Clock Stretching enable onyl in slave mode			*/
-	i2cWakeUpTypes_t wakeOn;			/*!< Define on which type of action the i2c channel should 
-										  wake up. Only if de prefiral goes to sleep			*/
-	i2cHardwareState_t hardwareState;	/*!< The current sitate of the I2C Bus					*/
-	i2cPeriferalState_t periferalState;	/*!< The current sitate of the I2C Bus					*/
-}i2c_t;
-
-/***************************************************************************************************
-	I2C Configuration functions											
-***************************************************************************************************/
-
-/**
- * @brief Initilize the I2C Hardware
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cInit(	i2c_t *i2cHardware,					/*!< Pointer to I2C hardware Object						*/
-				i2cCh_t channelNo,					/*!< The harware channel to be used						*/	
-				i2cMode_t mode,						/*!< Master, Slave or Multymaster Modes					*/
-				uint16_t mainAddress,				/*!< First and Main address of the device				*/ 
-				uint16_t secondAddress,				/*!< Second address if dual addresse mode is configured	*/
-				i2cAddressCount_t addressCount,		/*!< Single or multiple									*/ 
-				i2cAddressSize_t addressSize,		/*!< 10 or 7 bit address size							*/
-				i2cSpeed_t speed,					/*!< Bus Speed											*/  
-				i2cOpperationMode_t opperationMode,	/*!< Blocking or non blocking polling, Int or DMA		*/
-				i2cClockStretching_t stretching,	/*!< Clock Stretching enable onyl in slave mode			*/
-				i2cWakeUpTypes_t wakeOn				/*!< Wake up condition									*/
-		);
-
-/**
- * @brief De-Initilize the I2C Hardware
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cDeInit(i2c_t *i2cHardware); 
-
-/**
- * @brief Set the i2c channle to the gievn mode
- * @param Channel is the i2c hardware channel
- * @param mode The mode for i2c : Master Slave or Multymaster 
- */
-void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode);
-
-/**
- * @brief Set the i2c channles mode as Master Slave or Multymaster
- * @param i2cHardware is the i2c hardware channel
- * @param addressOne The forst address for the device
- * @param addressTwo The second address for the device only if dual address mode is not defined
- */
-void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress);
-
-/**
- * @brief Set the i2c Address Lenght, 7 bit or 8 bit, Master or slave doesn't make any difference
- * @param i2cHardware is the i2c hardware channel
- * @param size Is the Adress isze to be used 7 Bit or 10 Bit 
- */
-void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size);
-
-/**
- * @brief Stets the Communication speed 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param speed the different awailable speeds
- */
-void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed); 
-
-/**
- * @brief Initiates the opperation mode for the selected i2c Channel 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param opperation define if the i2c channel will opperate on pollin, Interrupt, or DMA modes 
- */
-void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation);
-
-
-/**
- * @brief Ebales or disables clock stretching functionalities 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param The value to be written in the register. This will heavily depend on the hardware
- */
-void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching);
-
-/**
- * @brief Set the wakeup mode  
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param wake the desider wakeup mode for now i have found only one mode. 
- */
-void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake); 
-
-/**
- * @brief Configures Hardware implmente filters if there are any.  
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cConfigureFilters(i2c_t *i2cHardware);	
-
-/**
- * @brief Set the timeout to close the i2c wait time if a communication fails. 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param timeout the desider timeout duration in ticks. 
- */
-void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout);
-
-/**
- * @brief Resets the i2c Periferal to it's inital state.  
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cPeriferalReset(i2c_t *i2cHardware);		
-
-/**
- * @brief Resets the i2c Harware and register to it's factory deflauts.  
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cHardwareReset(i2c_t *i2cHardware);		
-
-/**
- * @brief Enables I2C Hardware BUS & Clock & Pins  
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cEnableHardware(i2c_t *i2cHardware);	
-
-/**
- * @brief Enables I2C Periferal core.  
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cEnablePeriferal(i2c_t *i2cHardware);	
-
-/**
- * @brief Disables I2C Periferal core.  
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cDisablePeriferal(i2c_t *i2cHardware);	
-
-/**************************************************************************************************
-	I2C Communication functions independen of opperating mode
-***************************************************************************************************/
-
-/**
- * @brief	Writes the given amount of data to the selected device. This function will 
- *			automaticaly choose between i2cMasterSend(); or i2cSlaveSend(); 
- *			Depending if the I2C channel was initiated as slave or master. 
- *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- * @param registerAddress is the regiter to be red from the device
- * @param data is the data to be written
- * @param dataLenght is the total quantity of 8 bit data to be written.
- */
-void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
-
-/**
- * @brief Reads the given amount of data to the selected device. This function will 
- *			automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve(); 
- *			Depending if the I2C channel was initiated as slave or master. 
- *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- * @param registerAddress is the regiter to be red from the device
- * @param data is the data which has been red
- * @paran dataLenght is the total quantity of 8 bit data to be red
- */
-void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
-
-/**
- * @brief	Recieve a Single Byte as master from from the given devices register.
- *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- * @param registerAddress is the regiter to be red from the device
- * @param data is the data whic has been red
- */
-void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
-/**
- * @brief	Sends a Single Byte as master to the given devices register. 
- *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the send command will be sent
- * @param registerAddress is the regiter to be written to the device
- * @param data is the data to be sent
- */
-void i2cMasterSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
-
-/**
- * @brief	Recieve a Single Byte as slave from given devices register.
- *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- * @param registerAddress is the regiter to be red from the device
- * @param data is the data whic has been red
- */
-void i2cSlaveRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
-
-/**
- * @brief	Recieve a Single Byte as slave from the given devices register.
- *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- * @param registerAddress is the regiter to be red from the device
- * @param data is the data whic has been red
- */
-void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
-
-/**************************************************************************************************
-	I2C Hardware functions
-***************************************************************************************************/
-/**
- * @brief Checks if the device is ready for any type of communication	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cIsPeriferalReady(i2c_t *i2cHardware);
-
-/**
- * @brief Generates a Start condition.	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cGenerateStart(i2c_t *i2cHardware);
-
-/**
- * @brief Generates a Start condition.	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cGenerateStop(i2c_t *i2cHardware);
-
-/**
- * @brief Generates a NACK condition.	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cGenerateNack(i2c_t *i2cHardware);
-
-/**
- * @brief Checks If a NACK is recieved.	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-uint8_t i2cCheckNack(i2c_t *i2cHardware);
-
-/**
- * @brief Generates a ACK condition.	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cGenerateAck(i2c_t *i2cHardware);
-
-/**
- * @brief Initiates the communication  by sending the slave address on the bus followed by a WRITE 
- * and waits for an ACK (aknowledge)
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress The address of the slave to be communicated
- */
-void i2cSendSlaveAddressWrite(i2c_t *i2cHardware, uint16_t *slaveAddress);
-
-/**
- * @brief Initiates the communication by sending the slave address on the bus followed by a READ 
- * and waits for an ACK (aknowledge)
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress The address of the slave to be communicated
- */
-void i2cSendSlaveAddressRead(i2c_t *i2cHardware, uint16_t *slaveAddress);
-
-/**
- * @brief Sende the register adrres with which we want to communicate.
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param registerAddress The register address of the slave device that we are communication with
- */
-void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t *registerAddress);
-
-/**
- * @brief Send the register that we want to read or write.	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param registerAddress the register that need to be accessed
- */
-void i2cSendData(i2c_t *i2cHardware, uint8_t *registerAddress);
-
-/**
- * @brief Initiates a Write command with the previously set slave address. 	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cInitiateWriteCommand(i2c_t *i2cHardware);
-
-/**
- * @brief Initiates a read command with the previously set slave address. 	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cInitiateReadCommand(i2c_t *i2cHardware);
-
-/**
- * @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
- * is sent to the i2c BUS. 	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cIsOutputBufferEmpty(i2c_t *i2cHardware);
-
-/**
- * @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
- * is sent to the i2c BUS. 	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cIsInputBufferEmpty(i2c_t *i2cHardware);
-
-/**
- * @brief reads the I2C input buffer
- * is sent to the i2c BUS. 	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param data pointer to the data that need to be read and returned
- */
-void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data);
-
-/**
- * @brief writes to the I2C output buffer
- * is sent to the i2c BUS. 	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param data pointer to the data that need to be read and returned
- */
-void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data);
-
-/**
- * @brief Checks is transfer is complete
- * is sent to the i2c BUS. 	
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param data pointer to the data that need to be read and returned
- */
-void i2cIsTransferComplete(i2c_t *i2cHardware);
-
-/**
- * @brief Defines the amount of transfers to be made. Address exchange and start conditon does not count
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param count amount o data to be transfered. 
- */
-void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count);
-/**************************************************************************************************
-	I2C Communication functions Polling / Blocking Mode
-***************************************************************************************************/
-
-/**
- * @brief	Recieve a Single Byte in polling mode as master from from the given devices register.
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- * @param registerAddress is the regiter to be red from the device
- * @param data is the data whic has been red
- */
-void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
-/**
- * @brief	Sends a Single Byte in polling mode as master to the given devices register. 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the send command will be sent
- * @param registerAddress is the regiter to be written to the device
- * @param data is the data to be sent
- */
-void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
-
-/**
- * @brief	Recieve a Single Byte in polling mide as slave from the given devices register.
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- * @param registerAddress is the regiter to be red from the device
- * @param data is the data whic has been red
- */
-void i2cSlaveRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
-
-/**
- * @brief	Recieve a Single Byte in polling mode as slave from the given devices register.
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- * @param registerAddress is the regiter to be red from the device
- * @param data is the data whic has been red
- */
-void i2cSlaveSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
-
-/**************************************************************************************************
-	I2C Arbitration Functions for Multymaster mode and slaves clock stretching 
-***************************************************************************************************/
-void i2cClockSynchronise();	// I2C Standart : Clock Syncronization
-void i2cAbortTransmit();	// I2c Standart : Stop Communication for multimaster mode 
-void i2cArbitration();		// I2C Standart : Arbitration for multimaster mode to define the right master. 
-void i2cSoftReset();		// I2C Standart : Software reset not supported by all hardware.
-void i2cBusClear();			// I2C Standart : in case if SCL is stuck 
-
-
-/**************************************************************************************************
-	I2C Extra functions that are not esential for the main functionality
-***************************************************************************************************/
-
-/**
- * @brief	This function will scan every for possible addresses to discover devices on the bus.
- *			And write them to the Devices list given to him. This function will not discover more 
- *			devices than what he is told. 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param devices list where the discevered devices will be written
- * @param deviceCount Max number of devices to be discovered.
- */
-void i2cDiscoverDevices(i2c_t *i2cHardware, uint16_t *devices, uint8_t deviceCount);	   
-
-/**
- * @brief	This function will try to communicate with a device with every speed 
- *			allowed by his hardware to find out the maximum communication sppeed possible.
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to which the read command will be sent
- */
-i2cSpeed_t i2cTestDeviceSpeed(i2c_t *i2cHardware, uint16_t *slaveAddress);	
-
-/**
- * @brief	This function will read the device info register (if awailable) as follows : 
- *			I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev. 
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- * @param slaveAddress is the address of the device to be red
- */
-uint32_t i2cReadDeviceInfo(i2c_t *i2cHardware, uint16_t *slaveAddress);	
-
-/**
- * @brief The selected i2c channel is put on sleep.
- * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
- */
-void i2cSleep(i2c_t *i2cHardware); 
-
-/**
- * @brief Error handling.
- * @param error The error no generated. 
- */
-void i2cThrowError(int16_t error);	// Defined by me : Private error function for error handling
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _I2C_H_
+/**
+  **************************************************************************************************
+  * @file		i2c.h
+  * @author		Kerem Yollu & Edwin Koch
+  * @date		16.02.2023
+  * @version	1.2
+  ************************************************************************************************** 
+  * @brief		I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips : 
+  *				following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA		
+  *				This will also not have a I3C support for the forseable futrue. 
+  *				
+  * **Detailed Description :**
+  * 
+  *	I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips : 
+  *	following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA		
+  *	This will also not have a I3C support for the forseable futrue. 
+  *
+  * @todo 
+  * - 26.07.2021 : Implement DMA  
+  * - 26.07.2021 : Implement Interrupt  
+  * - 26.07.2021 : Implement Sleep/WakeUp  
+  * - 26.07.2021 : Implement Slave opperation  
+  **************************************************************************************************
+*/
+
+#ifndef _I2C_H_
+#define _I2C_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hardwareDescription.h"
+#include "pin.h"
+
+
+
+/*! Enum of possible I2C opperation modes */
+typedef enum{
+	i2c_mode_master,		/*!< Master mode : In Master mode, the I2C interface initiates 
+							  a data transfer and generates the clock signal. **DEFAULT**			*/ 
+	i2c_mode_multyMaster,	/*!< Multimaster Mode : In case if more than one master are present 
+							  in one I2C bus. In such case each device needs to be able to 
+							  cooperate knowing that another device could talking 
+							  therefore the bus is busy (Arbirtation). 
+							  For More information : https://www.i2c-bus.org/multimaster/		*/
+	i2c_mode_slave			/*!< Slave mode : A slave device has to always be ready to detect and 
+							  process a start condition and to recognize its address			*/
+}i2c_mode_t; 
+	
+/*! Enum of possible I2C speeds */
+typedef enum{
+	i2c_clk_speed_standart,		/*!< SM 100 kbits/s Standart i2c Speed **DEFAULT**	*/ 
+	i2c_clk_speed_fast,			/*!< FM 400 kbits/s									*/
+	i2c_clk_speed_fastPlus,		/*!< FM+ 1 Mbits/s									*/
+	i2c_clk_speed_hightSpeed,	/*!< HS 3.4 Mbits/s									*/
+	i2c_clk_speed_ultraFast		/*!< UFM 5 Mbits/s									*/
+}i2c_clk_speed_t;
+
+/*! Enum of possible I2C Adress sizes */
+typedef enum{
+	i2c_address_size_7b,	/*!< 7 Bits address size **DEFAULT** */ 
+	i2c_address_size_10b	/*!< 10 Bits address size */
+}i2c_address_size_t;
+
+/*! Enum of possible I2C Address count */
+typedef enum{
+	i2c_address_count_single,	/*!< Only one address for communication **DEFAULT** */ 
+	i2c_address_count_dual		/*!< Dual addresses for one device respondng to two addresses */
+}i2c_address_count_t;
+
+/*! Enum for clock strechning activation. Can only be implmented as Slave 
+ * for more information : https://www.i2c-bus.org/clock-stretching/ */
+typedef enum{
+	i2c_clk_stretching_disable,	/*!< We assume that the master and slave have compatible 
+								  Clock frequencies	**DEFAULT** */
+	i2c_clk_stretching_enable	/*!< In situations where an I2C slave is not able to co-operate 
+								  with the clock speed given by the master and needs to slow down. 
+								  This is done by a mechanism referred to as clock stretching. */ 
+}i2c_clk_stretching_t;
+
+/*! Enum for diffenrent wake up methodes wehnin sleep mode */
+typedef enum{
+	i2c_wake_disabled,			/*!< No wake up is possible this is the default mode also means that 
+									the sleep function is not implmentes **DEFAULT** */
+	i2c_wakeUp_address_match	/*!< Wakes up on address match, this can be harware dependent */
+}i2c_wake_types_t;
+
+/*! typedef for the i2c states*/
+typedef enum
+{
+	i2c_hw_disabled,		/*!< Hardware Is Disabled */
+	i2c_hw_reset,			/*!< Hardware Is Reseted and in reset mode and need to be initialised */
+	i2c_hw_enabled,			/*!< I2C Hardware is initilized but not neceserly ready */
+	i2c_hw_ready,			/*!< Hardware Initialized and ready for use */
+	i2c_hw_sent_start,		/*!< Generated the star condition */
+	i2c_hw_out_buff_full,	/*!< The output buffer of the I2C Periferal is Full */
+	i2c_hw_out_buff_empty,	/*!< The output buffer of the I2C Periferal is Empty */
+	i2c_hw_in_buff_full,	/*!< The input buffer of the I2C Periferal Is Full	*/
+	i2c_hw_in_buff_empty,	/*!< The input buffer of the I2C Periferal Is Empty	*/
+	i2c_hw_send_read,		/*!< Sent read request */
+	i2c_hw_send_write,		/*!< Sent write request	*/
+	i2c_hw_got_ack,			/*!< Recieved ACK */
+	i2c_hw_got_nack,		/*!< Recieved NACK */
+	i2c_hw_sent_ack,		/*!< Sent ACK */
+	i2c_hw_sent_nack,		/*!< Sent NACK */
+	i2c_hw_sent_stop,		/*!< Generated the star condition */
+	i2c_hw_error			/*!< Error */
+} i2c_hw_state_t;
+
+typedef enum
+{
+	i2c_perif_disabled,				/*!< Peripheral Is Disabled */
+	i2c_perif_reset,				/*!< Peripheral Is Reseted and in reset mode and need to be initialised */
+	i2c_perif_enabled,				/*!< I2C CHannle is initilized but not neceserly ready */
+	i2c_perif_ready,				/*!< Peripheral Initialized and ready for use */
+	i2c_perif_address_sent,			/*!< The Salve Address Was Sent to the bus */
+	i2c_perif_tx_ongoing,			/*!< A transfer to the bus is ongoing */
+	i2c_perif_tx_done,				/*!< The transfer to the bus is finished */
+	i2c_perif_rx_ongoing,			/*!< Recieving from the bus */
+	i2c_perif_rx_done,				/*!< Recived everything from the bus */
+	i2c_perif_listening,			/*!< Address Listen Mode is ongoing	*/
+	i2c_perif_listening_and_tx,		/*!< Address Listen Mode and ongoing Data Transmission */
+	i2c_perif_listening_and_rx,		/*!< Address Listen Mode and ongoing Data Reception	*/
+	i2c_perif_timeout,				/*!< Timeout state */
+	i2c_perif_Error					/*!< Error */
+} i2c_perif_state_t;
+/*! Struture a an i2c channel with all the required propereties*/
+typedef struct i2c_t
+{
+	i2cCh_t channelNo;					/*!< The harware channel to be used						*/	
+	i2c_mode_t mode;					/*!< Master, Slave or Multymaster Modes					*/
+	uint16_t mainAddress;				/*!< First and Main address of the device				*/ 
+	uint16_t secondAddress;				/*!< Second address if dual addresse mode is configured	*/
+	i2c_address_count_t addressCount;	/*!< Single or multiple									*/ 
+	i2c_address_size_t addressSize;		/*!< 10 or 7 bit address size							*/
+	i2c_clk_speed_t speed;				/*!< Bus Speed											*/  
+	i2c_clk_stretching_t stretching;	/*!< Clock Stretching enable onyl in slave mode			*/
+	i2c_wake_types_t wakeOn;			/*!< Define on which type of action the i2c channel should 
+										  wake up. Only if de prefiral goes to sleep			*/
+	i2c_hw_state_t hardwareState;		/*!< The current sitate of the I2C Bus					*/
+	i2c_perif_state_t periferalState;	/*!< The current sitate of the I2C Bus					*/
+}i2c_t;
+
+/***************************************************************************************************
+	I2C Configuration functions											
+***************************************************************************************************/
+
+/**
+ * @brief Initilize the I2C Hardware
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_init(	i2c_t *i2c_dev,					/*!< Pointer to I2C hardware Object						*/
+				i2cCh_t channelNo,					/*!< The harware channel to be used						*/	
+				i2c_mode_t mode,					/*!< Master, Slave or Multymaster Modes					*/
+				uint16_t mainAddress,				/*!< First and Main address of the device				*/ 
+				uint16_t secondAddress,				/*!< Second address if dual addresse mode is configured	*/
+				i2c_address_count_t addressCount,	/*!< Single or multiple									*/ 
+				i2c_address_size_t addressSize,		/*!< 10 or 7 bit address size							*/
+				i2c_clk_speed_t speed,				/*!< Bus Speed											*/  
+				i2c_clk_stretching_t stretching,	/*!< Clock Stretching enable onyl in slave mode			*/
+				i2c_wake_types_t wakeOn				/*!< Wake up condition									*/
+		);
+
+/**
+ * @brief De-Initilise the I2C Hardware
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_deinitialise(i2c_t *i2c_dev); 
+
+/**
+ * @brief Set the i2c channle to the gievn mode
+ * @param Channel is the i2c hardware channel
+ * @param mode The mode for i2c : Master Slave or Multymaster 
+ */
+void i2c_set_mode(i2c_t *i2c_dev, i2c_mode_t mode);
+
+/**
+ * @brief Set the i2c channel's address
+ * @param i2c_dev is the i2c hardware channel
+ * @param address is the desired address for the device
+ * @param addressTwo The second address for the device only if dual address mode is not defined
+ */
+void i2c_set_address(i2c_t *i2c_dev, uint16_t address);
+
+/**
+ * @brief Set the i2c channel's second address if the hardware allows it
+ * @param i2c_dev is the i2c hardware channel
+ * @param address is the desired address for the device
+ */
+void i2c_set_address_second(i2c_t *i2c_dev, uint16_t address);
+
+/**
+ * @brief Set the i2c Address Lenght, 7 bit or 8 bit, Master or slave doesn't make any difference
+ * @param i2c_dev is the i2c hardware channel
+ * @param size Is the Adress isze to be used 7 Bit or 10 Bit 
+ */
+void i2c_set_address_lenght(i2c_t *i2c_dev, i2c_address_size_t size);
+
+/**
+ * @brief Stets the Communication speed 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param speed the different awailable speeds
+ */
+void i2c_set_clk_speed(i2c_t *i2c_dev, i2c_clk_speed_t speed); 
+
+/**
+ * @brief Ebales or disables clock stretching functionalities 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param The value to be written in the register. This will heavily depend on the hardware
+ */
+void i2c_set_clk_stretch(i2c_t *i2c_dev, i2c_clk_stretching_t stretching);
+
+/**
+ * @brief Set the wakeup mode  
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param wake the desider wakeup mode for now i have found only one mode. 
+ */
+void i2c_set_wakeup(i2c_t *i2c_dev, i2c_wake_types_t wake); 
+
+/**
+ * @brief Configures Hardware implmente filters if there are any.  
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_set_filter(i2c_t *i2c_dev, uint8_t enable);
+
+/**
+ * @brief Set the timeout to close the i2c wait time if a communication fails. 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param timeout the desider timeout duration in ticks. 
+ */
+void i2c_set_timeout(i2c_t *i2c_dev, uint8_t timeout);
+
+/**
+ * @brief Resets the i2c Harware and register to it's factory deflauts.  
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_hardware_reset(i2c_t *i2c_dev);		
+
+/**
+ * @brief Enables I2C Hardware BUS & Clock & Pins  
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_hardware_enable(i2c_t *i2c_dev);	
+
+/**
+ * @brief Disables I2C Hardware.  
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_hardware_disable(i2c_t *i2c_dev);	
+
+/**
+ * @brief Resets the i2c Periferal to it's inital state.  
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_periferal_reset(i2c_t *i2c_dev);		
+
+/**
+ * @brief Enables I2C Periferal core.  
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_periferal_enable(i2c_t *i2c_dev);	
+
+/**
+ * @brief Disables I2C Periferal core.  
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_periferal_disable(i2c_t *i2c_dev);	
+
+/**************************************************************************************************
+	I2C Communication functions independen of opperating mode
+***************************************************************************************************/
+
+/**
+ * @brief	Writes the given amount of data to the selected device. This function will 
+ *			automaticaly choose between i2cMasterSend(); or i2cSlaveSend(); 
+ *			Depending if the I2C channel was initiated as slave or master. 
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data to be written
+ * @param dataLenght is the total quantity of 8 bit data to be written.
+ */
+void i2c_write(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
+
+/**
+ * @brief Reads the given amount of data to the selected device. This function will 
+ *			automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve(); 
+ *			Depending if the I2C channel was initiated as slave or master. 
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data which has been red
+ * @paran dataLenght is the total quantity of 8 bit data to be red
+ */
+void i2c_read(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
+
+/**
+ * @brief	Recieve a Single Byte as master from from the given devices register.
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2c_master_recieve(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+/**
+ * @brief	Sends a Single Byte as master to the given devices register. 
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the send command will be sent
+ * @param registerAddress is the regiter to be written to the device
+ * @param data is the data to be sent
+ */
+void i2c_master_send(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**
+ * @brief	Recieve a Single Byte as slave from given devices register.
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2c_slave_recieve(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**
+ * @brief	Recieve a Single Byte as slave from the given devices register.
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2c_slave_send(i2c_t *i2c_dev, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**************************************************************************************************
+	I2C Hardware functions
+***************************************************************************************************/
+/**
+ * @brief Checks if the device is ready for any type of communication	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+uint8_t i2c_is_perif_ready(i2c_t *i2c_dev);
+
+/**
+ * @brief Generates a Start condition.	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_send_start(i2c_t *i2c_dev);
+
+/**
+ * @brief Generates a Start condition.	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_send_stop(i2c_t *i2c_dev);
+
+/**
+ * @brief Generates a NACK condition.	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_send_nack(i2c_t *i2c_dev);
+
+/**
+ * @brief Checks If a NACK is recieved.	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+uint8_t i2c_check_nack(i2c_t *i2c_dev);
+
+/**
+ * @brief Generates a ACK condition.	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_send_ack(i2c_t *i2c_dev);
+
+/**
+ * @brief Initiates the communication  by sending the slave address on the bus followed by a WRITE 
+ * and waits for an ACK (aknowledge)
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress The address of the slave to be communicated
+ */
+void i2c_send_address_for_write(i2c_t *i2c_dev, uint16_t *slaveAddress);
+
+/**
+ * @brief Initiates the communication by sending the slave address on the bus followed by a READ 
+ * and waits for an ACK (aknowledge)
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress The address of the slave to be communicated
+ */
+void i2c_send_address_for_read(i2c_t *i2c_dev, uint16_t *slaveAddress);
+
+/**
+ * @brief Sende the register adrres with which we want to communicate.
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param registerAddress The register address of the slave device that we are communication with
+ */
+void i2c_send_reg_address(i2c_t *i2c_dev, uint8_t *registerAddress);
+
+/**
+ * @brief Send the register that we want to read or write.	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param registerAddress the register that need to be accessed
+ */
+void i2c_send_data(i2c_t *i2c_dev, uint8_t *data);
+
+/**
+ * @brief Initiates a Write command with the previously set slave address. 	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_init_write_command(i2c_t *i2c_dev);
+
+/**
+ * @brief Initiates a read command with the previously set slave address. 	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_init_read_command(i2c_t *i2c_dev);
+
+/**
+ * @brief Is the output buffer full. This also means that there is data present in the ouput buffer
+ * is sent to the i2c BUS. 	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+uint8_t i2c_is_output_buffer_full(i2c_t *i2c_dev);
+
+/**
+ * @brief Is the input buffer full. This also means that there is data present in the input buffer
+ * is sent to the i2c BUS. 	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @return 1 when input buffer is full | 0 whenthe input buffer is empty
+ */
+uint8_t i2c_is_input_buffer_full(i2c_t *i2c_dev);
+
+/**
+ * @brief reads the I2C input buffer
+ * is sent to the i2c BUS. 	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param data pointer to the data that need to be read and returned
+ */
+void i2c_get_input_register(i2c_t *i2c_dev, uint8_t *data);
+
+/**
+ * @brief writes to the I2C output buffer
+ * is sent to the i2c BUS. 	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param data pointer to the data that need to be read and returned
+ */
+void i2c_set_output_register(i2c_t *i2c_dev, uint8_t *data);
+
+/**
+ * @brief Checks if transfer is complete
+ * is sent to the i2c BUS. 	
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param data pointer to the data that need to be read and returned
+ * @return 1 when Transefer is complete | 0 When Transfer is ongoing
+ */
+uint8_t i2c_is_tx_complete(i2c_t *i2c_dev);
+
+/**
+ * @brief Defines the amount of transfers to be made. Address exchange and start conditon does not count
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param count amount o data to be transfered. 
+ */
+void i2c_set_tx_counter(i2c_t *i2c_dev, uint8_t count);
+
+/**************************************************************************************************
+	I2C Arbitration Functions for Multymaster mode and slaves clock stretching 
+***************************************************************************************************/
+void i2c_arbitrate_clk_sync();				// I2C Standart : Clock Syncronization
+void i2c_arbitrate_multymaster_abort_tx();	// I2c Standart : Stop Communication for multimaster mode 
+void i2c_arbitrate();						// I2C Standart : Arbitration for multimaster mode to define the right master. 
+void i2c_arbitrate_soft_rst();				// I2C Standart : Software reset not supported by all hardware.
+void i2c_arbitration_clear_bus();			// I2C Standart : in case if SCL is stuck 
+
+/**************************************************************************************************
+	I2C Extra functions that are not esential for the main functionality
+***************************************************************************************************/
+
+/**
+ * @brief	This function will scan every for possible addresses to discover devices on the bus.
+ *			And write them to the Devices list given to him. This function will not discover more 
+ *			devices than what he is told. 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param devices list where the discevered devices will be written
+ * @param deviceCount Max number of devices to be discovered.
+ */
+void i2c_discover_devices(i2c_t *i2c_dev, uint16_t *devices, uint8_t deviceCount);	   
+
+/**
+ * @brief	This function will try to communicate with a device with every speed 
+ *			allowed by his hardware to find out the maximum communication sppeed possible.
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ */
+i2c_clk_speed_t i2c_test_bus_speed(i2c_t *i2c_dev, uint16_t *slaveAddress);	
+
+/**
+ * @brief	This function will read the device info register (if awailable) as follows : 
+ *			I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev. 
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to be red
+ */
+uint32_t i2c_get_device_info(i2c_t *i2c_dev, uint16_t *slaveAddress);	
+
+/**
+ * @brief The selected i2c channel is put on sleep.
+ * @param i2c_dev is the beforehand declared i2c channel with his opperation modes
+ */
+void i2c_sleep(i2c_t *i2c_dev); 
+
+/**
+ * @brief Error handling.
+ * @param error The error no generated. 
+ */
+void i2c_throw_error(i2c_t *i2c_dev, int16_t error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _I2C_H_
diff --git a/peripherals/i2c.bak.c b/peripherals/i2c/i2c.bak.c
similarity index 100%
rename from peripherals/i2c.bak.c
rename to peripherals/i2c/i2c.bak.c
diff --git a/peripherals/i2c.bak.h b/peripherals/i2c/i2c.bak.h
similarity index 100%
rename from peripherals/i2c.bak.h
rename to peripherals/i2c/i2c.bak.h
diff --git a/peripherals/i2c/i2c.c b/peripherals/i2c/i2c.c
new file mode 100644
index 0000000..e3dfc98
--- /dev/null
+++ b/peripherals/i2c/i2c.c
@@ -0,0 +1,130 @@
+#include "i2c.h"
+#include "usart.h"
+
+void i2cInit(	i2c_t *i2cHardware,					
+				i2cCh_t channelNo,						
+				i2cMode_t mode,						
+				uint16_t mainAddress,				 
+				uint16_t secondAddress,				
+				i2cAddressCount_t addressCount,		 
+				i2cAddressSize_t addressSize,		
+				i2cSpeed_t speed,					  
+				i2cOpperationMode_t opperationMode,	
+				i2cClockStretching_t stretching,	
+				i2cWakeUpTypes_t wakeOn)			
+{
+	i2cHardware->channelNo = channelNo;
+	i2cHardware->mode = mode;
+	i2cHardware->mainAddress = mainAddress;				 
+	i2cHardware->secondAddress = secondAddress;
+	i2cHardware->addressCount = addressCount; 
+	i2cHardware->addressSize = addressSize;
+	i2cHardware->speed = speed; 														
+	i2cHardware->opperationMode = opperationMode; 
+	i2cHardware->stretching = stretching;
+	i2cHardware->wakeOn = wakeOn;
+	i2cHardware->hardwareState = i2cHwIdle;
+	i2cHardware->periferalState = i2cPerifNotInitialized;
+
+	i2cEnableHardware(i2cHardware);	
+	i2cDisablePeriferal(i2cHardware);	
+	i2cConfigureFilters(i2cHardware);
+	i2cSetClockStretch(i2cHardware, stretching);
+	i2cSetSpeed(i2cHardware, speed);
+	i2cSetMode(i2cHardware, opperationMode);
+	i2cSetAddressLenght(i2cHardware, addressSize);
+	i2cSetAddress(i2cHardware, mainAddress, secondAddress);
+	i2cEnablePeriferal(i2cHardware);	
+	
+	while(i2cHardware->periferalState != i2cPerifReady)
+	{
+		i2cIsPeriferalReady(i2cHardware);
+	}
+
+	i2cHardware->periferalState = i2cPerifInitialized;
+}
+
+
+void i2cDeInit(i2c_t *i2cHardware)
+{
+
+}	
+
+
+void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
+{	
+
+//
+// Start
+// Send Address
+// Wait For ACK
+//
+	uint8_t nbytes = 0; 
+
+	i2cHardware->periferalState = i2cPerifTransmitting;
+	
+	i2cSetTransferCounter(i2cHardware,1); 
+	i2cSendSlaveAddressWrite(i2cHardware, slaveAddress);	
+	i2cSendRegisterAddress(i2cHardware,registerAddress);
+	
+	while(i2cHardware->periferalState != i2cPerifTransferComplete)
+	{
+		i2cIsTransferComplete(i2cHardware);
+	}
+	
+	i2cHardware->periferalState = i2cPerifRecieving;
+	i2cSendSlaveAddressRead(i2cHardware, slaveAddress);
+	
+	
+	while(i2cHardware->periferalState != i2cPerifTransferComplete)
+	{
+		i2cIsTransferComplete(i2cHardware);
+	}
+
+	i2cGenerateNack(i2cHardware);
+	i2cGenerateStop(i2cHardware);
+	
+	i2cReadInputRegister(i2cHardware, data);
+	
+	print_Usart(usart2, "\n\rI2C Read completed\n\r"); 
+
+	while(i2cHardware->periferalState != i2cPerifReady)
+	{
+		i2cIsPeriferalReady(i2cHardware);
+	}
+	i2cHardware->periferalState = i2cPerifReady;
+	i2cHardware->hardwareState = i2cHwIdle;
+}
+
+void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght)
+{
+	i2cSetTransferCounter(i2cHardware,2); 
+	i2cSendSlaveAddressWrite(i2cHardware, slaveAddress);	
+	i2cSendRegisterAddress(i2cHardware,registerAddress);
+	while((i2cHardware->hardwareState =! i2cHwOutputBufferEmpty))
+	{
+		i2cIsOutputBufferEmpty(i2cHardware);
+	}
+	i2cSendData(i2cHardware,data);
+	
+	i2cGenerateStop(i2cHardware);
+	print_Usart(usart2, "\n\rI2C Transfer completed\n\r"); 
+}
+
+void i2cThrowError(i2c_t *i2cHardware, int16_t error)
+{
+	print_Usart(usart2, "\n\r"); 
+	print_Usart(usart2, "\n\r"); 
+	print_Usart(usart2, "I2C Error Detected : "); 
+
+	if (i2cHardware->periferalState == i2cPerifTransmitting)
+		print_Usart(usart2, "i2cPerifTransmitting"); 
+	if (i2cHardware->periferalState == i2cPerifRecieving)
+		print_Usart(usart2, "i2cPerifRecieving"); 
+	
+	print_Usart(usart2, "\n\r"); 
+	print_Usart(usart2, "I2C Error No: "); 
+	usartSendChar(usart2, error + 0x30); 
+	print_Usart(usart2, "\n\r"); 
+	print_Usart(usart2, "\n\r"); 
+}
diff --git a/peripherals/i2c/i2c.h b/peripherals/i2c/i2c.h
new file mode 100755
index 0000000..c2cda5d
--- /dev/null
+++ b/peripherals/i2c/i2c.h
@@ -0,0 +1,565 @@
+/**
+  **************************************************************************************************
+  * @file		i2c.h
+  * @author		Kerem Yollu & Edwin Koch
+  * @date		18.07.2022
+  * @version	1.01
+  ************************************************************************************************** 
+  * @brief		I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips : 
+  *				following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA		
+  *				This will also not have a I3C support for the forseable futrue. 
+  *				
+  * **Detailed Description :**
+  * 
+  *	I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips : 
+  *	following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA		
+  *	This will also not have a I3C support for the forseable futrue. 
+  *
+  * @todo 
+  * - 26.07.2021 : Implement the DMA  
+  * - 26.07.2021 : Implement the Interrupt  
+  * - 26.07.2021 : Implement the Sleep/WakeUp  
+  * - 26.07.2021 : Implement the Slave opperation  
+  **************************************************************************************************
+*/
+
+#ifndef _I2C_H_
+#define _I2C_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hardwareDescription.h"
+#include "pin.h"
+
+
+
+/*! Enum of possible I2C opperation modes */
+typedef enum{
+	i2cModeMaster,			/*!< Master mode : In Master mode, the I2C interface initiates 
+							  a data transfer and generates the clock signal. **DEFAULT**			*/ 
+	i2cModeMultyMaster,		/*!< Multimaster Mode : In case if more than one master are present 
+							  in one I2C bus. In such case each device needs to be able to 
+							  cooperate knowing that another device could talking 
+							  therefore the bus is busy (Arbirtation). 
+							  For More information : https://www.i2c-bus.org/multimaster/		*/
+	i2cModeSlave			/*!< Slave mode : A slave device has to always be ready to detect and 
+							  process a start condition and to recognize its address			*/
+}i2cMode_t; 
+	
+/*! Enum of possible I2C speeds */
+typedef enum{
+	i2cSpeedStandart,	/*!< SM 100 kbits/s Standart i2c Speed **DEFAULT**	*/ 
+	i2cSpeedFast,		/*!< FM 400 kbits/s									*/
+	i2cSpeedFastPlus,	/*!< FM+ 1 Mbits/s									*/
+	i2cSpeedHightSpeed, /*!< HS 3.4 Mbits/s									*/
+	i2cSpeedUltraFast	/*!< UFM 5 Mbits/s									*/
+}i2cSpeed_t;
+
+/*! Enum of possible I2C Adress sizes */
+typedef enum{
+	i2cAddressSizeSevenBits,	/*!< 7 Bits address size **DEFAULT**	*/ 
+	i2cAddressSizeTenBits		/*!< 10 Bits address size				*/
+}i2cAddressSize_t;
+
+/*! Enum of possible I2C Address count */
+typedef enum{
+	i2cAddressCountSingle,	/*!< Only one address for communication **DEFAULT**					*/ 
+	i2cAddressCountDual		/*!< Dual addresses for one device respondng to two addresses			*/
+}i2cAddressCount_t;
+
+/*! Enum for clock strechning activation. Can only be implmented as Slave 
+ * for more information : https://www.i2c-bus.org/clock-stretching/								*/
+typedef enum{
+	i2cClockStretchingDisable,	/*!< We assume that the master and slave have compatible 
+								  Clock frequencies	**DEFAULT**									*/
+	i2cClockStretchingEnable	/*!< In situations where an I2C slave is not able to co-operate 
+								  with the clock speed given by the master and needs to slow down. 
+								  This is done by a mechanism referred to as clock stretching.	*/ 
+}i2cClockStretching_t;
+
+/*! Enum for diffenrent wake up methodes wehnin sleep mode */
+typedef enum{
+	i2cWakeUpDisabled,		/*!< No wake up is possible this is the default mode also means that 
+							  the sleep function is not implmentes **DEFAULT**					*/
+	i2cWakeUpOnAddressMatch	/*!< Wakes up on address match, this can be harware dependent		*/
+}i2cWakeUpTypes_t;
+
+/*! Enum operation mode of the i2c channel */
+typedef enum{
+	i2cOpperationPolling,	/*!< Polling mode Blocking, i2c communication states are constantly 
+							  checked on polling mode so it can be stoped 
+							  when interrupts occures **DEFAULT**								*/
+	i2cOpperationInt,		/*!< Interrut Mode Non-blocking, i2c communications state changes 	
+							  generates an interrupt and can be handeled this way				*/
+	i2cOpperationDma		/*!< DMA Mode Non-blocking, I2C communication satets are managed 
+							  via Inteerupts and with Direct Memory Access						*/
+}i2cOpperationMode_t;
+
+/*! typedef for the i2c states*/
+typedef enum
+{
+	i2cHwIdle,					/*!< Hardware is in Idle Mode  **DEFAULT**				*/
+	i2cHwStartGenerated,		/*!< Generated the star condition						*/
+	i2cHwOutputBufferFull,		/*!< The output buffer of the I2C Periferal is Full		*/
+	i2cHwOutputBufferEmpty,		/*!< The output buffer of the I2C Periferal is Empty	*/
+	i2cHwInputBufferFull,		/*!< The input buffer of the I2C Periferal Is Full		*/
+	i2cHwInputBufferEmpty,		/*!< The input buffer of the I2C Periferal Is Empty		*/
+	i2cHwSentRead,				/*!< Sent read request									*/
+	i2cHwSentWrite,				/*!< Sent write request									*/
+	i2cHwGotAck,				/*!< Recieved ACK										*/
+	i2cHwGotNack,				/*!< Recieved NACK										*/
+	i2cHwSentAck,				/*!< Sent ACK											*/
+	i2cHwSentNack,				/*!< Sent NACK											*/
+	i2cHwStopGenerated,			/*!< Generated the star condition						*/
+	i2cHwError					/*!< Error												*/
+} i2cHardwareState_t;
+
+typedef enum
+{
+	i2cPerifNotInitialized,				/*!< Default Peripheral is not yet Initialized **DEFAULT**		*/
+	i2cPerifInitialized,				/*!< I2C CHannle is initilized but not neceserly ready			*/
+	i2cPerifSlaveAddressSent,			/*!< The Salve Address Was Sent to the bus						*/
+	i2cPerifTransferComplete,			/*!< A full communication process is complete (wire or Read)	*/
+	i2cPerifTransferOngoign,			/*!< A full communication process is in progress (wire or Read)	*/
+	i2cPerifReady,						/*!< Peripheral Initialized and ready for use					*/
+	i2cPerifSlaveNotFound,				/*!< Desired Slave was not able to be found 					*/
+	i2cPerifTransmitting,				/*!< Data Transmission process is ongoing						*/
+	i2cPerifRecieving,					/*!< Data Reception process is ongoing							*/
+	i2cPerifListening,					/*!< Address Listen Mode is ongoing								*/
+	i2cPerifListeningAndTransmitting,	/*!< Address Listen Mode and ongoing Data Transmission			*/
+	i2cPerifListeningAndRecieveing,		/*!< Address Listen Mode and ongoing Data Reception				*/
+	i2cPerifAbort,						/*!< Abort user request ongoing									*/
+	i2cPerifTimeout,					/*!< Timeout state												*/
+	i2cPerifError						/*!< Error														*/
+} i2cPeriferalState_t;
+/*! Struture a an i2c channel with all the required propereties*/
+typedef struct i2c_t
+{
+	i2cCh_t channelNo;					/*!< The harware channel to be used						*/	
+	i2cMode_t mode;						/*!< Master, Slave or Multymaster Modes					*/
+	uint16_t mainAddress;				/*!< First and Main address of the device				*/ 
+	uint16_t secondAddress;				/*!< Second address if dual addresse mode is configured	*/
+	i2cAddressCount_t addressCount;		/*!< Single or multiple									*/ 
+	i2cAddressSize_t addressSize;		/*!< 10 or 7 bit address size							*/
+	i2cSpeed_t speed;					/*!< Bus Speed											*/  
+	i2cOpperationMode_t opperationMode;	/*!< Blocking or non blocking polling, Int or DMA		*/
+	i2cClockStretching_t stretching;	/*!< Clock Stretching enable onyl in slave mode			*/
+	i2cWakeUpTypes_t wakeOn;			/*!< Define on which type of action the i2c channel should 
+										  wake up. Only if de prefiral goes to sleep			*/
+	i2cHardwareState_t hardwareState;	/*!< The current sitate of the I2C Bus					*/
+	i2cPeriferalState_t periferalState;	/*!< The current sitate of the I2C Bus					*/
+}i2c_t;
+
+/***************************************************************************************************
+	I2C Configuration functions											
+***************************************************************************************************/
+
+/**
+ * @brief Initilize the I2C Hardware
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cInit(	i2c_t *i2cHardware,					/*!< Pointer to I2C hardware Object						*/
+				i2cCh_t channelNo,					/*!< The harware channel to be used						*/	
+				i2cMode_t mode,						/*!< Master, Slave or Multymaster Modes					*/
+				uint16_t mainAddress,				/*!< First and Main address of the device				*/ 
+				uint16_t secondAddress,				/*!< Second address if dual addresse mode is configured	*/
+				i2cAddressCount_t addressCount,		/*!< Single or multiple									*/ 
+				i2cAddressSize_t addressSize,		/*!< 10 or 7 bit address size							*/
+				i2cSpeed_t speed,					/*!< Bus Speed											*/  
+				i2cOpperationMode_t opperationMode,	/*!< Blocking or non blocking polling, Int or DMA		*/
+				i2cClockStretching_t stretching,	/*!< Clock Stretching enable onyl in slave mode			*/
+				i2cWakeUpTypes_t wakeOn				/*!< Wake up condition									*/
+		);
+
+/**
+ * @brief De-Initilize the I2C Hardware
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cDeInit(i2c_t *i2cHardware); 
+
+/**
+ * @brief Set the i2c channle to the gievn mode
+ * @param Channel is the i2c hardware channel
+ * @param mode The mode for i2c : Master Slave or Multymaster 
+ */
+void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode);
+
+/**
+ * @brief Set the i2c channles mode as Master Slave or Multymaster
+ * @param i2cHardware is the i2c hardware channel
+ * @param addressOne The forst address for the device
+ * @param addressTwo The second address for the device only if dual address mode is not defined
+ */
+void i2cSetAddress(i2c_t *i2cHardware, uint16_t mainAddress, uint16_t secondAddress);
+
+/**
+ * @brief Set the i2c Address Lenght, 7 bit or 8 bit, Master or slave doesn't make any difference
+ * @param i2cHardware is the i2c hardware channel
+ * @param size Is the Adress isze to be used 7 Bit or 10 Bit 
+ */
+void i2cSetAddressLenght(i2c_t *i2cHardware, i2cAddressSize_t size);
+
+/**
+ * @brief Stets the Communication speed 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param speed the different awailable speeds
+ */
+void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed); 
+
+/**
+ * @brief Initiates the opperation mode for the selected i2c Channel 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param opperation define if the i2c channel will opperate on pollin, Interrupt, or DMA modes 
+ */
+void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation);
+
+
+/**
+ * @brief Ebales or disables clock stretching functionalities 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param The value to be written in the register. This will heavily depend on the hardware
+ */
+void i2cSetClockStretch(i2c_t *i2cHardware, i2cClockStretching_t stretching);
+
+/**
+ * @brief Set the wakeup mode  
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param wake the desider wakeup mode for now i have found only one mode. 
+ */
+void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake); 
+
+/**
+ * @brief Configures Hardware implmente filters if there are any.  
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cConfigureFilters(i2c_t *i2cHardware);	
+
+/**
+ * @brief Set the timeout to close the i2c wait time if a communication fails. 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param timeout the desider timeout duration in ticks. 
+ */
+void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout);
+
+/**
+ * @brief Resets the i2c Periferal to it's inital state.  
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cPeriferalReset(i2c_t *i2cHardware);		
+
+/**
+ * @brief Resets the i2c Harware and register to it's factory deflauts.  
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cHardwareReset(i2c_t *i2cHardware);		
+
+/**
+ * @brief Enables I2C Hardware BUS & Clock & Pins  
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cEnableHardware(i2c_t *i2cHardware);	
+
+/**
+ * @brief Enables I2C Periferal core.  
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cEnablePeriferal(i2c_t *i2cHardware);	
+
+/**
+ * @brief Disables I2C Periferal core.  
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cDisablePeriferal(i2c_t *i2cHardware);	
+
+/**************************************************************************************************
+	I2C Communication functions independen of opperating mode
+***************************************************************************************************/
+
+/**
+ * @brief	Writes the given amount of data to the selected device. This function will 
+ *			automaticaly choose between i2cMasterSend(); or i2cSlaveSend(); 
+ *			Depending if the I2C channel was initiated as slave or master. 
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data to be written
+ * @param dataLenght is the total quantity of 8 bit data to be written.
+ */
+void i2cWrite(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
+
+/**
+ * @brief Reads the given amount of data to the selected device. This function will 
+ *			automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve(); 
+ *			Depending if the I2C channel was initiated as slave or master. 
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data which has been red
+ * @paran dataLenght is the total quantity of 8 bit data to be red
+ */
+void i2cRead(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data, uint8_t *dataLenght);
+
+/**
+ * @brief	Recieve a Single Byte as master from from the given devices register.
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+/**
+ * @brief	Sends a Single Byte as master to the given devices register. 
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the send command will be sent
+ * @param registerAddress is the regiter to be written to the device
+ * @param data is the data to be sent
+ */
+void i2cMasterSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**
+ * @brief	Recieve a Single Byte as slave from given devices register.
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2cSlaveRecieve(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**
+ * @brief	Recieve a Single Byte as slave from the given devices register.
+ *			this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**************************************************************************************************
+	I2C Hardware functions
+***************************************************************************************************/
+/**
+ * @brief Checks if the device is ready for any type of communication	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cIsPeriferalReady(i2c_t *i2cHardware);
+
+/**
+ * @brief Generates a Start condition.	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cGenerateStart(i2c_t *i2cHardware);
+
+/**
+ * @brief Generates a Start condition.	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cGenerateStop(i2c_t *i2cHardware);
+
+/**
+ * @brief Generates a NACK condition.	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cGenerateNack(i2c_t *i2cHardware);
+
+/**
+ * @brief Checks If a NACK is recieved.	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+uint8_t i2cCheckNack(i2c_t *i2cHardware);
+
+/**
+ * @brief Generates a ACK condition.	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cGenerateAck(i2c_t *i2cHardware);
+
+/**
+ * @brief Initiates the communication  by sending the slave address on the bus followed by a WRITE 
+ * and waits for an ACK (aknowledge)
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress The address of the slave to be communicated
+ */
+void i2cSendSlaveAddressWrite(i2c_t *i2cHardware, uint16_t *slaveAddress);
+
+/**
+ * @brief Initiates the communication by sending the slave address on the bus followed by a READ 
+ * and waits for an ACK (aknowledge)
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress The address of the slave to be communicated
+ */
+void i2cSendSlaveAddressRead(i2c_t *i2cHardware, uint16_t *slaveAddress);
+
+/**
+ * @brief Sende the register adrres with which we want to communicate.
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param registerAddress The register address of the slave device that we are communication with
+ */
+void i2cSendRegisterAddress(i2c_t *i2cHardware, uint8_t *registerAddress);
+
+/**
+ * @brief Send the register that we want to read or write.	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param registerAddress the register that need to be accessed
+ */
+void i2cSendData(i2c_t *i2cHardware, uint8_t *data);
+
+/**
+ * @brief Initiates a Write command with the previously set slave address. 	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cInitiateWriteCommand(i2c_t *i2cHardware);
+
+/**
+ * @brief Initiates a read command with the previously set slave address. 	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cInitiateReadCommand(i2c_t *i2cHardware);
+
+/**
+ * @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
+ * is sent to the i2c BUS. 	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cIsOutputBufferEmpty(i2c_t *i2cHardware);
+
+/**
+ * @brief Is the output buffer empty. This allso meas that the data that was in the ouput buffer
+ * is sent to the i2c BUS. 	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cIsInputBufferEmpty(i2c_t *i2cHardware);
+
+/**
+ * @brief reads the I2C input buffer
+ * is sent to the i2c BUS. 	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param data pointer to the data that need to be read and returned
+ */
+void i2cReadInputRegister(i2c_t *i2cHardware, uint8_t *data);
+
+/**
+ * @brief writes to the I2C output buffer
+ * is sent to the i2c BUS. 	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param data pointer to the data that need to be read and returned
+ */
+void i2cSetOutputRegister(i2c_t *i2cHardware, uint8_t *data);
+
+/**
+ * @brief Checks is transfer is complete
+ * is sent to the i2c BUS. 	
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param data pointer to the data that need to be read and returned
+ */
+void i2cIsTransferComplete(i2c_t *i2cHardware);
+
+/**
+ * @brief Defines the amount of transfers to be made. Address exchange and start conditon does not count
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param count amount o data to be transfered. 
+ */
+void i2cSetTransferCounter(i2c_t *i2cHardware, uint8_t count);
+/**************************************************************************************************
+	I2C Communication functions Polling / Blocking Mode
+***************************************************************************************************/
+
+/**
+ * @brief	Recieve a Single Byte in polling mode as master from from the given devices register.
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+/**
+ * @brief	Sends a Single Byte in polling mode as master to the given devices register. 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the send command will be sent
+ * @param registerAddress is the regiter to be written to the device
+ * @param data is the data to be sent
+ */
+void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**
+ * @brief	Recieve a Single Byte in polling mide as slave from the given devices register.
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2cSlaveRecievePolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**
+ * @brief	Recieve a Single Byte in polling mode as slave from the given devices register.
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ * @param registerAddress is the regiter to be red from the device
+ * @param data is the data whic has been red
+ */
+void i2cSlaveSendPolling(i2c_t *i2cHardware, uint16_t *slaveAddress, uint8_t *registerAddress, uint8_t *data);
+
+/**************************************************************************************************
+	I2C Arbitration Functions for Multymaster mode and slaves clock stretching 
+***************************************************************************************************/
+void i2cClockSynchronise();	// I2C Standart : Clock Syncronization
+void i2cAbortTransmit();	// I2c Standart : Stop Communication for multimaster mode 
+void i2cArbitration();		// I2C Standart : Arbitration for multimaster mode to define the right master. 
+void i2cSoftReset();		// I2C Standart : Software reset not supported by all hardware.
+void i2cBusClear();			// I2C Standart : in case if SCL is stuck 
+
+
+/**************************************************************************************************
+	I2C Extra functions that are not esential for the main functionality
+***************************************************************************************************/
+
+/**
+ * @brief	This function will scan every for possible addresses to discover devices on the bus.
+ *			And write them to the Devices list given to him. This function will not discover more 
+ *			devices than what he is told. 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param devices list where the discevered devices will be written
+ * @param deviceCount Max number of devices to be discovered.
+ */
+void i2cDiscoverDevices(i2c_t *i2cHardware, uint16_t *devices, uint8_t deviceCount);	   
+
+/**
+ * @brief	This function will try to communicate with a device with every speed 
+ *			allowed by his hardware to find out the maximum communication sppeed possible.
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to which the read command will be sent
+ */
+i2cSpeed_t i2cTestDeviceSpeed(i2c_t *i2cHardware, uint16_t *slaveAddress);	
+
+/**
+ * @brief	This function will read the device info register (if awailable) as follows : 
+ *			I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev. 
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ * @param slaveAddress is the address of the device to be red
+ */
+uint32_t i2cReadDeviceInfo(i2c_t *i2cHardware, uint16_t *slaveAddress);	
+
+/**
+ * @brief The selected i2c channel is put on sleep.
+ * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
+ */
+void i2cSleep(i2c_t *i2cHardware); 
+
+/**
+ * @brief Error handling.
+ * @param error The error no generated. 
+ */
+void i2cThrowError(i2c_t *i2cHardware, int16_t error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _I2C_H_