From 3f15903566e0f6c4bcded7c0ea20e111d7beee44 Mon Sep 17 00:00:00 2001 From: mvdbro Date: Wed, 3 Feb 2016 17:05:04 +0100 Subject: [PATCH] Configurable I2C clock stretching limit Use Wire.setClockStretchLimit(limit) limit is in uSeconds --- cores/esp8266/core_esp8266_si2c.c | 23 +++++++++++++++-------- cores/esp8266/twi.h | 1 + libraries/Wire/Wire.cpp | 4 ++++ libraries/Wire/Wire.h | 1 + libraries/Wire/keywords.txt | 1 + 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/cores/esp8266/core_esp8266_si2c.c b/cores/esp8266/core_esp8266_si2c.c index 4008c5c8f0..52fdd21dde 100644 --- a/cores/esp8266/core_esp8266_si2c.c +++ b/cores/esp8266/core_esp8266_si2c.c @@ -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) @@ -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){ @@ -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); @@ -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); @@ -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; diff --git a/cores/esp8266/twi.h b/cores/esp8266/twi.h index 9e661e88ea..f0f76e106f 100644 --- a/cores/esp8266/twi.h +++ b/cores/esp8266/twi.h @@ -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); diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index c1f457aa47..1e7e2d5606 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -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; diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 9fc8f9c76d..fa20dbb310 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -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); diff --git a/libraries/Wire/keywords.txt b/libraries/Wire/keywords.txt index ff31475920..3344011d40 100644 --- a/libraries/Wire/keywords.txt +++ b/libraries/Wire/keywords.txt @@ -12,6 +12,7 @@ begin KEYWORD2 setClock KEYWORD2 +setClockStretchLimit KEYWORD2 beginTransmission KEYWORD2 endTransmission KEYWORD2 requestFrom KEYWORD2