Skip to content

Commit 07eb568

Browse files
Update twi.c
1 parent b1d3bae commit 07eb568

File tree

1 file changed

+61
-8
lines changed
  • libraries/Wire/src/utility

1 file changed

+61
-8
lines changed

libraries/Wire/src/utility/twi.c

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1818
1919
Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
20+
21+
Modified in February, 2019 by MathWorks Inc. to include timeout for I2C read and write operations
2022
*/
2123

2224
#include <math.h>
@@ -59,6 +61,8 @@ static volatile uint8_t twi_rxBufferIndex;
5961

6062
static volatile uint8_t twi_error;
6163

64+
static volatile uint32_t twi_timer_count; // Holds a number as timeout counter and it is increased gradually to trigger timeout
65+
6266
/*
6367
* Function twi_init
6468
* Desc readys twi pins and sets twi bitrate
@@ -72,9 +76,9 @@ void twi_init(void)
7276
twi_sendStop = true; // default value
7377
twi_inRepStart = false;
7478

75-
// activate internal pullups for twi.
76-
digitalWrite(SDA, 1);
77-
digitalWrite(SCL, 1);
79+
// Deactivate internal pullups for twi.
80+
digitalWrite(SDA, 0);
81+
digitalWrite(SCL, 0);
7882

7983
// initialize twi prescaler and bit rate
8084
cbi(TWSR, TWPS0);
@@ -154,7 +158,9 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
154158
}
155159

156160
// wait until twi is ready, become master receiver
161+
twi_timeout(1);//Initialize TimeOut counter
157162
while(TWI_READY != twi_state){
163+
if (twi_timeout(0)) break;
158164
continue;
159165
}
160166
twi_state = TWI_MRX;
@@ -189,11 +195,13 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
189195
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
190196
}
191197
else
192-
// send start condition
193-
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
198+
// send start condition
199+
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
194200

195201
// wait for read operation to complete
202+
twi_timeout(1);
196203
while(TWI_MRX == twi_state){
204+
if (twi_timeout(0)) break;
197205
continue;
198206
}
199207

@@ -222,6 +230,8 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
222230
* 2 .. address send, NACK received
223231
* 3 .. data send, NACK received
224232
* 4 .. other twi error (lost bus arbitration, bus error, ..)
233+
* 32 .. timed out while trying to become Bus Master
234+
* 64 .. timed out while waiting for data to be sent
225235
*/
226236
uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
227237
{
@@ -233,7 +243,12 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
233243
}
234244

235245
// wait until twi is ready, become master transmitter
246+
twi_timeout(1);
236247
while(TWI_READY != twi_state){
248+
if (twi_timeout(0))
249+
{
250+
return 32;
251+
}
237252
continue;
238253
}
239254
twi_state = TWI_MTX;
@@ -271,11 +286,16 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
271286
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
272287
}
273288
else
274-
// send start condition
289+
// send start condition
275290
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
276291

277292
// wait for write operation to complete
293+
twi_timeout(1);
278294
while(wait && (TWI_MTX == twi_state)){
295+
if (twi_timeout(0))
296+
{
297+
return 64;
298+
}
279299
continue;
280300
}
281301

@@ -373,7 +393,9 @@ void twi_stop(void)
373393

374394
// wait for stop condition to be exectued on bus
375395
// TWINT is not set after a stop condition!
396+
twi_timeout(1);
376397
while(TWCR & _BV(TWSTO)){
398+
if (twi_timeout(0)) return;
377399
continue;
378400
}
379401

@@ -396,7 +418,39 @@ void twi_releaseBus(void)
396418
twi_state = TWI_READY;
397419
}
398420

399-
ISR(TWI_vect)
421+
/*
422+
* Function twi_timeout
423+
* Desc Increases the counter in a loop
424+
* and if it reaches a maximum value,
425+
the hardware is initialized and
426+
the function returns true
427+
* Input isInitializationRequired: If 1 the
428+
timer resets the counter
429+
* Output 1 Timeout occurred
430+
* 0 No timeout occurred
431+
*/
432+
433+
uint8_t twi_timeout(uint8_t isInitializationRequired)
434+
{
435+
if (isInitializationRequired)
436+
{
437+
// reset the timeout counter
438+
twi_timer_count=0;
439+
}
440+
else
441+
{
442+
twi_timer_count++;
443+
}
444+
if (twi_timer_count>=10000UL) {
445+
twi_timer_count=0;
446+
// reinitialize the hardware
447+
twi_init();
448+
return 1;
449+
}
450+
return 0;
451+
}
452+
453+
SIGNAL(TWI_vect)
400454
{
401455
switch(TW_STATUS){
402456
// All Master
@@ -558,4 +612,3 @@ ISR(TWI_vect)
558612
break;
559613
}
560614
}
561-

0 commit comments

Comments
 (0)