1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-21 21:22:31 +03:00

Added 50kHz operation mode for I2C/Wire library (#3401)

This commit is contained in:
derSeddy
2018-03-24 19:46:29 +01:00
committed by Develo
parent 438d3f1d11
commit 6464ae0c79

View File

@ -45,13 +45,15 @@ static uint32_t twi_clockStretchLimit;
void twi_setClock(unsigned int freq){ void twi_setClock(unsigned int freq){
#if F_CPU == FCPU80 #if F_CPU == FCPU80
if(freq <= 100000) twi_dcount = 19;//about 100KHz 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 <= 200000) twi_dcount = 8;//about 200KHz
else if(freq <= 300000) twi_dcount = 3;//about 300KHz else if(freq <= 300000) twi_dcount = 3;//about 300KHz
else if(freq <= 400000) twi_dcount = 1;//about 400KHz else if(freq <= 400000) twi_dcount = 1;//about 400KHz
else twi_dcount = 1;//about 400KHz else twi_dcount = 1;//about 400KHz
#else #else
if(freq <= 100000) twi_dcount = 32;//about 100KHz 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 <= 200000) twi_dcount = 14;//about 200KHz
else if(freq <= 300000) twi_dcount = 8;//about 300KHz else if(freq <= 300000) twi_dcount = 8;//about 300KHz
else if(freq <= 400000) twi_dcount = 5;//about 400KHz else if(freq <= 400000) twi_dcount = 5;//about 400KHz
@ -85,14 +87,16 @@ static void twi_delay(unsigned char v){
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
unsigned int reg; unsigned int reg;
for(i=0;i<v;i++) reg = GPI; for(i=0;i<v;i++)
reg = GPI;
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
static bool twi_write_start(void) { static bool twi_write_start(void) {
SCL_HIGH(); SCL_HIGH();
SDA_HIGH(); SDA_HIGH();
if (SDA_READ() == 0) return false; if (SDA_READ() == 0)
return false;
twi_delay(twi_dcount); twi_delay(twi_dcount);
SDA_LOW(); SDA_LOW();
twi_delay(twi_dcount); twi_delay(twi_dcount);
@ -116,8 +120,10 @@ static bool twi_write_stop(void){
static bool twi_write_bit(bool bit) { static bool twi_write_bit(bool bit) {
uint32_t i = 0; uint32_t i = 0;
SCL_LOW(); SCL_LOW();
if (bit) SDA_HIGH(); if (bit)
else SDA_LOW(); SDA_HIGH();
else
SDA_LOW();
twi_delay(twi_dcount+1); twi_delay(twi_dcount+1);
SCL_HIGH(); SCL_HIGH();
while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
@ -149,25 +155,30 @@ static bool twi_write_byte(unsigned char byte) {
static unsigned char twi_read_byte(bool nack) { static unsigned char twi_read_byte(bool nack) {
unsigned char byte = 0; unsigned char byte = 0;
unsigned char bit; unsigned char bit;
for (bit = 0; bit < 8; bit++) byte = (byte << 1) | twi_read_bit(); for (bit = 0; bit < 8; bit++)
byte = (byte << 1) | twi_read_bit();
twi_write_bit(nack); twi_write_bit(nack);
return byte; return byte;
} }
unsigned char twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop){ unsigned char twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop){
unsigned int i; unsigned int i;
if(!twi_write_start()) return 4;//line busy if(!twi_write_start())
return 4;//line busy
if(!twi_write_byte(((address << 1) | 0) & 0xFF)) { if(!twi_write_byte(((address << 1) | 0) & 0xFF)) {
if (sendStop) twi_write_stop(); if (sendStop)
twi_write_stop();
return 2; //received NACK on transmit of address return 2; //received NACK on transmit of address
} }
for(i=0; i<len; i++) { for(i=0; i<len; i++) {
if(!twi_write_byte(buf[i])) { if(!twi_write_byte(buf[i])) {
if (sendStop) twi_write_stop(); if (sendStop)
twi_write_stop();
return 3;//received NACK on transmit of data return 3;//received NACK on transmit of data
} }
} }
if(sendStop) twi_write_stop(); if(sendStop)
twi_write_stop();
i = 0; i = 0;
while(SDA_READ() == 0 && (i++) < 10){ while(SDA_READ() == 0 && (i++) < 10){
SCL_LOW(); SCL_LOW();
@ -180,14 +191,18 @@ unsigned char twi_writeTo(unsigned char address, unsigned char * buf, unsigned i
unsigned char twi_readFrom(unsigned char address, unsigned char* buf, unsigned int len, unsigned char sendStop){ unsigned char twi_readFrom(unsigned char address, unsigned char* buf, unsigned int len, unsigned char sendStop){
unsigned int i; unsigned int i;
if(!twi_write_start()) return 4;//line busy if(!twi_write_start())
return 4;//line busy
if(!twi_write_byte(((address << 1) | 1) & 0xFF)) { if(!twi_write_byte(((address << 1) | 1) & 0xFF)) {
if (sendStop) twi_write_stop(); if (sendStop)
twi_write_stop();
return 2;//received NACK on transmit of address return 2;//received NACK on transmit of address
} }
for(i=0; i<(len-1); i++) buf[i] = twi_read_byte(false); for(i=0; i<(len-1); i++)
buf[i] = twi_read_byte(false);
buf[len-1] = twi_read_byte(true); buf[len-1] = twi_read_byte(true);
if(sendStop) twi_write_stop(); if(sendStop)
twi_write_stop();
i = 0; i = 0;
while(SDA_READ() == 0 && (i++) < 10){ while(SDA_READ() == 0 && (i++) < 10){
SCL_LOW(); SCL_LOW();