-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathI2CBase.cpp
66 lines (55 loc) · 1.49 KB
/
I2CBase.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "I2cbase.h"
#include <avr/io.h>
uint8_t I2C_Error;
void I2C_Init() {
TWCR = _BV(TWEA) | _BV(TWEN);
I2C_SetBusSpeed(I2CBUSCLOCK / 100);
}
void I2C_Start() {
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
I2C_WaitForComplete();
if ((TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) I2C_SetError(I2C_STARTError);
}
void I2C_SendAddr(uint8_t address) {
uint8_t Status;
if ((address & 0x01) == 0) Status = TW_MT_SLA_ACK;
else Status = TW_MR_SLA_ACK;
TWDR = address;
TWCR = _BV(TWINT) | _BV(TWEN);
I2C_WaitForComplete();
if (TW_STATUS != Status) I2C_SetError(I2C_NoACK);
else I2C_SetError(I2C_OK);
}
void I2C_SendByte(uint8_t byte) {
TWDR = byte;
TWCR = _BV(TWINT) | _BV(TWEN);
I2C_WaitForComplete();
if (TW_STATUS != TW_MT_DATA_ACK) I2C_SetError(I2C_NoACK);
}
uint8_t I2C_ReceiveData_ACK() {
TWCR = _BV(TWEA) | _BV(TWINT) | _BV(TWEN);
I2C_WaitForComplete();
if (TW_STATUS != TW_MR_DATA_ACK) I2C_SetError(I2C_NoACK);
return TWDR;
}
uint8_t I2C_ReceiveData_NACK() {
TWCR = _BV(TWINT) | _BV(TWEN);
I2C_WaitForComplete();
if (TW_STATUS != TW_MR_DATA_NACK) I2C_SetError(I2C_NoNACK);
return TWDR;
}
void I2C_SetBusSpeed(uint16_t speed) {
speed = (F_CPU / speed / 100 - 16) / 2;
uint8_t prescaler = 0;
while (speed > 255)
{
prescaler++;
speed = speed / 4;
};
TWSR = (TWSR & (_BV(TWPS1) | _BV(TWPS0))) | prescaler;
TWBR = speed;
}
void I2C_SendStartAndSelect(uint8_t addr) {
I2C_Start();
I2C_SendAddr(addr);
}