mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
* Double I2C read in one transaction skips a clock pulse (#5528)
See https://github.com/esp8266/Arduino/issues/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.
I also noticed some code duplication, which I moved to separate functions.
According to [this documentation on I2C clock stretching](https://www.i2c-bus.org/clock-stretching/) it is not allowed to have some slave keep the clock low during transmission of a byte, only after an ack.
So that's why it is not done in the while loop.
But I wondered if there should be an extra delay between the sequence of pulses and the extra added clock "valley". See my comment in the code.
Fixes #5528
* [I2C] Restore clock stretch functionality during transfer
As requested here: 8357a8c644 (r339310509)
* [I2C] Move duplicated clock stretch call to twi_scl_valley function
This commit is contained in:
parent
5d0b9aa5ac
commit
36c369bb8f
@ -128,6 +128,8 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a clock "valley" (at the end of a segment, just before a repeated start)
|
||||||
|
void twi_scl_valley(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setClock(unsigned int freq);
|
void setClock(unsigned int freq);
|
||||||
@ -386,13 +388,16 @@ unsigned char Twi::writeTo(unsigned char address, unsigned char * buf, unsigned
|
|||||||
{
|
{
|
||||||
write_stop();
|
write_stop();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
twi_scl_valley();
|
||||||
|
// TD-er: Also busywait(twi_dcount) here?
|
||||||
|
// busywait(twi_dcount);
|
||||||
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
while (!SDA_READ() && (i++) < 10)
|
while (!SDA_READ() && (i++) < 10)
|
||||||
{
|
{
|
||||||
SCL_LOW();
|
twi_scl_valley();
|
||||||
busywait(twi_dcount);
|
|
||||||
SCL_HIGH();
|
|
||||||
WAIT_CLOCK_STRETCH();
|
|
||||||
busywait(twi_dcount);
|
busywait(twi_dcount);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -422,13 +427,16 @@ unsigned char Twi::readFrom(unsigned char address, unsigned char* buf, unsigned
|
|||||||
{
|
{
|
||||||
write_stop();
|
write_stop();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
twi_scl_valley();
|
||||||
|
// TD-er: Also busywait(twi_dcount) here?
|
||||||
|
// busywait(twi_dcount);
|
||||||
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
while (!SDA_READ() && (i++) < 10)
|
while (!SDA_READ() && (i++) < 10)
|
||||||
{
|
{
|
||||||
SCL_LOW();
|
twi_scl_valley();
|
||||||
busywait(twi_dcount);
|
|
||||||
SCL_HIGH();
|
|
||||||
WAIT_CLOCK_STRETCH();
|
|
||||||
busywait(twi_dcount);
|
busywait(twi_dcount);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -649,6 +657,14 @@ void ICACHE_RAM_ATTR Twi::onTwipEvent(uint8_t status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Twi::twi_scl_valley(void)
|
||||||
|
{
|
||||||
|
SCL_LOW();
|
||||||
|
busywait(twi_dcount);
|
||||||
|
SCL_HIGH();
|
||||||
|
WAIT_CLOCK_STRETCH();
|
||||||
|
}
|
||||||
|
|
||||||
void ICACHE_RAM_ATTR Twi::onTimer(void *unused)
|
void ICACHE_RAM_ATTR Twi::onTimer(void *unused)
|
||||||
{
|
{
|
||||||
(void)unused;
|
(void)unused;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user