| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 | /* * I2C.c * k4be 2022 * License: BSD */ #include <avr/io.h>#include <util/delay.h>#include "I2C.h"#include "main.h"#define I2C_FREQ	400000#define	PRESCALER	1 /* possible values: 1, 4, 16, 64 */void I2C_init(void){	TWBR = (F_CPU/I2C_FREQ - 16.0)/2.0/PRESCALER;#if PRESCALER == 1	TWSR |= 0;#elif	PRESCALER == 4	TWSR |= _BV(TWPS0);#elif PRESCALER == 16	TWSR |= _BV(TWPS1);#elif PRESCALER == 64	TWSR |= _BV(TWPS1) | _BV(TWPS0);#else#error Invalid prescaler#endif}/* two byte command (or command + value) */unsigned int I2C_SendCommand(unsigned char address, unsigned char command, unsigned char data_byte){	unsigned int error = ERROR_I2C;	for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)	{		error = 0;		TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition		error |= I2C_WaitForTWInt();				error |= I2C_SendOneCommandByte(address << 1);		error |= I2C_SendOneCommandByte(command);		error |= I2C_SendOneCommandByte(data_byte);				TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);	}		return error;}/* three byte command (or command + 2 values) */unsigned int I2C_SendCommand3byte(unsigned char address,unsigned char command,unsigned char data0, unsigned char data1){	unsigned int error = ERROR_I2C;	for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)	{		error = 0;		TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition		error |= I2C_WaitForTWInt();				error |= I2C_SendOneCommandByte(address << 1);		error |= I2C_SendOneCommandByte(command);		error |= I2C_SendOneCommandByte(data0);		error |= I2C_SendOneCommandByte(data1);				TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);	}	return error;}/* read single byte */unsigned int I2C_ReceiveCommand(unsigned char address, unsigned char command, unsigned char *data_byte){	unsigned int error = ERROR_I2C;	unsigned char _unused;	for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)	{		error = 0;		TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition		error |= I2C_WaitForTWInt();				error |= I2C_SendOneCommandByte(address << 1);		error |= I2C_SendOneCommandByte(command);		error |= I2C_SendOneCommandByte((address << 1) | 1);		TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);		error |= I2C_WaitForTWInt();		error |= I2C_ReceiveOneCommandByte(&_unused, 0);		error |= I2C_ReceiveOneCommandByte(data_byte, 0);		TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);	}		return error;}/* send command + any byte count */unsigned int I2C_Send_n_bytes(unsigned char address,unsigned char command, const unsigned char *data, unsigned int length){	unsigned int error = ERROR_I2C;	unsigned int i;		for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)	{		error = 0;		TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition		error |= I2C_WaitForTWInt();				error |= I2C_SendOneCommandByte(address << 1);		error |= I2C_SendOneCommandByte(command);		for(i=0;i<length;i++){			error |= I2C_SendOneCommandByte(data[i]);		}				TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);	}	return error;}/* read any byte count */unsigned int I2C_Receive_n_bytes(unsigned char address, unsigned char command, unsigned char *data, unsigned int length){	unsigned int i;	unsigned int error = ERROR_I2C;	for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)	{		error = 0;		TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition		error |= I2C_WaitForTWInt();				error |= I2C_SendOneCommandByte(address << 1);		error |= I2C_SendOneCommandByte(command);				TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);		_delay_us(1);		TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);		error |= I2C_WaitForTWInt();				error |= I2C_SendOneCommandByte((address << 1) | 1);		for(i=0; i<length; i++){			error |= I2C_ReceiveOneCommandByte(&data[i], i != length-1);		}		TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);	}		return error;}/* read 2 bytes */unsigned int I2C_ReceiveCommand3byte(unsigned char address, unsigned char command, unsigned char *data0, unsigned char *data1){	unsigned int error = ERROR_I2C;	unsigned char _unused;	for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)	{		error = 0;		TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);//Send START condition		error |= I2C_WaitForTWInt();				error |= I2C_SendOneCommandByte(address << 1);		error |= I2C_SendOneCommandByte(command);		error |= I2C_SendOneCommandByte((address << 1) | 1);				TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);		error |= I2C_WaitForTWInt();		error |= I2C_ReceiveOneCommandByte(&_unused, 0);		error |= I2C_ReceiveOneCommandByte(data0, 0);		error |= I2C_ReceiveOneCommandByte(data1, 0);				TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);	}		return error;}unsigned int I2C_SendOneCommandByte(unsigned char command){	TWDR = command;	TWCR = (1<<TWINT) | (1<<TWEN);	return I2C_WaitForTWInt();}unsigned int I2C_ReceiveOneCommandByte(unsigned char *command, unsigned char ack){	TWCR = (1<<TWINT) | (1<<TWEN) | (ack?_BV(TWEA):0);	unsigned int error = I2C_WaitForTWInt();	*command = TWDR;	return error;}unsigned int I2C_WaitForTWInt(void){	unsigned char count = 10;	while (count && !(TWCR & (1<<TWINT))){		count--;		_delay_us(1000000.0/I2C_FREQ*10); /* wait for 10 bit periods; the transaction never succeeds quicker */	}	if(count == 0) return ERROR_I2C_TIMEOUT;	return ERROR_NO;}
 |