├── README.md ├── Wire ├── Wire.cpp ├── Wire.h ├── keywords.txt └── library.properties └── esp8266 ├── core_esp8266_si2c.cpp └── twi.h /README.md: -------------------------------------------------------------------------------- 1 | [![license-badge][]][license] [![stars][]][stargazers] [![hit-count][]][count] [![github-issues][]][issues] 2 | 3 | # ESP8266-I2C-Driver 4 | Fixed built-in Master I²C driver for Arduino ESP8266 core. Sorry it doesn't support slave I²C mode. 5 | 6 | | Board | SDA | SCL | Level | 7 | | ---- | ---- | ---- | ---- | 8 | | ESP8266 | GPIO4 | GPIO5 | 3.3v/5v | 9 | | ESP8266 ESP-01 | GPIO0/D5 | GPIO2/D3 | 3.3v/5v | 10 | | NodeMCU 1.0, WeMos D1 Mini | GPIO4/D2 | GPIO5/D1 | 3.3v/5v | 11 | 12 | Copy and replace "**twi.h**", "**core_esp8266_si2c.cpp**" in folder %USERPROFILE%\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\cores\esp8266 13 | 14 | Copy and replace "**Wire.h**", "**Wire.cpp**" in folder %USERPROFILE%\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\Wire 15 | 16 | If you want to keep the original files - just change the file extension* to "**twi.h.OLD**" and etc. Then you always can go back. 17 | 18 | *_if you change the file name you get an error at compile time_ 19 | 20 | Special thanks to [Tech-TX(StanJ)](https://github.com/Tech-TX) 21 | 22 | [license-badge]: https://img.shields.io/badge/License-GPLv3-blue.svg 23 | [license]: https://choosealicense.com/licenses/gpl-3.0/ 24 | [stars]: https://img.shields.io/github/stars/enjoyneering/ESP8266-I2C-Driver.svg 25 | [stargazers]: https://github.com/enjoyneering/ESP8266-I2C-Driver/stargazers 26 | [hit-count]: http://hits.dwyl.io/enjoyneering/ESP8266-I2C-Driver/badges.svg 27 | [count]: http://hits.dwyl.io/enjoyneering/ESP8266-I2C-Driver/badges 28 | [github-issues]: https://img.shields.io/github/issues/enjoyneering/ESP8266-I2C-Driver.svg 29 | [issues]: https://github.com/enjoyneering/ESP8266-I2C-Driver/issues/ 30 | -------------------------------------------------------------------------------- /Wire/Wire.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************************/ 2 | /* 3 | TwoWire.cpp - master TWI/I²C library for ESP8266 Arduino 4 | 5 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 6 | Modified December 2014 by Ivan Grokhotkov (ivan@esp8266.com) - esp8266 support 7 | Modified April 2015 by Hrsto Gochkov (ficeto@ficeto.com) - alternative esp8266 support 8 | Modified 2019 by enjoyneering79, source code: https://github.com/enjoyneering/ 9 | 10 | Specials pins are required: 11 | Board: SDA SCL Level 12 | ESP8266................................... GPIO4 GPIO5 3.3v/5v 13 | ESP8266 ESP-01............................ GPIO0/D5 GPIO2/D3 3.3v/5v 14 | NodeMCU 1.0, WeMos D1 Mini................ GPIO4/D2 GPIO5/D1 3.3v/5v 15 | 16 | NOTE: 17 | - I2C bus drivers are "open drain", meaning that they can pull the 18 | corresponding signal line low, but cannot drive it high. Thus, there can 19 | be no bus contention where one device is trying to drive the line high 20 | while another tries to pull it low, eliminating the potential for damage 21 | to the drivers or excessive power dissipation in the system. Each signal 22 | line has a pull-up resistor on it, to restore the signal to high when no 23 | device is asserting it low. 24 | 25 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 26 | This library is free software; you can redistribute it and/or 27 | modify it under the terms of the GNU Lesser General Public 28 | License as published by the Free Software Foundation; either 29 | version 2.1 of the License, or (at your option) any later version. 30 | This library is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 33 | Lesser General Public License for more details. 34 | 35 | You should have received a copy of the GNU Lesser General Public 36 | License along with this library; if not, write to the Free Software 37 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 38 | */ 39 | /**************************************************************************************/ 40 | 41 | extern "C" 42 | { 43 | #include 44 | #include 45 | #include 46 | } 47 | 48 | #include "twi.h" //i2c software bit-bang emulation 49 | #include "Wire.h" //arduino wrapper 50 | 51 | 52 | /**************************************************************************/ 53 | /* 54 | Some boards don't have SDA/SCL pins available & don't support "Wire.h" 55 | */ 56 | /**************************************************************************/ 57 | #if !defined(PIN_WIRE_SDA) || !defined(PIN_WIRE_SCL) 58 | #error Wire library is not supported by this board 59 | #endif 60 | 61 | /**************************************************************************/ 62 | /* 63 | Initialize Class Variables 64 | */ 65 | /**************************************************************************/ 66 | uint8_t TwoWire::_rxBuffer[TWI_I2C_BUFFER_LENGTH]; 67 | uint8_t TwoWire::_rxBufferIndex = 0; 68 | uint8_t TwoWire::_rxBufferLength = 0; 69 | 70 | uint8_t TwoWire::_txBuffer[TWI_I2C_BUFFER_LENGTH]; 71 | uint8_t TwoWire::_txAddress = 0; 72 | uint8_t TwoWire::_txBufferIndex = 0; 73 | uint8_t TwoWire::_txBufferLength = 0; 74 | bool TwoWire::_transmitting = false; 75 | 76 | void (*TwoWire::user_onRequest)(void); 77 | void (*TwoWire::user_onReceive)(int); 78 | 79 | static uint8_t default_sda_pin = SDA; 80 | static uint8_t default_scl_pin = SCL; 81 | 82 | /**************************************************************************/ 83 | /* 84 | Constructors 85 | */ 86 | /**************************************************************************/ 87 | TwoWire::TwoWire() 88 | { 89 | } 90 | 91 | /**************************************************************************/ 92 | /* 93 | pins(), public method 94 | 95 | Deprecated, use begin(sda, scl) in new projects 96 | */ 97 | /**************************************************************************/ 98 | void TwoWire::pins(int sda, int scl) 99 | { 100 | default_sda_pin = sda; 101 | default_scl_pin = scl; 102 | } 103 | 104 | /**************************************************************************/ 105 | /* 106 | begin(), public method 107 | 108 | Sets bus speed, clock strech limit & sets pins to open drain & switch 109 | them to high state 110 | 111 | NOTE: 112 | - I2C bus drivers are “open drain”, meaning that they can pull the 113 | corresponding signal line low, but cannot drive it high. Thus, there can 114 | be no bus contention where one device is trying to drive the line high 115 | while another tries to pull it low, eliminating the potential for damage 116 | to the drivers or excessive power dissipation in the system. Each signal 117 | line has a pull-up resistor on it, to restore the signal to high when no 118 | device is asserting it low. 119 | - however this driver used INPUT_PULLUP, because people forgetting about 120 | external pull up resistors, so the code has changed a bit recently. 121 | Instead of changing pin output register when banging the bits, we now 122 | change pin mode register. The pin is switched between INPUT_PULLUP & 123 | OUTPUT modes, which makes it either a weak pull up or a strong pull down 124 | (output register has 0 written into it in advance) 125 | */ 126 | /**************************************************************************/ 127 | void TwoWire::begin(uint8_t sda, uint8_t scl) 128 | { 129 | default_sda_pin = sda; 130 | default_scl_pin = scl; 131 | 132 | twi_init(sda, scl); 133 | flush(); 134 | } 135 | 136 | /**************************************************************************/ 137 | /* 138 | begin(), public method 139 | 140 | Sets bus speed, clock strech limit, SDA & SCL to INPUT_PULLUP & pulls 141 | lines high 142 | */ 143 | /**************************************************************************/ 144 | void TwoWire::begin(void) 145 | { 146 | begin(default_sda_pin, default_scl_pin); 147 | } 148 | 149 | /**************************************************************************/ 150 | /* 151 | setClock(), public method 152 | 153 | Sets i2c speed, in Hz 154 | 155 | NOTE: 156 | - speed @ 80Mhz CPU: 10kHz..400KHz 157 | - speed @ 160Mhz CPU: 10kHz..700KHz 158 | */ 159 | /**************************************************************************/ 160 | void TwoWire::setClock(uint32_t frequency) 161 | { 162 | twi_setClock(frequency); 163 | } 164 | 165 | /**************************************************************************/ 166 | /* 167 | setClockStretchLimit(), public method 168 | 169 | Sets SCL stretch limit, in μsec 170 | 171 | NOTE: 172 | - 1250 μsec by default 173 | */ 174 | /**************************************************************************/ 175 | void TwoWire::setClockStretchLimit(uint32_t limit) 176 | { 177 | twi_setClockStretchLimit(limit); 178 | } 179 | 180 | /**************************************************************************/ 181 | /* 182 | beginTransmission(), public method 183 | 184 | Sets all tx buffer variebles before reading 185 | */ 186 | /**************************************************************************/ 187 | void TwoWire::beginTransmission(uint8_t address) 188 | { 189 | _txAddress = address; 190 | _txBufferIndex = 0; 191 | _txBufferLength = 0; 192 | _transmitting = true; //ready to transmit flag, true when address is set up 193 | } 194 | 195 | void TwoWire::beginTransmission(int address) 196 | { 197 | beginTransmission(static_cast(address)); 198 | } 199 | 200 | /**************************************************************************/ 201 | /* 202 | write(), public Print class method 203 | 204 | Adds outcoming ONE byte into tx buffer for future transmit 205 | Returns the qnt of added bytes, in our case 1 or 0 206 | */ 207 | /**************************************************************************/ 208 | size_t TwoWire::write(uint8_t data) 209 | { 210 | if (_transmitting != true || _txBufferLength > TWI_I2C_BUFFER_LENGTH) return 0; //slave address not set or data too long to fit in tx buffer 211 | 212 | /* put one byte into tx buffer */ 213 | _txBuffer[_txBufferIndex] = data; 214 | _txBufferIndex++; 215 | _txBufferLength = _txBufferIndex; 216 | 217 | return 1; 218 | } 219 | 220 | /**************************************************************************/ 221 | /* 222 | write(), public Print class method 223 | 224 | Adds outcoming ARRAY of bytes into tx buffer for future transmit 225 | Returns the qnt of successfully added bytes 226 | */ 227 | /**************************************************************************/ 228 | size_t TwoWire::write(const uint8_t *buffer, size_t quantity) 229 | { 230 | for (size_t i = 0; i < quantity; i++) 231 | { 232 | if (write(buffer[i]) == 0) return i; //add one byte from array into tx buffer, if error return qnt of successfully added bytes 233 | } 234 | 235 | return quantity; 236 | } 237 | 238 | /**************************************************************************/ 239 | /* 240 | endTransmission(), public method 241 | 242 | Transmits the data from rx buffer to slave. 243 | 244 | NOTE: 245 | - i2c bus status reply: 246 | 0 - success 247 | 1 - data too long to fit in transmit buffer 248 | 2 - received NACK on transmit of address 249 | 3 - received NACK on transmit of data 250 | 4 - can't start, line busy 251 | - byte is transferred with the most significant bit (MSB) first, 7..0 bit 252 | - when master sets SDA HIGH during this 9-th clock pulse, this is 253 | defined as NACK (Not Acknowledge). The master generate STOP condition 254 | to abort the transfer 255 | - if master sets SDA LOW during this 9-th clock pulse, this is defined 256 | as ACK (Acknowledge). The master generate REPEATE START condition to 257 | start a new transfer. 258 | - regardless of the number of start conditions during one transfer 259 | the transfer must be ended by exactly one stop condition followed 260 | by NACK. 261 | */ 262 | /**************************************************************************/ 263 | uint8_t TwoWire::endTransmission(bool sendStop) 264 | { 265 | if (_txBufferLength > TWI_I2C_BUFFER_LENGTH) return 1; //data too long to fit in tx buffer 266 | 267 | #if defined TWI_I2C_DISABLE_INTERRUPTS 268 | noInterrupts(); //disable all interrupts 269 | #endif 270 | 271 | uint8_t reply = twi_writeTo(_txAddress, _txBuffer, _txBufferLength, sendStop); //write data from tx buffer to I2C slave 272 | 273 | #if defined TWI_I2C_DISABLE_INTERRUPTS 274 | interrupts(); //re-enable all interrupts 275 | #endif 276 | 277 | flushTX(); //clear tx buffer for future data 278 | 279 | return reply; 280 | } 281 | 282 | uint8_t TwoWire::endTransmission(void) 283 | { 284 | return endTransmission(true); 285 | } 286 | 287 | /**************************************************************************/ 288 | /* 289 | requestFrom(), public method 290 | 291 | Reads the data from slave to the rx buffer & returns the quantity 292 | of successfully received bytes 293 | */ 294 | /**************************************************************************/ 295 | uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, bool sendStop) 296 | { 297 | if (quantity == 0) return 0; //nothing to read 298 | if (quantity > TWI_I2C_BUFFER_LENGTH) quantity = TWI_I2C_BUFFER_LENGTH; //safety check 299 | 300 | flushRX(); //clear rx buffer for new data 301 | 302 | #if defined TWI_I2C_DISABLE_INTERRUPTS 303 | noInterrupts(); //disable all interrupts 304 | #endif 305 | 306 | uint8_t length = twi_readFrom(address, _rxBuffer, quantity, sendStop); //read new data from I2C slave to rx buffer 307 | 308 | #if defined TWI_I2C_DISABLE_INTERRUPTS 309 | interrupts(); //re-enable all interrupts 310 | #endif 311 | 312 | _rxBufferLength = length; 313 | 314 | return length; 315 | } 316 | 317 | uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) 318 | { 319 | return requestFrom(address, quantity, static_cast(sendStop)); 320 | } 321 | 322 | uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) 323 | { 324 | return requestFrom(address, quantity, true); 325 | } 326 | 327 | uint8_t TwoWire::requestFrom(int address, int quantity, bool sendStop) 328 | { 329 | return requestFrom(static_cast(address), static_cast(quantity), sendStop); 330 | } 331 | 332 | uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) 333 | { 334 | return requestFrom(static_cast(address), static_cast(quantity), static_cast(sendStop)); 335 | } 336 | 337 | uint8_t TwoWire::requestFrom(int address, int quantity) 338 | { 339 | return requestFrom(static_cast(address), static_cast(quantity), true); 340 | } 341 | 342 | /**************************************************************************/ 343 | /* 344 | available(), public method 345 | 346 | Checks the rx buffer & returns available qnt of bytes retrieved from slave 347 | 348 | NOTE: 349 | - the proper way to use available() 350 | 351 | do 352 | { 353 | Wire.requestFrom(ADDRESS, 1, true); //read slave & fill the rx buffer with data 354 | } 355 | while (Wire.available() != 1); //check available data size in rx buffer 356 | */ 357 | /**************************************************************************/ 358 | int TwoWire::available(void) 359 | { 360 | int result = _rxBufferLength - _rxBufferIndex; 361 | 362 | /* 363 | yield will not make more data available but it will prevent the esp8266 364 | from going into WDT reset during the "while()" 365 | */ 366 | if (result == 0) optimistic_yield(1000); 367 | 368 | return result; 369 | } 370 | 371 | /**************************************************************************/ 372 | /* 373 | read(), public method 374 | 375 | Returns byte value from rx buffer 376 | */ 377 | /**************************************************************************/ 378 | int TwoWire::read(void) 379 | { 380 | if (_rxBufferIndex > _rxBufferLength) return 0; 381 | 382 | int value = _rxBuffer[_rxBufferIndex]; 383 | 384 | _rxBufferIndex++; 385 | 386 | return value; 387 | } 388 | 389 | 390 | /**************************************************************************/ 391 | /* 392 | peek(), public method 393 | 394 | Returns the value of last received byte without removing it 395 | from rx buffer 396 | */ 397 | /**************************************************************************/ 398 | int TwoWire::peek(void) 399 | { 400 | if (_rxBufferIndex < _rxBufferLength) return _rxBuffer[_rxBufferIndex]; 401 | return 0; 402 | } 403 | 404 | /**************************************************************************/ 405 | /* 406 | flushRX(), private method 407 | 408 | Clears & resets rx buffers 409 | */ 410 | /**************************************************************************/ 411 | void TwoWire::flushRX(void) 412 | { 413 | _rxBufferIndex = 0; 414 | _rxBufferLength = 0; 415 | //memset(_rxBuffer, 0, TWI_I2C_BUFFER_LENGTH); //sets all bytes in rx buffer to "0" 416 | } 417 | 418 | /**************************************************************************/ 419 | /* 420 | flushTX(), private method 421 | 422 | Clears & resets tx buffers 423 | */ 424 | /**************************************************************************/ 425 | void TwoWire::flushTX(void) 426 | { 427 | _txBufferIndex = 0; 428 | _txBufferLength = 0; 429 | _transmitting = false; //ready to transmit flag, true when address is set up 430 | //memset(_txBuffer, 0, TWI_I2C_BUFFER_LENGTH); //sets all bytes in tx buffer to "0" 431 | } 432 | 433 | /**************************************************************************/ 434 | /* 435 | flush(), public method 436 | 437 | Clears & resets rx/tx buffers 438 | */ 439 | /**************************************************************************/ 440 | void TwoWire::flush(void) 441 | { 442 | flushTX(); 443 | flushRX(); 444 | } 445 | 446 | /**************************************************************************/ 447 | /* 448 | status(), public method 449 | 450 | Returns i2c bus status 451 | 452 | NOTE: 453 | - returned code: 454 | - I2C_OK 0, OK 455 | - I2C_SDA_HELD_LOW 1, SDA held low by another device, no procedure available to recover 456 | - I2C_SDA_HELD_LOW_AFTER_INIT 2, SDA held low beyond slave clock stretch time, increase stretch time 457 | - I2C_SCL_HELD_LOW 3, SCL held low by another device, no procedure available to recover 458 | - I2C_SCL_HELD_LOW_AFTER_READ 4, SCL held low beyond slave clock stretch time, stretch stretch time 459 | */ 460 | /**************************************************************************/ 461 | uint8_t TwoWire::status() 462 | { 463 | return twi_status(); 464 | } 465 | 466 | /**************************************************************************/ 467 | /* 468 | onReceive(), public method 469 | */ 470 | /**************************************************************************/ 471 | void TwoWire::onReceive(void (*function)(int)) 472 | { 473 | (void)function; 474 | } 475 | 476 | /**************************************************************************/ 477 | /* 478 | onRequest(), public method 479 | */ 480 | /**************************************************************************/ 481 | void TwoWire::onRequest(void (*function)(void)) 482 | { 483 | (void)function; 484 | } 485 | 486 | /**************************************************************************/ 487 | /* 488 | onReceiveService(), private method 489 | */ 490 | /**************************************************************************/ 491 | void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) 492 | { 493 | (void)inBytes; 494 | (void)numBytes; 495 | /* 496 | //don't bother if user hasn't registered a callback 497 | if (!user_onReceive) return; 498 | 499 | //don't bother if rx buffer is in use by a master requestFrom() op 500 | //i know this drops data, but it allows for slight stupidity 501 | //meaning, they may not have read all the master requestFrom() data yet 502 | if (_rxBufferIndex < _rxBufferLength) return; 503 | 504 | //copy twi rx buffer into local read buffer 505 | //this enables new reads to happen in parallel 506 | for(uint8_t i = 0; i < numBytes; ++i) 507 | { 508 | _rxBuffer[i] = inBytes[i]; 509 | } 510 | //set rx iterator vars 511 | _rxBufferIndex = 0; 512 | _rxBufferLength = numBytes; 513 | 514 | //alert user program 515 | user_onReceive(numBytes); 516 | */ 517 | } 518 | 519 | /**************************************************************************/ 520 | /* 521 | onRequestService(), private method 522 | */ 523 | /**************************************************************************/ 524 | void TwoWire::onRequestService(void) 525 | { 526 | /* 527 | //don't bother if user hasn't registered a callback 528 | if (!user_onRequest) return; 529 | 530 | //reset tx buffer iterator vars 531 | //!!! this will kill any pending pre-master sendTo() activity 532 | _rxBufferIndex = 0; 533 | _rxBufferLength = 0; 534 | 535 | //alert user program 536 | user_onRequest(); 537 | */ 538 | } 539 | 540 | #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_TWOWIRE) 541 | TwoWire Wire; 542 | #endif 543 | -------------------------------------------------------------------------------- /Wire/Wire.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************/ 2 | /* 3 | TwoWire.h - master TWI/I²C library for ESP8266 Arduino 4 | 5 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 6 | Modified December 2014 by Ivan Grokhotkov (ivan@esp8266.com) - esp8266 support 7 | Modified April 2015 by Hrsto Gochkov (ficeto@ficeto.com) - alternative esp8266 support 8 | Modified 2019 by enjoyneering79, source code: https://github.com/enjoyneering/ 9 | 10 | Specials pins are required: 11 | Board: SDA SCL Level 12 | ESP8266................................... GPIO4 GPIO5 3.3v/5v 13 | ESP8266 ESP-01............................ GPIO0/D5 GPIO2/D3 3.3v/5v 14 | NodeMCU 1.0, WeMos D1 Mini................ GPIO4/D2 GPIO5/D1 3.3v/5v 15 | 16 | NOTE: 17 | - I2C bus drivers are "open drain", meaning that they can pull the 18 | corresponding signal line low, but cannot drive it high. Thus, there can 19 | be no bus contention where one device is trying to drive the line high 20 | while another tries to pull it low, eliminating the potential for damage 21 | to the drivers or excessive power dissipation in the system. Each signal 22 | line has a pull-up resistor on it, to restore the signal to high when no 23 | device is asserting it low. 24 | 25 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 26 | This library is free software; you can redistribute it and/or 27 | modify it under the terms of the GNU Lesser General Public 28 | License as published by the Free Software Foundation; either 29 | version 2.1 of the License, or (at your option) any later version. 30 | This library is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 33 | Lesser General Public License for more details. 34 | 35 | You should have received a copy of the GNU Lesser General Public 36 | License along with this library; if not, write to the Free Software 37 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 38 | */ 39 | /**************************************************************************************/ 40 | 41 | #ifndef TwoWire_h 42 | #define TwoWire_h 43 | 44 | #include 45 | #include "Stream.h" 46 | 47 | /* 48 | The arduino toolchain includes library headers before it includes your sketch. 49 | Unfortunately, you cannot #define in a sketch & get it in the library. 50 | */ 51 | //defined TWI_I2C_DISABLE_INTERRUPTS //uncomment to disable interrupts during read/write 52 | 53 | #ifndef TWI_I2C_BUFFER_LENGTH 54 | #define TWI_I2C_BUFFER_LENGTH 32 //32-bytes rx buffer + 32-bytes tx buffer, 64-bytes total 55 | #endif 56 | 57 | 58 | class TwoWire : public Stream 59 | { 60 | public: 61 | TwoWire(); 62 | 63 | void pins(int sda, int scl) __attribute__((deprecated)); //use "begin(sda, scl)" in new projects 64 | void begin(uint8_t sda, uint8_t scl); 65 | void begin(void); 66 | void setClock(uint32_t frequency); 67 | void setClockStretchLimit(uint32_t limit); 68 | 69 | void beginTransmission(uint8_t address); 70 | void beginTransmission(int address); 71 | 72 | virtual size_t write(uint8_t data); 73 | virtual size_t write(const uint8_t *buffer, size_t quantity); 74 | 75 | //inline size_t write(int data) {return write((uint8_t)data);} 76 | //inline size_t write(unsigned int data) {return write((uint8_t)data);} 77 | //inline size_t write(long data) {return write((uint8_t)data);} 78 | //inline size_t write(unsigned long data) {return write((uint8_t)data);} 79 | 80 | using Print::write; 81 | 82 | uint8_t endTransmission(bool sendStop); 83 | uint8_t endTransmission(void); 84 | 85 | uint8_t requestFrom(uint8_t address, uint8_t quantity, bool sendStop); 86 | uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop); 87 | uint8_t requestFrom(uint8_t address, uint8_t quantity); 88 | uint8_t requestFrom(int address, int quantity, bool sendStop); 89 | uint8_t requestFrom(int address, int quantity, int sendStop); 90 | uint8_t requestFrom(int address, int quantity); 91 | virtual int available(void); 92 | virtual int read(void); 93 | 94 | virtual int peek(void); 95 | void flushRX(void); 96 | void flushTX(void); 97 | virtual void flush(void); 98 | uint8_t status(void); 99 | 100 | void onReceive(void (*)(int)); 101 | void onRequest(void (*)(void)); 102 | 103 | private: 104 | static uint8_t _rxBuffer[]; 105 | static uint8_t _rxBufferIndex; 106 | static uint8_t _rxBufferLength; 107 | 108 | static uint8_t _txBuffer[]; 109 | static uint8_t _txAddress; 110 | static uint8_t _txBufferIndex; 111 | static uint8_t _txBufferLength; 112 | static bool _transmitting; 113 | 114 | static void onReceiveService(uint8_t *inBytes, int numBytes); 115 | static void onRequestService(void); 116 | static void (*user_onRequest)(void); 117 | static void (*user_onReceive)(int); 118 | }; 119 | 120 | #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_TWOWIRE) 121 | extern TwoWire Wire; 122 | #endif 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /Wire/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Wire 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | beginTransmission KEYWORD2 14 | setClock KEYWORD2 15 | setClockStretchLimit KEYWORD2 16 | beginTransmission KEYWORD2 17 | write KEYWORD2 18 | endTransmission KEYWORD2 19 | requestFrom KEYWORD2 20 | available KEYWORD2 21 | read KEYWORD2 22 | peek KEYWORD2 23 | flush KEYWORD2 24 | status KEYWORD2 25 | onReceive KEYWORD2 26 | onRequest KEYWORD2 27 | 28 | ####################################### 29 | # Instances (KEYWORD2) 30 | ####################################### 31 | 32 | Wire KEYWORD2 33 | 34 | ####################################### 35 | # Constants (LITERAL1) 36 | ####################################### 37 | 38 | TWI_I2C_BUFFER_LENGTH LITERAL1 39 | TWI_I2C_DISABLE_INTERRUPTS LITERAL1 40 | -------------------------------------------------------------------------------- /Wire/library.properties: -------------------------------------------------------------------------------- 1 | name = Wire, I²C master 2 | version = 1.0 3 | author = Arduino 4 | maintainer = Ivan Grokhotkov 5 | sentence = Allows communication between ESP8266 & devices via TWI/I²C Bus 6 | paragraph = Allows communication between master ESP8266 & slave devices via TWI/I²C Bus 7 | category = Signal Input/Output 8 | url = http://arduino.cc/en/Reference/Wire 9 | architectures = esp8266 10 | dot_a_linkage = true 11 | -------------------------------------------------------------------------------- /esp8266/core_esp8266_si2c.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************************/ 2 | /* 3 | si2c.h - Software/bit-bang master I²C library for ESP8266 Arduino 4 | 5 | Modified 2019 by enjoyneering79, source code: https://github.com/enjoyneering/ 6 | 7 | Specials pins are required: 8 | Board: SDA SCL Level 9 | ESP8266................................... GPIO4 GPIO5 3.3v/5v 10 | ESP8266 ESP-01............................ GPIO0/D5 GPIO2/D3 3.3v/5v 11 | NodeMCU 1.0, WeMos D1 Mini................ GPIO4/D2 GPIO5/D1 3.3v/5v 12 | 13 | Copyright (c) 2015 Hristo Gochkov. All rights reserved. 14 | This file is part of the esp8266 core for Arduino environment. 15 | 16 | This library is free software; you can redistribute it and/or 17 | modify it under the terms of the GNU Lesser General Public 18 | License as published by the Free Software Foundation; either 19 | version 2.1 of the License, or (at your option) any later version. 20 | 21 | This library is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 | Lesser General Public License for more details. 25 | 26 | You should have received a copy of the GNU Lesser General Public 27 | License along with this library; if not, write to the Free Software 28 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 29 | */ 30 | /**************************************************************************************/ 31 | 32 | #include "twi.h" 33 | #include "pins_arduino.h" 34 | #include "wiring_private.h" 35 | 36 | extern "C" 37 | { 38 | 39 | #ifndef FCPU80 40 | #define FCPU80 80000000UL 41 | #endif 42 | 43 | #if F_CPU == FCPU80 44 | #define TWI_CLOCK_STRETCH_MULTIPLIER 3 45 | #else 46 | #define TWI_CLOCK_STRETCH_MULTIPLIER 6 47 | #endif 48 | 49 | #define SDA_LOW() (GPES = (1 << twi_sda)) //enable SDA, pins becomes OUTPUT & since GPO is 0 for the pin it will pull line low 50 | #define SDA_HIGH() (GPEC = (1 << twi_sda)) //disable SDA, pins becomes INPUT_PULLUP & since it has 30kOhm..100kOhm pullup it will go high 51 | #define SDA_READ() ((GPI & (1 << twi_sda)) != 0) 52 | #define SCL_LOW() (GPES = (1 << twi_scl)) 53 | #define SCL_HIGH() (GPEC = (1 << twi_scl)) 54 | #define SCL_READ() ((GPI & (1 << twi_scl)) != 0) 55 | 56 | static uint8_t twi_sda = 0; //sda pin 57 | static uint8_t twi_scl = 0; //scl pin 58 | static uint32_t twi_clockStretchLimit = 0; 59 | int16_t twi_dcount = 0; 60 | uint32_t preferred_si2c_clock = TWI_I2C_DEFAULT_CLOCK; //100kHz 61 | 62 | static bool collision = false; //shows if bit was successfully read by slave 63 | 64 | /**************************************************************************/ 65 | /* 66 | twi_setClock() 67 | 68 | Sets I2C clock speed 69 | */ 70 | /**************************************************************************/ 71 | void twi_setClock(uint32_t freq) 72 | { 73 | preferred_si2c_clock = freq; 74 | 75 | #if F_CPU == FCPU80 76 | if (freq <= 10000) twi_dcount = 220; //~10KHz 77 | else if (freq <= 15000) twi_dcount = 145; //~15KHz 78 | else if (freq <= 25000) twi_dcount = 87; //~25KHz 79 | else if (freq <= 50000) twi_dcount = 42; //~50KHz 80 | else if (freq <= 100000) twi_dcount = 19; //~100KHz 81 | else if (freq <= 200000) twi_dcount = 9; //~200KHz 82 | else if (freq <= 250000) twi_dcount = 6; //~250KHz 83 | else if (freq <= 300000) twi_dcount = 5; //~300KHz 84 | else if (freq <= 400000) twi_dcount = 3; //~400KHz 85 | else twi_dcount = 3; //~400KHz 86 | #else 87 | if (freq <= 10000) twi_dcount = 350; //~10KHz 88 | else if (freq <= 15000) twi_dcount = 240; //~15KHz 89 | else if (freq <= 25000) twi_dcount = 140; //~25KHz 90 | else if (freq <= 50000) twi_dcount = 70; //~50KHz 91 | else if (freq <= 100000) twi_dcount = 32; //~100KHz 92 | else if (freq <= 200000) twi_dcount = 16; //~200KHz 93 | else if (freq <= 250000) twi_dcount = 14; //~250KHz 94 | else if (freq <= 300000) twi_dcount = 11; //~300KHz 95 | else if (freq <= 400000) twi_dcount = 8; //~400KHz 96 | else if (freq <= 500000) twi_dcount = 6; //~500KHz 97 | else if (freq <= 600000) twi_dcount = 5; //~600KHz 98 | else twi_dcount = 4; //~700KHz 99 | #endif 100 | } 101 | 102 | /**************************************************************************/ 103 | /* 104 | twi_setClockStretchLimit 105 | 106 | Sets SCL maximum stretch time, in μs 107 | 108 | NOTE: 109 | - default stretch SCL limit 1250 μsec or 0.8KHz 110 | */ 111 | /**************************************************************************/ 112 | void twi_setClockStretchLimit(uint32_t limit) 113 | { 114 | twi_clockStretchLimit = limit * TWI_CLOCK_STRETCH_MULTIPLIER; 115 | } 116 | 117 | /**************************************************************************/ 118 | /* 119 | twi_delay 120 | */ 121 | /**************************************************************************/ 122 | static void twi_delay(int16_t value) 123 | { 124 | if (value < 1) value = twi_dcount; //to avoid nagative values 125 | 126 | #pragma GCC diagnostic push 127 | #pragma GCC diagnostic ignored "-Wunused-but-set-variable" 128 | 129 | uint16_t reg = 0; 130 | 131 | for (uint16_t i = 0; i < value; i++) reg = GPI; //read input level 132 | 133 | (void)reg; 134 | 135 | #pragma GCC diagnostic pop 136 | } 137 | 138 | /**************************************************************************/ 139 | /* 140 | clockStretch() 141 | 142 | Checks for SCL locked low by slave 143 | 144 | NOTE: 145 | - when the slave cannot follow the master, it blocks the SCL line at 146 | LOW level, this is a sign that slave needs more time 147 | - master slow down SCL by extending each clock LOW period 148 | - default stretch SCL limit 1250 μsec or 0.8KHz 149 | - clock stretching can change I2C speed from 0Hz to max kHz 150 | */ 151 | /**************************************************************************/ 152 | static bool clockStretch(void) 153 | { 154 | if (twi_clockStretchLimit != 0) //value, limited clock stretching 155 | { 156 | int32_t pollCounter = twi_clockStretchLimit; 157 | 158 | while (SCL_READ() == LOW) 159 | { 160 | if (pollCounter-- < 0) return false; //error handler, ERROR - SCL locked!!! 161 | } 162 | } 163 | else //no value, infinite clock stretching 164 | { 165 | while (SCL_READ() == LOW) 166 | { 167 | yield(); //can slow down up to 0Hz & block SCL line forever 168 | } 169 | } 170 | 171 | return true; //SCL released!!! 172 | } 173 | 174 | /**************************************************************************/ 175 | /* 176 | freeBus() 177 | 178 | Dirty hack to release I2C bus if slave locked SDA low 179 | 180 | NOTE: 181 | - i2c bus status reply: 182 | - I2C_SDA_HELD_LOW 1, SDA held low by another device, no procedure available to recover 183 | - I2C_SCL_HELD_LOW_AFTER_READ 4, SCL held low beyond slave clock stretch time, increase stretch time 184 | - I2C_SDA_OK 5, SDA free 185 | - I2C_SDA_RELEASED 6, SDA released after use by another device 186 | - if SDA stuck LOW, the master should send 9 clock pulses. The device 187 | that held the bus LOW should release it sometime within those 9 clocks. 188 | If not, then use the MCU HW reset or cycle power to clear the bus 189 | - see Analog Device application note AN-686 for more details 190 | - bus frequency is equal to first SCL = 1 / (tLOW + tHIGH), 191 | SCL = 1 / (4.7μsec + 4.0μsec) = 115kHz 192 | - see NXP UM10204 p.48 and p.50 for timing details 193 | */ 194 | /**************************************************************************/ 195 | static uint8_t freeBus(void) 196 | { 197 | if (SDA_READ() == HIGH) return I2C_SDA_OK; //SDA is free 198 | 199 | int8_t pollCounter = TWI_I2C_SDA_POLLING_LIMIT; 200 | 201 | /* SDA is low, I2C bus is locked */ 202 | while (SDA_READ() == LOW) 203 | { 204 | if (pollCounter-- < 0) return I2C_SDA_HELD_LOW; //error handler, ERROR - SDA busy!!! 205 | 206 | SCL_LOW(); //becomes OUTPUT & pulls line LOW 207 | twi_delay(twi_dcount - 3); //tLOW >= 4.7μsec is LOW period of the SCL 208 | 209 | SCL_HIGH(); //release the SCL bus, so we can read a bit or ack/nack answer from slave 210 | if (clockStretch() != true) return I2C_SCL_HELD_LOW_AFTER_READ; //stretching the clock slave is buuuuuusy, ERROR - SCL busy!!! 211 | twi_delay(twi_dcount - 3); //tHIGH >= 4.0μsec is HIGH period of the SCL 212 | } 213 | 214 | return I2C_SDA_RELEASED; //SDA released!!! 215 | } 216 | 217 | /**************************************************************************/ 218 | /* 219 | twi_write_stop() 220 | 221 | Sends stop pulse, returns != I2C_OK if SCL busy 222 | 223 | NOTE: 224 | - STOP conditions are always generated by the master 225 | - bus is free only after the STOP condition 226 | - see TI SLVA704 fig.5 on p.4 for more details 227 | - see NXP UM10204 p.48 and p.50 for timing details 228 | */ 229 | /**************************************************************************/ 230 | static bool twi_write_stop(void) 231 | { 232 | /* start SCL & SDA routine */ 233 | SCL_LOW(); //becomes OUTPUT & pulls line LOW, SCL FIRST DO NOT TOUCH 234 | SDA_LOW(); //becomes OUTPUT & pulls line LOW 235 | twi_delay(twi_dcount - 3); //tLOW >= 4.7μsec is LOW period of the SCL, measured 5.083μsec 236 | 237 | /* continue SCL routine */ 238 | SCL_HIGH(); //release the SCL line, becomes INPUT_PULLUP & pulls line high 239 | if (clockStretch() != true) return ~I2C_OK; //stretching the clock slave is buuuuuusy, ERROR - SCL busy!!! 240 | twi_delay(twi_dcount - 5); //tSU;STO >= 4.0μsec is set-up time for STOP condition, measured 4.458μsec 241 | 242 | /*continue SDA routine */ 243 | SDA_HIGH(); //finish the STOP by releasing SDA line 244 | 245 | return I2C_OK; //success!!! 246 | } 247 | 248 | /**************************************************************************/ 249 | /* 250 | twi_write_start() 251 | 252 | Sends start pulse & returns false if SCL or SDA is busy 253 | 254 | NOTE: 255 | - START conditions are always generated by the master 256 | - bus is considered to be busy after the START condition 257 | - see TI SLVA704 fig.5 on p.4 for more details 258 | - see NXP UM10204 p.48 and p.50 for timing details 259 | */ 260 | /**************************************************************************/ 261 | static bool twi_write_start(void) 262 | { 263 | /* start SCL & SDA routine */ 264 | SCL_HIGH(); //becomes INPUT_PULLUP & pulls line high, SCL FIRST DO NOT TOUCH 265 | SDA_HIGH(); //becomes INPUT_PULLUP & pulls line high 266 | twi_delay(twi_dcount - 18); //tSU;STA & tBUF >= 4.7μsec is bus free time between STOP & START condition, measured 5.125μsec 267 | 268 | /* check if SDA line is blocked */ 269 | switch (freeBus()) //dirty hack to release locked SDA line 270 | { 271 | case I2C_SDA_RELEASED: 272 | twi_write_stop(); //always use stop after start/unfinished read 273 | 274 | SCL_HIGH(); //becomes INPUT_PULLUP & pulls line high, SCL FIRST DO NOT TOUCH 275 | SDA_HIGH(); //becomes INPUT_PULLUP & pulls line high 276 | twi_delay(twi_dcount - 18); //tSU;STA & tBUF >= 4.7μsec is bus free time between STOP & START condition, measured 5.125μsec 277 | break; 278 | 279 | case I2C_SDA_HELD_LOW: 280 | case I2C_SCL_HELD_LOW_AFTER_READ: 281 | return ~I2C_OK; //fail to release locked SDA line or stretch time is too short 282 | break; 283 | } 284 | 285 | /* continue SCL & SDA routine */ 286 | SDA_LOW(); //becomes OUTPUT & pulls line LOW 287 | twi_delay(twi_dcount - 1); //tHD;STA >= 4.0μsec is START hold time, measured 4.416μsec 288 | SCL_LOW(); 289 | 290 | return I2C_OK; //success!!! 291 | } 292 | 293 | /**************************************************************************/ 294 | /* 295 | twi_init 296 | 297 | Initialisation of software/bit-bang master I2C bus protocol 298 | 299 | NOTE: 300 | - normaly I2C bus drivers are "open drain", meaning that they can pull the 301 | corresponding signal line low, but cannot drive it high. Thus, there can 302 | be no bus contention where one device is trying to drive the line high 303 | while another tries to pull it low, eliminating the potential for damage 304 | to the drivers or excessive power dissipation in the system. Each signal 305 | line has a pull-up resistor on it, to restore the signal to high when no 306 | device is asserting it low 307 | - however this driver used INPUT_PULLUP, because people forgetting about 308 | external pull up resistors, so the code has changed a bit recently. 309 | Instead of changing pin output register when banging the bits, we now 310 | change pin mode register. The pin is switched between INPUT_PULLUP & 311 | OUTPUT modes, which makes it either a weak pull up or a strong pull down 312 | (output register has 0 written into it in advance) 313 | */ 314 | /**************************************************************************/ 315 | void twi_init(uint8_t sda, uint8_t scl) 316 | { 317 | twi_sda = sda; 318 | twi_scl = scl; 319 | 320 | SCL_HIGH(); //becomes INPUT_PULLUP & pulls line high 321 | SDA_HIGH(); //becomes INPUT_PULLUP & pulls line high 322 | delay(20); //some slave needs > 15msec to reach the idle state 323 | 324 | twi_setClock(preferred_si2c_clock); //~100KHz, by default 325 | twi_setClockStretchLimit(); //set stretch SCL limit, in μsec 326 | 327 | if (freeBus() == I2C_SDA_RELEASED) twi_write_stop(); //dirty hack to release locked SDA line, always use stop after start/unfinished read 328 | } 329 | 330 | /**************************************************************************/ 331 | /* 332 | twi_write_bit() 333 | 334 | Writes a bit, returns != I2C_OK if SCL busy 335 | 336 | NOTE: 337 | - data is stable and valid for read when SCL line is HIGH 338 | - the HIGH or LOW state of the SDA line can only change when the SCL 339 | line is LOW, one clock pulse is generated for each data bit transferred 340 | - if a slave cannot receive or transmit another complete byte of data it 341 | can hold the clock line SCL LOW to force the master into a wait state, 342 | data transfer continues when the slave is ready for another byte of 343 | data and releases clock line SCL 344 | - see TI SLVA704, fig.6 on p.5 345 | - see NXP UM10204 p.48 and p.50 for timing details 346 | */ 347 | /**************************************************************************/ 348 | static bool twi_write_bit(bool txBit) 349 | { 350 | /* start SCL routine */ 351 | SCL_LOW(); 352 | twi_delay(twi_dcount - 5); //tLOW >= 4.7μsec is LOW period of the SCL, measured 5.083μsec 353 | 354 | /* start SDA routine, set the bit */ 355 | switch (txBit) 356 | { 357 | case HIGH: 358 | SDA_HIGH(); //becomes INPUT_PULLUP & pulls line high 359 | break; 360 | 361 | case LOW: 362 | SDA_LOW(); //becomes OUTPUT & pulls line LOW 363 | break; 364 | } 365 | twi_delay(1); //tSU;DAT > 3.45μsec is data set-up time, measured 4.458μsec 366 | 367 | /* continue SCL routine, bit is valid for read */ 368 | SCL_HIGH(); //try to release the SCL line, becomes INPUT_PULLUP & pulls line high 369 | if (clockStretch() == false) return ~I2C_OK; //stretching the clock slave is buuuuuusy, ERROR - SCL busy!!! 370 | twi_delay(twi_dcount - 5); //tHIGH >= 4.0μsec is HIGH period of the SCL, measured 4.417μsec 371 | SCL_LOW(); 372 | 373 | return I2C_OK; //success!!! 374 | } 375 | 376 | /**************************************************************************/ 377 | /* 378 | twi_read_bit() 379 | 380 | Reads a bit or NACK/ACK(1/0) if SCL busy 381 | 382 | NOTE: 383 | - data is stable and valid for read when SCL line is HIGH 384 | - the HIGH or LOW state of the SDA line can only change when the SCL 385 | line is LOW, one clock pulse is generated for each data bit transferred 386 | - if a slave cannot receive or transmit another complete byte of data it 387 | can hold the clock line SCL LOW to force the master into a wait state, 388 | data transfer continues when the slave is ready for another byte of 389 | data and releases clock line SCL 390 | - when SDA remains HIGH during this 9-th clock pulse, this is defined 391 | as the Not Acknowledge signal. The master can then generate either a 392 | STOP condition to abort the transfer, or a repeated START condition 393 | to start a new transfer. There are five conditions that lead to the 394 | generation of a NACK 395 | - see TI SLVA704, fig.6 on p.5 or NXP UM10204, fig.4 on p.9 for more details 396 | - see NXP UM10204 p.48 and p.50 for timing details 397 | */ 398 | /**************************************************************************/ 399 | static uint8_t twi_read_bit(void) 400 | { 401 | bool rxBit = 0; 402 | 403 | /* start SCL & SDA routine */ 404 | SCL_LOW(); //becomes OUTPUT & pulls line LOW 405 | twi_delay(twi_dcount - 3); //tLOW >= 4.7μsec is LOW period of the SCL, measured 5.083μsec 406 | 407 | /* continue SCL routine */ 408 | SDA_HIGH(); //release the SDA line, so slave can send bit or ack/nack answer 409 | SCL_HIGH(); //release the SCL line, so we can read a bit or ack/nack answer from slave 410 | if (clockStretch() == false) return I2C_SCL_HELD_LOW; //returns 3 411 | 412 | /* continue SDA routine, read the data */ 413 | rxBit = SDA_READ(); //read 7..0 data bit or 8-th NACK/ACK = 1/0 bit, 9 bits in total 414 | twi_delay(twi_dcount - 6); //tHIGH >= 4.0μsec is HIGH period of the SCL, measured 4.417μsec 415 | switch (rxBit) //during "twi_write_byte()" removes spike after reading 9-th NACK/ACK bit 416 | { 417 | case HIGH: 418 | SDA_HIGH(); 419 | break; 420 | 421 | case LOW: 422 | SDA_LOW(); 423 | break; 424 | } 425 | SCL_LOW(); 426 | 427 | return rxBit; //return bit!!! 428 | } 429 | 430 | /**************************************************************************/ 431 | /* 432 | twi_write_byte() 433 | 434 | Write a byte, returns ACK/NACK 435 | 436 | NOTE: 437 | - data is transferred with the most significant bit (MSB) first 438 | - when SDA remains HIGH during this 9-th clock pulse, this is defined 439 | as NACK (Not Acknowledge). The master can then generate either a 440 | STOP condition to abort the transfer, or a repeated START condition 441 | to start a new transfer 442 | - see NXP UM10204 p.48 and p.50 for timing details 443 | */ 444 | /**************************************************************************/ 445 | static bool twi_write_byte(uint8_t txByte) 446 | { 447 | /* write the byte, in order MSB->LSB (7..0 bit) */ 448 | for (int8_t i = 7; i >= 0; i--) 449 | { 450 | if (twi_write_bit(bitRead(txByte, i)) != I2C_OK) return TWI_I2C_NACK; //write one byte in order MSB->LSB (7..0 bit), ERROR - NACK!!! 451 | } 452 | 453 | if (twi_read_bit() == TWI_I2C_ACK) return TWI_I2C_ACK; //reads 9-th bit NACK/ACK 454 | return TWI_I2C_NACK; 455 | } 456 | 457 | /**************************************************************************/ 458 | /* 459 | twi_read_byte() 460 | 461 | Reads a byte & sends NACK/ACK after 462 | 463 | NOTE: 464 | - data is transferred with the most significant bit (MSB) first 465 | - when SDA remains HIGH during this 9-th clock pulse, this is defined 466 | as NACK (Not Acknowledge). The master can then generate either a 467 | STOP condition to abort the transfer, or a repeated START condition 468 | to start a new transfer 469 | - 1 is NACK 470 | - 0 is ACK 471 | */ 472 | /**************************************************************************/ 473 | static uint8_t twi_read_byte(bool ack_nack) 474 | { 475 | uint8_t rxByte = 0; 476 | uint8_t rxBit = 0; 477 | 478 | /* read the byte, in order MSB->LSB (7..0 bit) */ 479 | for (uint8_t i = 0; i < 8; i++) 480 | { 481 | rxBit = twi_read_bit(); 482 | 483 | switch (rxBit) 484 | { 485 | case HIGH: 486 | rxByte = (rxByte << 1) | rxBit; 487 | break; 488 | 489 | case LOW: 490 | rxByte = rxByte << 1; 491 | break; 492 | 493 | case I2C_SCL_HELD_LOW: 494 | collision = true; //SCL busy!!! 495 | return 0; 496 | break; 497 | } 498 | } 499 | 500 | /* write 9-th NACK/ACK bit */ 501 | if (twi_write_bit(ack_nack) != I2C_OK) 502 | { 503 | collision = true; //SCL busy!!! 504 | return 0; 505 | } 506 | 507 | collision = false; 508 | return rxByte; //return byte!!! 509 | } 510 | 511 | /**************************************************************************/ 512 | /* 513 | twi_writeTo() 514 | 515 | Fills in txBuffer & returns code 516 | 517 | NOTE: 518 | - byte is transferred with the most significant bit (MSB) first 519 | - see NXP UM10204 p.15 for details 520 | - default tx buffer size 32 bytes, see Wire.h 521 | 522 | Returned codes: 523 | 0 - success 524 | 1 - data too long to fit in transmit data16 525 | 2 - received NACK on transmit of address 526 | 3 - received NACK on transmit of data 527 | 4 - line is busy 528 | */ 529 | /**************************************************************************/ 530 | uint8_t twi_writeTo(uint8_t address, uint8_t *buffer, uint8_t length, bool sendStop) 531 | { 532 | /* send start */ 533 | if (twi_write_start() != I2C_OK) return 4; //line is busy!!! 534 | 535 | /* write address */ 536 | if (twi_write_byte(address << 1) != TWI_I2C_ACK) //address is seven bits long followed by eighth data direction bit, "0" indicates WRITE 537 | { 538 | twi_write_stop(); //always use stop after "twi_write_start()" 539 | 540 | return 2; //error, received NACK during address transmission!!! 541 | } 542 | 543 | /* write n bytes */ 544 | for(uint8_t i = 0; i < length; i++) 545 | { 546 | if (twi_write_byte(buffer[i]) != TWI_I2C_ACK) //error handler 547 | { 548 | twi_write_stop(); //always use stop after "twi_write_start()" 549 | 550 | return 3; //error, received NACK during data transmission!!! 551 | } 552 | } 553 | 554 | /* send stop */ 555 | if (sendStop == true) twi_write_stop(); 556 | 557 | return 0; //success!!! 558 | } 559 | 560 | /**************************************************************************/ 561 | /* 562 | twi_readFrom() 563 | 564 | Fills in rxBuffer & returns qnt of received bytes or 0 if bus error 565 | 566 | NOTE: 567 | - byte is transferred with the most significant bit (MSB) first 568 | - if master sets SDA HIGH during this 9-th clock pulse, this is 569 | defined as NACK (Not Acknowledge). The master generate STOP condition 570 | to abort the transfer 571 | - if master sets SDA LOW during this 9-th clock pulse, this is defined 572 | as ACK (Acknowledge). The master generate REPEATE START condition to 573 | start a new transfer. 574 | - regardless of the number of start conditions during one transfer 575 | the transfer must be ended by exactly one stop condition followed 576 | by NACK. 577 | - see NXP UM10204 p.15 for details 578 | - default rx buffer size 32-bytes, see Wire.h 579 | */ 580 | /**************************************************************************/ 581 | uint8_t twi_readFrom(uint8_t address, uint8_t *buffer, uint8_t length, bool sendStop) 582 | { 583 | length = length - 1; //buffer array starts from zero, zero length safety check is in Wire library 584 | 585 | /* send start */ 586 | if (twi_write_start() != I2C_OK) return 0; //error, line is busy!!! 587 | 588 | /* write address */ 589 | if (twi_write_byte((address << 1) | 0x01) != TWI_I2C_ACK) //address is seven bits long followed by eighth data direction bit, "1" indicates READ 590 | { 591 | twi_write_stop(); //always use stop after "twi_write_start()" 592 | 593 | return 0; //error, received NACK during address transmition!!! 594 | } 595 | 596 | /* read n - 1 bytes from slave, except last one */ 597 | for (uint8_t i = 0; i < length; i++) 598 | { 599 | buffer[i] = twi_read_byte(TWI_I2C_ACK); //sends ACK, assuming byte successfully received, let slave send another one 600 | 601 | if (collision == true) //error reading byte from slave 602 | { 603 | twi_write_stop(); //always use stop after "twi_write_start()" 604 | 605 | return i; //return qnt of successfully received bytes 606 | } 607 | } 608 | 609 | /* check "repeated START" conditions & read last byte */ 610 | switch (sendStop) 611 | { 612 | case HIGH: 613 | buffer[length] = twi_read_byte(TWI_I2C_NACK); //always sends NACK before stop 614 | twi_write_stop(); 615 | break; 616 | 617 | case LOW: 618 | buffer[length] = twi_read_byte(TWI_I2C_ACK); //sends ACK, signal for "repeated START" 619 | break; 620 | } 621 | 622 | if (collision == true) //error reading last byte from slave 623 | { 624 | if (sendStop == LOW) twi_write_stop(); //always use stop after "twi_write_start()" 625 | 626 | return 0; 627 | } 628 | 629 | return length + 1; //all bytes were successfully received 630 | } 631 | 632 | /**************************************************************************/ 633 | /* 634 | twi_status() 635 | 636 | 637 | NOTE: 638 | - returned code: 639 | - I2C_OK 0, OK 640 | - I2C_SDA_HELD_LOW 1, SDA held low by another device, no procedure available to recover 641 | - I2C_SDA_HELD_LOW_AFTER_INIT 2, SDA held low beyond slave clock stretch time, increase stretch time 642 | - I2C_SCL_HELD_LOW 3, SCL held low by another device, no procedure available to recover 643 | - I2C_SCL_HELD_LOW_AFTER_READ 4, SCL held low beyond slave clock stretch time, increase stretch time 644 | */ 645 | /**************************************************************************/ 646 | uint8_t twi_status() 647 | { 648 | if (twi_write_start() != I2C_OK) return I2C_SDA_HELD_LOW_AFTER_INIT; 649 | if (twi_write_stop() != I2C_OK) return I2C_SCL_HELD_LOW_AFTER_READ; 650 | if (SDA_READ() == LOW) return I2C_SDA_HELD_LOW; 651 | if (SCL_READ() == LOW) return I2C_SCL_HELD_LOW; 652 | return I2C_OK; 653 | } 654 | 655 | }; 656 | -------------------------------------------------------------------------------- /esp8266/twi.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************/ 2 | /* 3 | twi.h - Software/bit-bang master I²C library for ESP8266 Arduino 4 | 5 | Modified 2019 by enjoyneering79, source code: https://github.com/enjoyneering/ 6 | 7 | Specials pins are required: 8 | Board: SDA SCL Level 9 | ESP8266................................... GPIO4 GPIO5 3.3v/5v 10 | ESP8266 ESP-01............................ GPIO0/D5 GPIO2/D3 3.3v/5v 11 | NodeMCU 1.0, WeMos D1 Mini................ GPIO4/D2 GPIO5/D1 3.3v/5v 12 | 13 | Copyright (c) 2015 Hristo Gochkov. All rights reserved. 14 | This file is part of the esp8266 core for Arduino environment. 15 | 16 | This library is free software; you can redistribute it and/or 17 | modify it under the terms of the GNU Lesser General Public 18 | License as published by the Free Software Foundation; either 19 | version 2.1 of the License, or (at your option) any later version. 20 | 21 | This library is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 | Lesser General Public License for more details. 25 | 26 | You should have received a copy of the GNU Lesser General Public 27 | License along with this library; if not, write to the Free Software 28 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 29 | */ 30 | /**************************************************************************************/ 31 | 32 | #ifndef SI2C_h 33 | #define SI2C_h 34 | 35 | #include "Arduino.h" 36 | 37 | #ifdef __cplusplus 38 | extern "C" 39 | { 40 | #endif 41 | 42 | #define TWI_I2C_DEFAULT_CLOCK 100000 //default I2C speed, in Hz 43 | #define TWI_I2C_SCL_STRCH_LIMIT 1250 //maximum SCL stretch time, in μsec 44 | #define TWI_I2C_SDA_POLLING_LIMIT 20 //maximum number of SCL pulses to release I2C bus if slave blocked SDA low 45 | 46 | #define TWI_I2C_NACK HIGH //1 47 | #define TWI_I2C_ACK LOW //0 48 | 49 | #define I2C_OK 0 //bus OK 50 | #define I2C_SDA_HELD_LOW 1 //SDA held low by another device, no procedure available to recover 51 | #define I2C_SDA_HELD_LOW_AFTER_INIT 2 //SDA held low beyond slave clock stretch time 52 | #define I2C_SCL_HELD_LOW 3 //SCL held low by another device, no procedure available to recover 53 | #define I2C_SCL_HELD_LOW_AFTER_READ 4 //SCL held low beyond slave clock stretch time 54 | 55 | #define I2C_SDA_OK 5 //SDA free 56 | #define I2C_SDA_RELEASED 6 //SDA released after use by another device 57 | 58 | 59 | void twi_init(uint8_t sda, uint8_t scl); 60 | void twi_setClock(uint32_t freq); 61 | void twi_setClockStretchLimit(uint32_t limit = TWI_I2C_SCL_STRCH_LIMIT); 62 | uint8_t twi_writeTo(uint8_t address, uint8_t *buffer, uint8_t length, bool sendStop); 63 | uint8_t twi_readFrom(uint8_t address, uint8_t *buffer, uint8_t length, bool sendStop); 64 | uint8_t twi_status(); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif 71 | --------------------------------------------------------------------------------