/*
 * i2c.c
 *
 * Created: 20.02.2019 20:33:30
 *  Author: jens
 */ 

#include <stdio.h>
#include <avr/io.h>
#include "i2c.h"

void i2c_init()
{
	TWBR = 0xFF;
	TWSR = 0x00;
}

void i2c_send(uint8_t addr, uint8_t rw, uint8_t *data, size_t size)
{
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	// Send START condition
	do
	{
		while (!(TWCR &(1<<TWINT)));	// Wait for TWINT Flag set. This indicates
		// that the START condition has been
		// transmitted.
		if((TWSR & 0xF8) != I2C_START)
		{
			printf("Error I2C_START\n");
			break;
		}
		TWDR = addr<<1 | rw;					// Load SLA_W into TWDR Register. Clear
		// TWINT bit in TWCR to start transmission of
		// address.
		TWCR = (1<<TWINT) | (1<<TWEN);
		while (!(TWCR &(1<<TWINT)));	// Wait for TWINT Flag set. This indicates
		// that the SLA+W has been transmitted, and
		// ACK/NACK has been received.


		if ((TWSR & 0xF8) != I2C_SLA_ACK)
		{
			printf("Error I2C_SLA_ACK\n");
			break;
		}
		// Check value of TWI Status Register. Mask
		// prescaler bits. If status different from
		// MT_SLA_ACK go to ERROR
		for (size_t i=0; i < size; i++)
		{
			
			TWDR = *(data++);
			TWCR = (1<<TWINT) | (1<<TWEN);
			// Load DATA into TWDR Register. Clear
			// TWINT bit in TWCR to start transmission of
			// data.

			while (!(TWCR & (1<<TWINT)));
			// Wait for TWINT Flag set. This indicates
			// that the DATA has been transmitted, and
			// ACK/NACK has been received}

			if ((TWSR & 0xF8) != I2C_DATA_ACK)
			{
				printf("Error I2C_DATA_ACK\n");
				break;
			}
			//	Check value of TWI Status Register. Mask
			//	prescaler bits. If status different from
			//	MT_DATA_ACK go to ERROR.
		}
		
	} while (0);
	TWCR = (1<<TWINT)| (1<<TWEN)|(1<<TWSTO);	// Transmit STOP condition.

}
