8000 Double I2C read in one transaction skips a clock pulse (#5528) · esp8266/Arduino@1c63358 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1c63358

Browse files
committed
Double I2C read in one transaction skips a clock pulse (#5528)
See #5528 and the more elaborate [description](https://github.com/maarten-pennings/I2C-tool/blob/master/I2Ctest8266/README.md#how-to-fix) where @maarten-pennings did all the hard work, but as far as I could see, no PR was made.
1 parent 1c14e9e commit 1c63358

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

cores/esp8266/core_esp8266_si2c.cpp

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ class Twi
113113
return (GPI & (1 << twi_scl)) != 0;
114114
}
115115

116+
// ICACHE_RAM_ATTR used to have a constant delay.
117+
void ICACHE_RAM_ATTR twi_wait_clockStretchLimit(void);
118+
119+
// Generate a clock "valley" (at the end of a segment, just before a repeated start)
120+
void twi_scl_valley(void);
121+
116122
public:
117123
void setClock(unsigned int freq);
118124
void setClockStretchLimit(uint32_t limit);
@@ -268,12 +274,11 @@ bool Twi::write_start(void)
268274

269275
bool Twi::write_stop(void)
270276
{
271-
uint32_t i = 0;
272277
SCL_LOW();
273278
SDA_LOW();
274279
delay(twi_dcount);
275280
SCL_HIGH();
276-
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit); // Clock stretching
281+
twi_wait_clockStretchLimit();
277282
delay(twi_dcount);
278283
SDA_HIGH();
279284
delay(twi_dcount);
@@ -282,7 +287,6 @@ bool Twi::write_stop(void)
282287

283288
bool Twi::write_bit(bool bit)
284289
{
285-
uint32_t i = 0;
286290
SCL_LOW();
287291
if (bit)
288292
{
@@ -294,19 +298,18 @@ bool Twi::write_bit(bool bit)
294298
}
295299
delay(twi_dcount + 1);
296300
SCL_HIGH();
297-
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
301+
twi_wait_clockStretchLimit();
298302
delay(twi_dcount);
299303
return true;
300304
}
301305

302306
bool Twi::read_bit(void)
303307
{
304-
uint32_t i = 0;
305308
SCL_LOW();
306309
SDA_HIGH();
307310
delay(twi_dcount + 2);
308311
SCL_HIGH();
309-
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
312+
twi_wait_clockStretchLimit();
310313
bool bit = SDA_READ();
311314
delay(twi_dcount);
312315
return bit;
@@ -364,14 +367,18 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
364367
if (sendStop)
365368
{
366369
write_stop();
370+
}
371+
else
372+
{
373+
twi_scl_valley();
374+
twi_wait_clockStretchLimit();
375+
// TD-er: Also twi_delay here?
376+
// delay(twi_dcount);
367377
}
368378
i = 0;
369379
while (SDA_READ() == 0 && (i++) < 10)
370380
{
371-
SCL_LOW();
372-
delay(twi_dcount);
373-
SCL_HIGH();
374-
unsigned int t = 0; while (SCL_READ() == 0 && (t++) < twi_clockStretchLimit); // twi_clockStretchLimit
381+
twi_scl_valley();
375382
delay(twi_dcount);
376383
}
377384
return 0;
@@ -401,13 +408,17 @@ unsigned char Twi::readFrom(unsigned char address, unsigned char* buf, unsigned
401408
{
402409
write_stop();
403410
}
411+
else
412+
{
413+
twi_scl_valley();
414+
twi_wait_clockStretchLimit();
415+
// TD-er: Also twi_delay here?
416+
// delay(twi_dcount);
417+
}
404418
i = 0;
405419
while (SDA_READ() == 0 && (i++) < 10)
406420
{
407-
SCL_LOW();
408-
delay(twi_dcount);
409-
SCL_HIGH();
410-
unsigned int t = 0; while (SCL_READ() == 0 && (t++) < twi_clockStretchLimit); // twi_clockStretchLimit
421+
twi_scl_valley();
411422
delay(twi_dcount);
412423
}
413424
return 0;
@@ -628,6 +639,19 @@ void ICACHE_RAM_ATTR Twi::onTwipEvent(uint8_t status)
628639
}
629640
}
630641

642+
void ICACHE_RAM_ATTR Twi::twi_wait_clockStretchLimit(void)
643+
{
644+
uint32_t t=0;
645+
while(SCL_READ() == 0 && (t++) < twi_clockStretchLimit); // Clock stretching
646+
}
647+
648+
void Twi::twi_scl_valley(void)
649+
{
650+
SCL_LOW();
651+
delay(twi_dcount);
652+
SCL_HIGH();
653+
}
654+
631655
void ICACHE_RAM_ATTR Twi::onTimer(void *unused)
632656
{
633657
(void)unused;

0 commit comments

Comments
 (0)
0