181 lines
4.2 KiB
C
181 lines
4.2 KiB
C
|
//
|
||
|
// i2c.c
|
||
|
// i2c
|
||
|
//
|
||
|
// Created by Michael Köhler on 09.10.17.
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#include "i2c.h"
|
||
|
|
||
|
#if defined (__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || \
|
||
|
defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PA__) || \
|
||
|
defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88__) || \
|
||
|
defined(__AVR_ATmega8__) || \
|
||
|
defined(__AVR_ATmega48P__) || \
|
||
|
defined(__AVR_ATmega1284P__) || \
|
||
|
defined (__AVR_ATmega324A__) || defined (__AVR_ATmega324P__) || defined (__AVR_ATmega324PA__) || \
|
||
|
defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__) || \
|
||
|
defined (__AVR_ATmega1284P__) || \
|
||
|
defined (__AVR_ATmega2560__)
|
||
|
#if PSC_I2C != 1 && PSC_I2C != 4 && PSC_I2C != 16 && PSC_I2C != 64
|
||
|
#error "Wrong prescaler for TWI !"
|
||
|
#elif SET_TWBR < 0 || SET_TWBR > 255
|
||
|
#error "TWBR out of range, change PSC_I2C or F_I2C !"
|
||
|
#endif
|
||
|
|
||
|
uint8_t I2C_ErrorCode;
|
||
|
/**********************************************
|
||
|
Public Function: i2c_init
|
||
|
|
||
|
Purpose: Initialise TWI/I2C interface
|
||
|
|
||
|
Input Parameter: none
|
||
|
|
||
|
Return Value: none
|
||
|
**********************************************/
|
||
|
void i2c_init(void){
|
||
|
// set clock
|
||
|
switch (PSC_I2C) {
|
||
|
case 4:
|
||
|
TWSR = 0x1;
|
||
|
break;
|
||
|
case 16:
|
||
|
TWSR = 0x2;
|
||
|
break;
|
||
|
case 64:
|
||
|
TWSR = 0x3;
|
||
|
break;
|
||
|
default:
|
||
|
TWSR = 0x00;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
TWBR = (uint8_t)SET_TWBR;
|
||
|
// enable
|
||
|
TWCR = (1 << TWEN);
|
||
|
}
|
||
|
/**********************************************
|
||
|
Public Function: i2c_start
|
||
|
|
||
|
Purpose: Start TWI/I2C interface
|
||
|
|
||
|
Input Parameter:
|
||
|
- uint8_t i2c_addr: Adress of reciever
|
||
|
|
||
|
Return Value: none
|
||
|
**********************************************/
|
||
|
void i2c_start(uint8_t i2c_addr){
|
||
|
// i2c start
|
||
|
TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN);
|
||
|
uint16_t timeout = F_CPU/F_I2C*2.0;
|
||
|
while((TWCR & (1 << TWINT)) == 0 &&
|
||
|
timeout !=0){
|
||
|
timeout--;
|
||
|
if(timeout == 0){
|
||
|
I2C_ErrorCode |= (1 << I2C_START);
|
||
|
return;
|
||
|
}
|
||
|
};
|
||
|
// send adress
|
||
|
TWDR = 0x78;
|
||
|
TWCR = (1 << TWINT)|( 1 << TWEN);
|
||
|
timeout = F_CPU/F_I2C*2.0;
|
||
|
while((TWCR & (1 << TWINT)) == 0 &&
|
||
|
timeout !=0){
|
||
|
timeout--;
|
||
|
if(timeout == 0){
|
||
|
I2C_ErrorCode |= (1 << I2C_SENDADRESS);
|
||
|
return;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
/**********************************************
|
||
|
Public Function: i2c_stop
|
||
|
|
||
|
Purpose: Stop TWI/I2C interface
|
||
|
|
||
|
Input Parameter: none
|
||
|
|
||
|
Return Value: none
|
||
|
**********************************************/
|
||
|
void i2c_stop(void){
|
||
|
// i2c stop
|
||
|
TWCR = (1 << TWINT)|(1 << TWSTO)|(1 << TWEN);
|
||
|
}
|
||
|
/**********************************************
|
||
|
Public Function: i2c_byte
|
||
|
|
||
|
Purpose: Send byte at TWI/I2C interface
|
||
|
|
||
|
Input Parameter:
|
||
|
- uint8_t byte: Byte to send to reciever
|
||
|
|
||
|
Return Value: none
|
||
|
**********************************************/
|
||
|
void i2c_byte(uint8_t byte){
|
||
|
TWDR = byte;
|
||
|
TWCR = (1 << TWINT)|( 1 << TWEN);
|
||
|
uint16_t timeout = F_CPU/F_I2C*2.0;
|
||
|
while((TWCR & (1 << TWINT)) == 0 &&
|
||
|
timeout !=0){
|
||
|
timeout--;
|
||
|
if(timeout == 0){
|
||
|
I2C_ErrorCode |= (1 << I2C_BYTE);
|
||
|
return;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
/**********************************************
|
||
|
Public Function: i2c_readAck
|
||
|
|
||
|
Purpose: read acknowledge from TWI/I2C Interface
|
||
|
|
||
|
Input Parameter: none
|
||
|
|
||
|
Return Value: uint8_t
|
||
|
- TWDR: recieved value at TWI/I2C-Interface, 0 at timeout
|
||
|
- 0: Error at read
|
||
|
**********************************************/
|
||
|
uint8_t i2c_readAck(void){
|
||
|
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
|
||
|
uint16_t timeout = F_CPU/F_I2C*2.0;
|
||
|
while((TWCR & (1 << TWINT)) == 0 &&
|
||
|
timeout !=0){
|
||
|
timeout--;
|
||
|
if(timeout == 0){
|
||
|
I2C_ErrorCode |= (1 << I2C_READACK);
|
||
|
return 0;
|
||
|
}
|
||
|
};
|
||
|
return TWDR;
|
||
|
}
|
||
|
|
||
|
/**********************************************
|
||
|
Public Function: i2c_readNAck
|
||
|
|
||
|
Purpose: read non-acknowledge from TWI/I2C Interface
|
||
|
|
||
|
Input Parameter: none
|
||
|
|
||
|
Return Value: uint8_t
|
||
|
- TWDR: recieved value at TWI/I2C-Interface
|
||
|
- 0: Error at read
|
||
|
**********************************************/
|
||
|
uint8_t i2c_readNAck(void){
|
||
|
TWCR = (1<<TWINT)|(1<<TWEN);
|
||
|
uint16_t timeout = F_CPU/F_I2C*2.0;
|
||
|
while((TWCR & (1 << TWINT)) == 0 &&
|
||
|
timeout !=0){
|
||
|
timeout--;
|
||
|
if(timeout == 0){
|
||
|
I2C_ErrorCode |= (1 << I2C_READNACK);
|
||
|
return 0;
|
||
|
}
|
||
|
};
|
||
|
return TWDR;
|
||
|
}
|
||
|
#else
|
||
|
#error "Micorcontroller not supported now!"
|
||
|
#endif
|