1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

Configurable I2C clock stretching limit

Use Wire.setClockStretchLimit(limit)
limit is in uSeconds
This commit is contained in:
mvdbro 2016-02-03 17:05:04 +01:00
parent aa0c14c2d0
commit 3f15903566
5 changed files with 22 additions and 8 deletions

View File

@ -24,6 +24,7 @@
unsigned char twi_dcount = 18; unsigned char twi_dcount = 18;
static unsigned char twi_sda, twi_scl; 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_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) #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 #endif
#if F_CPU == FCPU80 #if F_CPU == FCPU80
#define TWI_CLOCK_STRETCH 800 #define TWI_CLOCK_STRETCH_MULTIPLIER 3
#else #else
#define TWI_CLOCK_STRETCH 1600 #define TWI_CLOCK_STRETCH_MULTIPLIER 6
#endif #endif
void twi_setClock(unsigned int freq){ void twi_setClock(unsigned int freq){
@ -60,14 +61,20 @@ void twi_setClock(unsigned int freq){
#endif #endif
} }
void twi_setClockStretchLimit(uint32_t limit){
twi_clockStretchLimit = limit * TWI_CLOCK_STRETCH_MULTIPLIER;
}
void twi_init(unsigned char sda, unsigned char scl){ void twi_init(unsigned char sda, unsigned char scl){
twi_sda = sda; twi_sda = sda;
twi_scl = scl; twi_scl = scl;
pinMode(twi_sda, INPUT_PULLUP); pinMode(twi_sda, INPUT_PULLUP);
pinMode(twi_scl, INPUT_PULLUP); pinMode(twi_scl, INPUT_PULLUP);
twi_setClock(100000); twi_setClock(100000);
twi_setClockStretchLimit(230); // default value is 230 uS
} }
void twi_stop(void){ void twi_stop(void){
pinMode(twi_sda, INPUT); pinMode(twi_sda, INPUT);
pinMode(twi_scl, INPUT); pinMode(twi_scl, INPUT);
@ -93,12 +100,12 @@ static bool twi_write_start(void) {
} }
static bool twi_write_stop(void){ static bool twi_write_stop(void){
unsigned int i = 0; uint32_t i = 0;
SCL_LOW(); SCL_LOW();
SDA_LOW(); SDA_LOW();
twi_delay(twi_dcount); twi_delay(twi_dcount);
SCL_HIGH(); 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); twi_delay(twi_dcount);
SDA_HIGH(); SDA_HIGH();
twi_delay(twi_dcount); twi_delay(twi_dcount);
@ -107,24 +114,24 @@ static bool twi_write_stop(void){
} }
static bool twi_write_bit(bool bit) { static bool twi_write_bit(bool bit) {
unsigned int i = 0; uint32_t i = 0;
SCL_LOW(); SCL_LOW();
if (bit) SDA_HIGH(); if (bit) SDA_HIGH();
else SDA_LOW(); else SDA_LOW();
twi_delay(twi_dcount+1); twi_delay(twi_dcount+1);
SCL_HIGH(); 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); twi_delay(twi_dcount);
return true; return true;
} }
static bool twi_read_bit(void) { static bool twi_read_bit(void) {
unsigned int i = 0; uint32_t i = 0;
SCL_LOW(); SCL_LOW();
SDA_HIGH(); SDA_HIGH();
twi_delay(twi_dcount+2); twi_delay(twi_dcount+2);
SCL_HIGH(); 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(); bool bit = SDA_READ();
twi_delay(twi_dcount); twi_delay(twi_dcount);
return bit; return bit;

View File

@ -29,6 +29,7 @@ extern "C" {
void twi_init(unsigned char sda, unsigned char scl); void twi_init(unsigned char sda, unsigned char scl);
void twi_stop(void); void twi_stop(void);
void twi_setClock(unsigned int freq); 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_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); uint8_t twi_readFrom(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop);

View File

@ -85,6 +85,10 @@ void TwoWire::setClock(uint32_t frequency){
twi_setClock(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){ size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop){
if(size > BUFFER_LENGTH){ if(size > BUFFER_LENGTH){
size = BUFFER_LENGTH; size = BUFFER_LENGTH;

View File

@ -56,6 +56,7 @@ class TwoWire : public Stream
void begin(uint8_t); void begin(uint8_t);
void begin(int); void begin(int);
void setClock(uint32_t); void setClock(uint32_t);
void setClockStretchLimit(uint32_t);
void beginTransmission(uint8_t); void beginTransmission(uint8_t);
void beginTransmission(int); void beginTransmission(int);
uint8_t endTransmission(void); uint8_t endTransmission(void);

View File

@ -12,6 +12,7 @@
begin KEYWORD2 begin KEYWORD2
setClock KEYWORD2 setClock KEYWORD2
setClockStretchLimit KEYWORD2
beginTransmission KEYWORD2 beginTransmission KEYWORD2
endTransmission KEYWORD2 endTransmission KEYWORD2
requestFrom KEYWORD2 requestFrom KEYWORD2