25
25
#include <avr/io.h>
26
26
#include <avr/interrupt.h>
27
27
#include <compat/twi.h>
28
- #include "Arduino.h" // for digitalWrite
28
+ #include "Arduino.h" // for digitalWrite and millis
29
29
30
30
#ifndef cbi
31
31
#define cbi (sfr , bit ) (_SFR_BYTE(sfr) &= ~_BV(bit))
@@ -42,6 +42,7 @@ static volatile uint8_t twi_state;
42
42
static volatile uint8_t twi_slarw ;
43
43
static volatile uint8_t twi_sendStop ; // should the transaction end with a stop
44
44
static volatile uint8_t twi_inRepStart ; // in the middle of a repeated start
45
+ static volatile uint8_t twi_timeout_ms = 0 ;
45
46
46
47
static void (* twi_onSlaveTransmit )(void );
47
48
static void (* twi_onSlaveReceive )(uint8_t * , int );
@@ -154,7 +155,15 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
154
155
}
155
156
156
157
// wait until twi is ready, become master receiver
158
+ uint32_t startMillis = millis ();
157
159
while (TWI_READY != twi_state ){
160
+ if ((twi_timeout_ms > 0 ) && (millis () - startMillis > twi_timeout_ms )) {
161
+ //timeout
162
+ twi_disable ();
163
+ twi_init ();
164
+
165
+ return 0 ;
166
+ }
158
167
continue ;
159
168
}
160
169
twi_state = TWI_MRX ;
@@ -193,7 +202,15 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
193
202
TWCR = _BV (TWEN ) | _BV (TWIE ) | _BV (TWEA ) | _BV (TWINT ) | _BV (TWSTA );
194
203
195
204
// wait for read operation to complete
205
+ startMillis = millis ();
196
206
while (TWI_MRX == twi_state ){
207
+ if ((twi_timeout_ms > 0 ) && (millis () - startMillis > twi_timeout_ms )) {
208
+ //timeout
209
+ twi_disable ();
210
+ twi_init ();
211
+
212
+ return 0 ;
213
+ }
197
214
continue ;
198
215
}
199
216
@@ -233,7 +250,15 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
233
250
}
234
251
235
252
// wait until twi is ready, become master transmitter
253
+ uint32_t startMillis = millis ();
236
254
while (TWI_READY != twi_state ){
255
+ if ((twi_timeout_ms > 0 ) && (millis () - startMillis > twi_timeout_ms )) {
256
+ //timeout
257
+ twi_disable ();
258
+ twi_init ();
259
+
260
+ return 4 ;
261
+ }
237
262
continue ;
238
263
}
239
264
twi_state = TWI_MTX ;
@@ -275,7 +300,15 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
275
300
TWCR = _BV (TWINT ) | _BV (TWEA ) | _BV (TWEN ) | _BV (TWIE ) | _BV (TWSTA ); // enable INTs
276
301
277
302
// wait for write operation to complete
303
+ startMillis = millis ();
278
304
while (wait && (TWI_MTX == twi_state )){
305
+ if ((twi_timeout_ms > 0 ) && (millis () - startMillis > twi_timeout_ms )) {
306
+ //timeout
307
+ twi_disable ();
308
+ twi_init ();
309
+
310
+ return 4 ;
311
+ }
279
312
continue ;
280
313
}
281
314
@@ -373,7 +406,17 @@ void twi_stop(void)
373
406
374
407
// wait for stop condition to be exectued on bus
375
408
// TWINT is not set after a stop condition!
409
+ uint32_t counter = 0 ;
376
410
while (TWCR & _BV (TWSTO )){
411
+ counter ++ ;
412
+ if ((twi_timeout_ms > 0 ) && (counter >= 25000 )) {
413
+ // timeout
414
+ twi_disable ();
415
+ twi_init ();
416
+
417
+ return ;
418
+ }
419
+
377
420
continue ;
378
421
}
379
422
@@ -396,6 +439,11 @@ void twi_releaseBus(void)
396
439
twi_state = TWI_READY ;
397
440
}
398
441
442
+ void twi_setTimeoutInMillis (uint8_t timeout )
443
+ {
444
+ twi_timeout_ms = timeout ;
445
+ }
446
+
399
447
ISR (TWI_vect )
400
448
{
401
449
switch (TW_STATUS ){
0 commit comments