@@ -42,6 +42,10 @@ class Twi
42
42
unsigned char twi_addr = 0 ;
43
43
uint32_t twi_clockStretchLimit = 0 ;
44
44
45
+ // These are int-wide, even though they could all fit in a byte, to reduce code size and avoid any potential
46
+ // issues about RmW on packed bytes. The int-wide variations of asm instructions are smaller than the equivalent
47
+ // byte-wide ones, and since these emums are used everywhere, the difference adds up fast. There is only a single
48
+ // instance of the class, though, so the extra 12 bytes of RAM used here saves a lot more IRAM.
45
49
volatile enum { TWIPM_UNKNOWN = 0 , TWIPM_IDLE, TWIPM_ADDRESSED, TWIPM_WAIT} twip_mode = TWIPM_IDLE;
46
50
volatile enum { TWIP_UNKNOWN = 0 , TWIP_IDLE, TWIP_START, TWIP_SEND_ACK, TWIP_WAIT_ACK, TWIP_WAIT_STOP, TWIP_SLA_W, TWIP_SLA_R, TWIP_REP_START, TWIP_READ, TWIP_STOP, TWIP_REC_ACK, TWIP_READ_ACK, TWIP_RWAIT_ACK, TWIP_WRITE, TWIP_BUS_ERR } twip_state = TWIP_IDLE;
47
51
volatile int twip_status = TW_NO_INFO;
@@ -78,7 +82,7 @@ class Twi
78
82
static void ICACHE_RAM_ATTR onTimer (void *unused);
79
83
80
84
// Internal use functions
81
- void ICACHE_RAM_ATTR delay (unsigned char v);
85
+ void ICACHE_RAM_ATTR busywait (unsigned char v);
82
86
bool write_start (void );
83
87
bool write_stop (void );
84
88
bool write_bit (bool bit);
@@ -238,7 +242,7 @@ void Twi::setAddress(uint8_t address)
238
242
twi_addr = address << 1 ;
239
243
}
240
244
241
- void ICACHE_RAM_ATTR Twi::delay (unsigned char v)
245
+ void ICACHE_RAM_ATTR Twi::busywait (unsigned char v)
242
246
{
243
247
unsigned int i;
244
248
#pragma GCC diagnostic push
@@ -256,13 +260,13 @@ bool Twi::write_start(void)
256
260
{
257
261
SCL_HIGH ();
258
262
SDA_HIGH ();
259
- if (SDA_READ () == 0 )
263
+ if (! SDA_READ ())
260
264
{
261
265
return false ;
262
266
}
263
- delay (twi_dcount);
267
+ busywait (twi_dcount);
264
268
SDA_LOW ();
265
- delay (twi_dcount);
269
+ busywait (twi_dcount);
266
270
return true ;
267
271
}
268
272
@@ -271,12 +275,12 @@ bool Twi::write_stop(void)
271
275
uint32_t i = 0 ;
272
276
SCL_LOW ();
273
277
SDA_LOW ();
274
- delay (twi_dcount);
278
+ busywait (twi_dcount);
275
279
SCL_HIGH ();
276
- while (SCL_READ () == 0 && (i++) < twi_clockStretchLimit); // Clock stretching
277
- delay (twi_dcount);
280
+ while (! SCL_READ () && (i++) < twi_clockStretchLimit); // Clock stretching
281
+ busywait (twi_dcount);
278
282
SDA_HIGH ();
279
- delay (twi_dcount);
283
+ busywait (twi_dcount);
280
284
return true ;
281
285
}
282
286
@@ -292,10 +296,10 @@ bool Twi::write_bit(bool bit)
292
296
{
293
297
SDA_LOW ();
294
298
}
295
- delay (twi_dcount + 1 );
299
+ busywait (twi_dcount + 1 );
296
300
SCL_HIGH ();
297
- while (SCL_READ () == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
298
- delay (twi_dcount);
301
+ while (! SCL_READ () && (i++) < twi_clockStretchLimit);// Clock stretching
302
+ busywait (twi_dcount);
299
303
return true ;
300
304
}
301
305
@@ -304,11 +308,11 @@ bool Twi::read_bit(void)
304
308
uint32_t i = 0 ;
305
309
SCL_LOW ();
306
310
SDA_HIGH ();
307
- delay (twi_dcount + 2 );
311
+ busywait (twi_dcount + 2 );
308
312
SCL_HIGH ();
309
- while (SCL_READ () == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
313
+ while (! SCL_READ () && (i++) < twi_clockStretchLimit);// Clock stretching
310
314
bool bit = SDA_READ ();
311
- delay (twi_dcount);
315
+ busywait (twi_dcount);
312
316
return bit;
313
317
}
314
318
@@ -366,13 +370,13 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
366
370
write_stop ();
367
371
}
368
372
i = 0 ;
369
- while (SDA_READ () == 0 && (i++) < 10 )
373
+ while (! SDA_READ () && (i++) < 10 )
370
374
{
371
375
SCL_LOW ();
372
- delay (twi_dcount);
376
+ busywait (twi_dcount);
373
377
SCL_HIGH ();
374
- unsigned int t = 0 ; while (SCL_READ () == 0 && (t++) < twi_clockStretchLimit); // twi_clockStretchLimit
375
- delay (twi_dcount);
378
+ unsigned int t = 0 ; while (! SCL_READ () && (t++) < twi_clockStretchLimit); // twi_clockStretchLimit
379
+ busywait (twi_dcount);
376
380
}
377
381
return 0 ;
378
382
}
@@ -402,34 +406,34 @@ unsigned char Twi::readFrom(unsigned char address, unsigned char* buf, unsigned
402
406
write_stop ();
403
407
}
404
408
i = 0 ;
405
- while (SDA_READ () == 0 && (i++) < 10 )
409
+ while (! SDA_READ () && (i++) < 10 )
406
410
{
407
411
SCL_LOW ();
408
- delay (twi_dcount);
412
+ busywait (twi_dcount);
409
413
SCL_HIGH ();
410
- unsigned int t = 0 ; while (SCL_READ () == 0 && (t++) < twi_clockStretchLimit); // twi_clockStretchLimit
411
- delay (twi_dcount);
414
+ unsigned int t = 0 ; while (! SCL_READ () && (t++) < twi_clockStretchLimit); // twi_clockStretchLimit
415
+ busywait (twi_dcount);
412
416
}
413
417
return 0 ;
414
418
}
415
419
416
420
uint8_t Twi::status ()
417
421
{
418
- if (SCL_READ () == 0 )
422
+ if (! SCL_READ ())
419
423
{
420
424
return I2C_SCL_HELD_LOW; // SCL held low by another device, no procedure available to recover
421
425
}
422
426
423
427
int clockCount = 20 ;
424
- while (SDA_READ () == 0 && clockCount-- > 0 ) // if SDA low, read the bits slaves have to sent to a max
428
+ while (! SDA_READ () && clockCount-- > 0 ) // if SDA low, read the bits slaves have to sent to a max
425
429
{
426
430
read_bit ();
427
- if (SCL_READ () == 0 )
431
+ if (! SCL_READ ())
428
432
{
429
433
return I2C_SCL_HELD_LOW_AFTER_READ; // I2C bus error. SCL held low beyond slave clock stretch time
430
434
}
431
435
}
432
- if (SDA_READ () == 0 )
436
+ if (! SDA_READ ())
433
437
{
434
438
return I2C_SDA_HELD_LOW; // I2C bus error. SDA line held low by slave/another_master after n bits.
435
439
}
@@ -501,7 +505,7 @@ inline void ICACHE_RAM_ATTR Twi::stop(void)
501
505
// TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
502
506
SCL_HIGH (); // _BV(TWINT)
503
507
twi_ack = 1 ; // _BV(TWEA)
504
- delay (5 ); // Maybe this should be here
508
+ busywait (5 ); // Maybe this should be here
505
509
SDA_HIGH (); // _BV(TWSTO)
506
510
// update twi state
507
511
twi_state = TWI_READY;
0 commit comments