Skip to content

Commit 42a8a4f

Browse files
DanNixonthirtythreeforty
authored andcommitted
Cherry-pick: Added TWI max iteration timeout to while loops
Cherry picked and squashed by @thirtythreeforty from arduino#1842.
1 parent 90bd172 commit 42a8a4f

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

Diff for: libraries/Wire/utility/twi.c

+29-5
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ static volatile uint8_t twi_rxBufferIndex;
5959

6060
static volatile uint8_t twi_error;
6161

62+
volatile uint32_t twi_iter_count;
63+
6264
/*
6365
* Function twi_init
6466
* Desc readys twi pins and sets twi bitrate
@@ -122,7 +124,8 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
122124
}
123125

124126
// wait until twi is ready, become master receiver
125-
while(TWI_READY != twi_state){
127+
twi_timeout_guard(1);
128+
while((TWI_READY != twi_state) && !twi_timeout_guard(0)){
126129
continue;
127130
}
128131
twi_state = TWI_MRX;
@@ -159,7 +162,8 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
159162
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
160163

161164
// wait for read operation to complete
162-
while(TWI_MRX == twi_state){
165+
twi_timeout_guard(1);
166+
while((TWI_MRX == twi_state) && !twi_timeout_guard(0)){
163167
continue;
164168
}
165169

@@ -199,7 +203,8 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
199203
}
200204

201205
// wait until twi is ready, become master transmitter
202-
while(TWI_READY != twi_state){
206+
twi_timeout_guard(1);
207+
while((TWI_READY != twi_state) && !twi_timeout_guard(0)){
203208
continue;
204209
}
205210
twi_state = TWI_MTX;
@@ -239,7 +244,8 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
239244
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
240245

241246
// wait for write operation to complete
242-
while(wait && (TWI_MTX == twi_state)){
247+
twi_timeout_guard(1);
248+
while((wait && (TWI_MTX == twi_state)) && !twi_timeout_guard(0)){
243249
continue;
244250
}
245251

@@ -337,7 +343,8 @@ void twi_stop(void)
337343

338344
// wait for stop condition to be exectued on bus
339345
// TWINT is not set after a stop condition!
340-
while(TWCR & _BV(TWSTO)){
346+
twi_timeout_guard(1);
347+
while((TWCR & _BV(TWSTO)) && !twi_timeout_guard(0)){
341348
continue;
342349
}
343350

@@ -525,3 +532,20 @@ ISR(TWI_vect)
525532
}
526533
}
527534

535+
uint8_t twi_timeout_guard(uint8_t init)
536+
{
537+
if(init)
538+
twi_iter_count = 0;
539+
else
540+
{
541+
twi_iter_count++;
542+
if(twi_iter_count > TWI_MAX_ITERS)
543+
{
544+
twi_init();
545+
TWCR = 0;
546+
return 1;
547+
}
548+
}
549+
return 0;
550+
}
551+

Diff for: libraries/Wire/utility/twi.h

100755100644
+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#define TWI_MTX 2
3838
#define TWI_SRX 3
3939
#define TWI_STX 4
40+
41+
#define TWI_MAX_ITERS 100000UL
4042

4143
void twi_init(void);
4244
void twi_setAddress(uint8_t);
@@ -48,6 +50,7 @@
4850
void twi_reply(uint8_t);
4951
void twi_stop(void);
5052
void twi_releaseBus(void);
53+
uint8_t twi_timeout_guard(uint8_t);
5154

5255
#endif
5356

0 commit comments

Comments
 (0)