aboutsummaryrefslogtreecommitdiff
path: root/drivers/avr/i2c_master.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/avr/i2c_master.c')
-rwxr-xr-xdrivers/avr/i2c_master.c102
1 files changed, 36 insertions, 66 deletions
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c
index 97f690043..caca2179e 100755
--- a/drivers/avr/i2c_master.c
+++ b/drivers/avr/i2c_master.c
@@ -19,24 +19,19 @@ void i2c_init(void)
19 //TWBR = 10; 19 //TWBR = 10;
20} 20}
21 21
22uint8_t i2c_start(uint8_t address) 22i2c_status_t i2c_start(uint8_t address, uint8_t timeout)
23{ 23{
24 // reset TWI control register 24 // reset TWI control register
25 TWCR = 0; 25 TWCR = 0;
26 // transmit START condition 26 // transmit START condition
27 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); 27 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
28 28
29 #ifdef I2C_TIMEOUT 29 uint16_t timeout_timer = timer_read();
30 uint16_t timeout_timer = timer_read(); 30 while( !(TWCR & (1<<TWINT)) ) {
31 while( !(TWCR & (1<<TWINT)) ) { 31 if (timeout && (timer_read() - timeout_timer) > timeout) {
32 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { 32 return I2C_STATUS_TIMEOUT;
33 return 2; // should make these codes standard
34 }
35 } 33 }
36 #else 34 }
37 // wait for end of transmission
38 while( !(TWCR & (1<<TWINT)) );
39 #endif
40 35
41 // check if the start condition was successfully transmitted 36 // check if the start condition was successfully transmitted
42 if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return 1; } 37 if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return 1; }
@@ -46,17 +41,12 @@ uint8_t i2c_start(uint8_t address)
46 // start transmission of address 41 // start transmission of address
47 TWCR = (1<<TWINT) | (1<<TWEN); 42 TWCR = (1<<TWINT) | (1<<TWEN);
48 43
49 #ifdef I2C_TIMEOUT 44 timeout_timer = timer_read();
50 timeout_timer = timer_read(); 45 while( !(TWCR & (1<<TWINT)) ) {
51 while( !(TWCR & (1<<TWINT)) ) { 46 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
52 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { 47 return I2C_STATUS_TIMEOUT;
53 return 2; // should make these codes standard
54 }
55 } 48 }
56 #else 49 }
57 // wait for end of transmission
58 while( !(TWCR & (1<<TWINT)) );
59 #endif
60 50
61 // check if the device has acknowledged the READ / WRITE mode 51 // check if the device has acknowledged the READ / WRITE mode
62 uint8_t twst = TW_STATUS & 0xF8; 52 uint8_t twst = TW_STATUS & 0xF8;
@@ -65,75 +55,60 @@ uint8_t i2c_start(uint8_t address)
65 return 0; 55 return 0;
66} 56}
67 57
68uint8_t i2c_write(uint8_t data) 58i2c_status_t i2c_write(uint8_t data, uint8_t timeout)
69{ 59{
70 // load data into data register 60 // load data into data register
71 TWDR = data; 61 TWDR = data;
72 // start transmission of data 62 // start transmission of data
73 TWCR = (1<<TWINT) | (1<<TWEN); 63 TWCR = (1<<TWINT) | (1<<TWEN);
74 64
75 #ifdef I2C_TIMEOUT 65 uint16_t timeout_timer = timer_read();
76 uint16_t timeout_timer = timer_read(); 66 while( !(TWCR & (1<<TWINT)) ) {
77 while( !(TWCR & (1<<TWINT)) ) { 67 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
78 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { 68 return I2C_STATUS_TIMEOUT;
79 return 2; // should make these codes standard
80 }
81 } 69 }
82 #else 70 }
83 // wait for end of transmission
84 while( !(TWCR & (1<<TWINT)) );
85 #endif
86 71
87 if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; } 72 if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
88 73
89 return 0; 74 return 0;
90} 75}
91 76
92uint8_t i2c_read_ack(void) 77i2c_status_t i2c_read_ack(uint8_t timeout)
93{ 78{
94 79
95 // start TWI module and acknowledge data after reception 80 // start TWI module and acknowledge data after reception
96 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); 81 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
97 82
98 #ifdef I2C_TIMEOUT 83 uint16_t timeout_timer = timer_read();
99 uint16_t timeout_timer = timer_read(); 84 while( !(TWCR & (1<<TWINT)) ) {
100 while( !(TWCR & (1<<TWINT)) ) { 85 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
101 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { 86 return I2C_STATUS_TIMEOUT;
102 return 2; // should make these codes standard
103 }
104 } 87 }
105 #else 88 }
106 // wait for end of transmission
107 while( !(TWCR & (1<<TWINT)) );
108 #endif
109 89
110 // return received data from TWDR 90 // return received data from TWDR
111 return TWDR; 91 return TWDR;
112} 92}
113 93
114uint8_t i2c_read_nack(void) 94i2c_status_t i2c_read_nack(uint8_t timeout)
115{ 95{
116 96
117 // start receiving without acknowledging reception 97 // start receiving without acknowledging reception
118 TWCR = (1<<TWINT) | (1<<TWEN); 98 TWCR = (1<<TWINT) | (1<<TWEN);
119 99
120 #ifdef I2C_TIMEOUT 100 uint16_t timeout_timer = timer_read();
121 uint16_t timeout_timer = timer_read(); 101 while( !(TWCR & (1<<TWINT)) ) {
122 while( !(TWCR & (1<<TWINT)) ) { 102 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
123 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { 103 return I2C_STATUS_TIMEOUT;
124 return 2; // should make these codes standard
125 }
126 } 104 }
127 #else 105 }
128 // wait for end of transmission
129 while( !(TWCR & (1<<TWINT)) );
130 #endif
131 106
132 // return received data from TWDR 107 // return received data from TWDR
133 return TWDR; 108 return TWDR;
134} 109}
135 110
136uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length) 111i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
137{ 112{
138 if (i2c_start(address | I2C_WRITE)) return 1; 113 if (i2c_start(address | I2C_WRITE)) return 1;
139 114
@@ -197,22 +172,17 @@ uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t le
197 return 0; 172 return 0;
198} 173}
199 174
200uint8_t i2c_stop(void) 175i2c_status_t i2c_stop(uint8_t timeout)
201{ 176{
202 // transmit STOP condition 177 // transmit STOP condition
203 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); 178 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
204 179
205 #ifdef I2C_TIMEOUT 180 uint16_t timeout_timer = timer_read();
206 uint16_t timeout_timer = timer_read(); 181 while(TWCR & (1<<TWSTO)) {
207 while(TWCR & (1<<TWSTO)) { 182 if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
208 if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { 183 return I2C_STATUS_TIMEOUT;
209 return 2; // should make these codes standard
210 }
211 } 184 }
212 #else 185 }
213 // wait for end of transmission
214 while(TWCR & (1<<TWSTO));
215 #endif
216 186
217 return 0; 187 return 0;
218} 188}