Skip to content

Commit 0ec1fa5

Browse files
committed
Double I2C read in one transaction skips a clock pulse (esp8266#5528)
See esp8266#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 215459f commit 0ec1fa5

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

cores/esp8266/core_esp8266_si2c.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -197,38 +197,39 @@ static bool twi_write_start(void) {
197197
return true;
198198
}
199199

200+
static void ICACHE_RAM_ATTR twi_wait_clockStretchLimit() {
201+
uint32_t t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit
202+
}
203+
200204
static bool twi_write_stop(void){
201-
uint32_t i = 0;
202205
SCL_LOW();
203206
SDA_LOW();
204207
twi_delay(twi_dcount);
205208
SCL_HIGH();
206-
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit); // Clock stretching
209+
twi_wait_clockStretchLimit();
207210
twi_delay(twi_dcount);
208211
SDA_HIGH();
209212
twi_delay(twi_dcount);
210213
return true;
211214
}
212215

213216
static bool twi_write_bit(bool bit) {
214-
uint32_t i = 0;
215217
SCL_LOW();
216218
if (bit) SDA_HIGH();
217219
else SDA_LOW();
218220
twi_delay(twi_dcount+1);
219221
SCL_HIGH();
220-
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
222+
twi_wait_clockStretchLimit();
221223
twi_delay(twi_dcount);
222224
return true;
223225
}
224226

225227
static bool twi_read_bit(void) {
226-
uint32_t i = 0;
227228
SCL_LOW();
228229
SDA_HIGH();
229230
twi_delay(twi_dcount+2);
230231
SCL_HIGH();
231-
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
232+
twi_wait_clockStretchLimit();
232233
bool bit = SDA_READ();
233234
twi_delay(twi_dcount);
234235
return bit;
@@ -251,6 +252,13 @@ static unsigned char twi_read_byte(bool nack) {
251252
return byte;
252253
}
253254

255+
// Generate a clock "valey" (at the end of a segment, just before a repeated start)
256+
void twi_scl_valey( void ) {
257+
SCL_LOW();
258+
twi_delay(twi_dcount);
259+
SCL_HIGH();
260+
}
261+
254262
unsigned char twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop){
255263
unsigned int i;
256264
if(!twi_write_start()) return 4;//line busy
@@ -265,12 +273,15 @@ unsigned char twi_writeTo(unsigned char address, unsigned char * buf, unsigned i
265273
}
266274
}
267275
if(sendStop) twi_write_stop();
276+
else {
277+
twi_scl_valey();
278+
twi_wait_clockStretchLimit();
279+
// TD-er: Also twi_delay here?
280+
// twi_delay(twi_dcount);
281+
}
268282
i = 0;
269283
while(SDA_READ() == 0 && (i++) < 10){
270-
SCL_LOW();
271-
twi_delay(twi_dcount);
272-
SCL_HIGH();
273-
unsigned int t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit
284+
twi_scl_valey();
274285
twi_delay(twi_dcount);
275286
}
276287
return 0;
@@ -286,12 +297,15 @@ unsigned char twi_readFrom(unsigned char address, unsigned char* buf, unsigned i
286297
for(i=0; i<(len-1); i++) buf[i] = twi_read_byte(false);
287298
buf[len-1] = twi_read_byte(true);
288299
if(sendStop) twi_write_stop();
300+
else {
301+
twi_scl_valey();
302+
twi_wait_clockStretchLimit();
303+
// TD-er: Also twi_delay here?
304+
// twi_delay(twi_dcount);
305+
}
289306
i = 0;
290307
while(SDA_READ() == 0 && (i++) < 10){
291-
SCL_LOW();
292-
twi_delay(twi_dcount);
293-
SCL_HIGH();
294-
unsigned int t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit
308+
twi_scl_valey();
295309
twi_delay(twi_dcount);
296310
}
297311
return 0;

0 commit comments

Comments
 (0)