Skip to content
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

Issue2524 allow clocks below 100KHz #6934

Merged
merged 11 commits into from
Dec 28, 2019
109 changes: 24 additions & 85 deletions cores/esp8266/core_esp8266_si2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Twi
{
private:
unsigned int preferred_si2c_clock = 100000;
unsigned char twi_dcount = 18;
uint32_t twi_dcount = 18;
unsigned char twi_sda = 0;
unsigned char twi_scl = 0;
unsigned char twi_addr = 0;
Expand Down Expand Up @@ -112,7 +112,7 @@ class Twi
bool _slaveEnabled = false;

// Internal use functions
void ICACHE_RAM_ATTR busywait(unsigned char v);
void ICACHE_RAM_ATTR busywait(unsigned int v);
bool write_start(void);
bool write_stop(void);
bool write_bit(bool bit);
Expand Down Expand Up @@ -148,7 +148,6 @@ class Twi
void attachSlaveRxEvent(void (*function)(uint8_t*, size_t));
void attachSlaveTxEvent(void (*function)(void));
void ICACHE_RAM_ATTR reply(uint8_t ack);
void ICACHE_RAM_ATTR stop(void);
void ICACHE_RAM_ATTR releaseBus(void);
void enableSlave();
};
Expand All @@ -161,65 +160,22 @@ static Twi twi;

void Twi::setClock(unsigned int freq)
{
preferred_si2c_clock = freq;
preferred_si2c_clock = freq;

#if F_CPU == FCPU80
if (freq <= 50000)
{
twi_dcount = 38; //about 50KHz
}
else if (freq <= 100000)
{
twi_dcount = 19; //about 100KHz
}
else if (freq <= 200000)
{
twi_dcount = 8; //about 200KHz
}
else if (freq <= 300000)
{
twi_dcount = 3; //about 300KHz
}
else if (freq <= 400000)
{
twi_dcount = 1; //about 400KHz
}
else
{
twi_dcount = 1; //about 400KHz
}

if (freq > 400000)
freq = 400000;
twi_dcount = (500000000 / freq); // half-cycle period in ns
twi_dcount = (1000*(twi_dcount - 1120)) / 62500; // (half cycle - overhead) / busywait loop time

#else
if (freq <= 50000)
{
twi_dcount = 64; //about 50KHz
}
else if (freq <= 100000)
{
twi_dcount = 32; //about 100KHz
}
else if (freq <= 200000)
{
twi_dcount = 14; //about 200KHz
}
else if (freq <= 300000)
{
twi_dcount = 8; //about 300KHz
}
else if (freq <= 400000)
{
twi_dcount = 5; //about 400KHz
}
else if (freq <= 500000)
{
twi_dcount = 3; //about 500KHz
}
else if (freq <= 600000)
{
twi_dcount = 2; //about 600KHz
}
else
{
twi_dcount = 1; //about 700KHz
}

if (freq > 800000)
freq = 800000;
twi_dcount = (500000000 / freq); // half-cycle period in ns
twi_dcount = (1000*(twi_dcount - 560)) / 31250; // (half cycle - overhead) / busywait loop time

#endif
}

Expand Down Expand Up @@ -262,18 +218,18 @@ void Twi::enableSlave()
}
}

void ICACHE_RAM_ATTR Twi::busywait(unsigned char v)
void ICACHE_RAM_ATTR Twi::busywait(unsigned int v)
{
unsigned int i;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
unsigned int reg;
for (i = 0; i < v; i++)
for (i = 0; i < v; i++) // loop time is 5 machine cycles: 31.25ns @ 160MHz, 62.5ns @ 80MHz
{
reg = GPI;
asm("nop"); // minimum element to keep GCC from optimizing this function out.
}
(void)reg;
#pragma GCC diagnostic pop

// {
// esp8266::polledTimeout::oneShotFastNs timeout(v);
// while(!timeout) { //
// }
}

bool Twi::write_start(void)
Expand Down Expand Up @@ -529,17 +485,6 @@ void ICACHE_RAM_ATTR Twi::reply(uint8_t ack)
}
}

void ICACHE_RAM_ATTR Twi::stop(void)
{
// send stop condition
//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
SCL_HIGH(twi.twi_scl); // _BV(TWINT)
twi_ack = 1; // _BV(TWEA)
busywait(5); // Maybe this should be here
SDA_HIGH(twi.twi_sda); // _BV(TWSTO)
// update twi state
twi_state = TWI_READY;
}

void ICACHE_RAM_ATTR Twi::releaseBus(void)
{
Expand Down Expand Up @@ -657,7 +602,6 @@ void ICACHE_RAM_ATTR Twi::onTwipEvent(uint8_t status)
break;
case TW_BUS_ERROR: // bus error, illegal stop/start
twi_error = TW_BUS_ERROR;
stop();
break;
}
}
Expand Down Expand Up @@ -1018,11 +962,6 @@ extern "C" {
return twi.setAddress(a);
}

void twi_stop(void)
{
twi.stop();
}

void twi_setClock(unsigned int freq)
{
twi.setClock(freq);
Expand Down