Skip to content

Configurable I2C clock stretching limit #1563

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from Feb 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions cores/esp8266/core_esp8266_si2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

unsigned char twi_dcount = 18;
static unsigned char twi_sda, twi_scl;
static uint32_t twi_clockStretchLimit;

#define SDA_LOW() (GPES = (1 << twi_sda)) //Enable SDA (becomes output and since GPO is 0 for the pin, it will pull the line low)
#define SDA_HIGH() (GPEC = (1 << twi_sda)) //Disable SDA (becomes input and since it has pullup it will go high)
Expand All @@ -37,9 +38,9 @@ static unsigned char twi_sda, twi_scl;
#endif

#if F_CPU == FCPU80
#define TWI_CLOCK_STRETCH 800
#define TWI_CLOCK_STRETCH_MULTIPLIER 3
#else
#define TWI_CLOCK_STRETCH 1600
#define TWI_CLOCK_STRETCH_MULTIPLIER 6
#endif

void twi_setClock(unsigned int freq){
Expand All @@ -60,14 +61,20 @@ void twi_setClock(unsigned int freq){
#endif
}

void twi_setClockStretchLimit(uint32_t limit){
twi_clockStretchLimit = limit * TWI_CLOCK_STRETCH_MULTIPLIER;
}

void twi_init(unsigned char sda, unsigned char scl){
twi_sda = sda;
twi_scl = scl;
pinMode(twi_sda, INPUT_PULLUP);
pinMode(twi_scl, INPUT_PULLUP);
twi_setClock(100000);
twi_setClockStretchLimit(230); // default value is 230 uS
}


void twi_stop(void){
pinMode(twi_sda, INPUT);
pinMode(twi_scl, INPUT);
Expand All @@ -93,12 +100,12 @@ static bool twi_write_start(void) {
}

static bool twi_write_stop(void){
unsigned int i = 0;
uint32_t i = 0;
SCL_LOW();
SDA_LOW();
twi_delay(twi_dcount);
SCL_HIGH();
while (SCL_READ() == 0 && (i++) < TWI_CLOCK_STRETCH);// Clock stretching (up to 100us)
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit); // Clock stretching
twi_delay(twi_dcount);
SDA_HIGH();
twi_delay(twi_dcount);
Expand All @@ -107,24 +114,24 @@ static bool twi_write_stop(void){
}

static bool twi_write_bit(bool bit) {
unsigned int i = 0;
uint32_t i = 0;
SCL_LOW();
if (bit) SDA_HIGH();
else SDA_LOW();
twi_delay(twi_dcount+1);
SCL_HIGH();
while (SCL_READ() == 0 && (i++) < TWI_CLOCK_STRETCH);// Clock stretching (up to 100us)
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
twi_delay(twi_dcount);
return true;
}

static bool twi_read_bit(void) {
unsigned int i = 0;
uint32_t i = 0;
SCL_LOW();
SDA_HIGH();
twi_delay(twi_dcount+2);
SCL_HIGH();
while (SCL_READ() == 0 && (i++) < TWI_CLOCK_STRETCH);// Clock stretching (up to 100us)
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
bool bit = SDA_READ();
twi_delay(twi_dcount);
return bit;
Expand Down
1 change: 1 addition & 0 deletions cores/esp8266/twi.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern "C" {
void twi_init(unsigned char sda, unsigned char scl);
void twi_stop(void);
void twi_setClock(unsigned int freq);
void twi_setClockStretchLimit(uint32_t limit);
uint8_t twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop);
uint8_t twi_readFrom(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop);

Expand Down
4 changes: 4 additions & 0 deletions libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ void TwoWire::setClock(uint32_t frequency){
twi_setClock(frequency);
}

void TwoWire::setClockStretchLimit(uint32_t limit){
twi_setClockStretchLimit(limit);
}

size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop){
if(size > BUFFER_LENGTH){
size = BUFFER_LENGTH;
Expand Down
1 change: 1 addition & 0 deletions libraries/Wire/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class TwoWire : public Stream
void begin(uint8_t);
void begin(int);
void setClock(uint32_t);
void setClockStretchLimit(uint32_t);
void beginTransmission(uint8_t);
void beginTransmission(int);
uint8_t endTransmission(void);
Expand Down
1 change: 1 addition & 0 deletions libraries/Wire/keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

begin KEYWORD2
setClock KEYWORD2
setClockStretchLimit KEYWORD2
beginTransmission KEYWORD2
endTransmission KEYWORD2
requestFrom KEYWORD2
Expand Down