Brzo I2C
===================
Brzo i2c implements an i2c master and is written in assembly language for the esp8266. The core features are:

 - Fast mode plus speeds 
	 - 800 KHz @ 80 MHz CPU frequency
	 - 1 MHz @ 160 MHz CPU frequency
 - Precise timing for SCL and SDA, including removal of spikes
 - i2c transactions: Group any combination of i2c writes or reads together, either with or without repeated start.

For further information you may refer to the [wiki](https://github.com/pasko-zh/brzo_i2c/wiki)

HW and Tool Chain Support
-------

 - Brzo i2c supports **only** esp8266 modules because it is implented in Xtensa assembly language.
 - The code is tested for the Arduino tool chain 
 - And thanks to **valkuc** it works for the native tool chain, too! Make sure to use the correct [compiler flags](https://github.com/pasko-zh/brzo_i2c/issues/9#issuecomment-247020598).
 - Tested Arduino versions:
	 - ESP8266 Arduino Core 2.4.1
	 - ESP8266 Arduino Core 2.3.0
	 - ESP8266 Arduino Core 2.2.0
	 - ESP8266 Arduino Core 2.1.0
 - Tested Native SDK versions:
 	 - SDK Version 3.0.1
	 - SDK Version 2.0.0	

Brzo i2c was tested with several i2c devices. If you find one which is not working, please open an issue.

**NOTE for AM2320 Sensor: The wake-up sequence is not compatible with `brzo_i2c`, see analysis [here](https://github.com/pasko-zh/brzo_i2c/issues/33#issuecomment-460065731)**

How to install the Brzo I2C Library
-------

 - Use the Library Manager: 
	 - If you are using the ArduinoIDE, you can install via library manager
	 - If you are developing with [PlatformIO](http://platformio.org/) then simply use the library manager to install [brzo_i2c](http://platformio.org/lib/show/335/Brzo%20I2C)

 - Pull it from github

And then just include brzo_i2c in your sketch as any other library with `#include "brzo_i2c.h"`. 


Disabling or enabling Interrupts during i2c reads or writes
-------

In [brzo_i2c.h](https://github.com/pasko-zh/brzo_i2c/blob/master/brzo_i2c.h#L29) you can set the behaviour how interrupts during i2c reads or writes are handled: Setting `BRZO_I2C_DISABLE_INTERRUPTS` to `1` will *disable* all interrupts during i2c read or writes. The default is *all interrupts are disabled*. For further information about disabling or enabling interrupts refer to the [wiki](https://github.com/pasko-zh/brzo_i2c/wiki)


I2C Setup
----------------

To setup the i2c bus you need to call at least once `brzo_i2c_setup`.  

`brzo_i2c_setup(uint8_t sda, uint8_t scl, uint32_t clock_stretch_time_out_usec)`.  
Input

 - The number of your SDA Pin
 - The number of your SCL Pin
 - The timeout for an i2c slave clock stretch in micro seconds. **Be careful when using i2c devices with a very long clock stretching, please read the [wiki](https://github.com/pasko-zh/brzo_i2c/wiki#i2c-setup-and-clock-stretching).**

Returns

 - None
 
Example:
`brzo_i2c_setup(5, 12, 200);`

I2C Transactions
----------------

The motivation for i2c transactions is found on the [wiki](https://github.com/pasko-zh/brzo_i2c/wiki#i2c-transactions). An i2c transactions always begins with `brzo_i2c_start_transaction` and ends with `brzo_i2c_end_transaction`.  Within a transaction you can combine any number i2c commands with or without a repeated start, i.e. `brzo_i2c_write` or `brzo_i2c_read`. 
A transaction is bound to one i2c slave and all commands are executed at the same SCL speed. Thus, brzo_i2c_start_transaction takes the slave address and SCL speed in KHz as input parameters.

**Begin a transaction**

`brzo_i2c_start_transaction(uint8_t slave_address, uint16_t SCL_frequency_KHz)`

Input

 - I2c slave address (7 bit encoded)
 - SCL speed to be used for the entire transaction in KHz (SCL speed is rounded to the next 100-level, e.g., 651 will be rounded up to 700)


Returns

 - None

Example: Start a transaction to an i2c slave at 0x20 with 1 MHz SCL speed.
`brzo_i2c_start_transaction(0x20, 1000);`


**End a Transaction**

`uint8_t brzo_i2c_end_transaction()`

> **Note:** 
> - The last i2c command before calling `brzo_i2c_end_transaction()` must not contain a repeated start, therefore use `brzo_i2c_read/write(.., .., false)` to send a STOP sequence instead of another repeated START.
> - Refer to the [i2c specification](http://www.i2c-bus.org/repeated-start-condition) about repeated starts and how to "end" them

Input

 - None
 
Returns

- 0 : All i2c commands were executed without errors
- errors
	 - 1 : Bus not free, i.e. either SDA or SCL is low
	 - 2 : Not ACK ("NACK") by slave during write: Either the slave did not respond to the given slave address; or the slave did not ACK a byte transferred by the master.
	 - 4 : Not ACK ("NACK") by slave during read, i.e. slave did not respond to the given slave address
	 - 8 : Clock Stretching by slave exceeded maximum clock stretching time. Most probably, there is a bus stall now!
	 - 16 : Read was called with 0 bytes to be read by the master. Command not sent to the slave, since this could yield to a bus stall
	 - 32 : ACK Polling timeout exceeded 

I2C Commands
----------------

The following i2c commands shall only be used within a transaction!

**I2C write**

`brzo_i2c_write(uint8_t *data, uint8_t no_of_bytes, boolean repeated_start)`

> **Note:** 
> - You can only call `brzo_i2c_write` inside a transaction!
> - Of course, there is error checking inside the write command. However, errors are only reported at the end of a transaction. 


Input

 - A pointer to an array of bytes: Either use the base address, e.g., `brzo_i2c_write(buffer, 2, ..)` or use the address of a specific array element, e.g. `brzo_i2c_write(&buffer[4], 2, ..);`. The former writes `buffer[0]` and `buffer[1]`, the latter  `buffer[4]` and `buffer[5]`
 - The number of bytes to be written
 - Repeated start if needed
 
Returns

- None

Example
- From (the previously defined)  `uint8_t buffer[4]` write 2 bytes (`buffer[0]`, `buffer[1]`) and finish the command with a STOP,  i.e. no repeated start.
`brzo_i2c_write(buffer, 2, false);`

**I2C Read**

`brzo_i2c_read(uint8_t *data, uint8_t no_of_bytes, boolean repeated_start)`

> **Note:** 
> - You can only call `brzo_i2c_read` inside a transaction!
> - Of course, there is error checking inside the read command. However, errors are only reported at the end of a transaction.


Input

 - A pointer to an array of bytes: Either use the base address, e.g., `brzo_i2c_read(buffer, 2, ..)` or use the address of a specific array element, e.g. `brzo_i2c_read(&buffer[4], 2, ..);`. The former receives two bytes and saves them to `buffer[0]` and `buffer[1]`, the latter to `buffer[4]` and `buffer[5]`
 - The number of bytes to be read
 - Repeated start if needed
 
Returns

- None

Example

- Into (the previously defined) `uint8_t buffer[4]` store 3 bytes (`buffer[0]`, `buffer[1]`, `buffer[2]`) and finish the read with a repeated start, i.e. do not send a STOP.
`brzo_i2c_read(buffer, 3, true);`

**I2C Acknowledge Polling**

Please see the [wiki](https://github.com/pasko-zh/brzo_i2c/wiki#i2c-acknowledge-polling) for further information about ACK Polling.

`brzo_i2c_ACK_polling(uint16_t ACK_polling_time_out_usec)`


> **Note:** 
> - You can only call `brzo_i2c_ACK_polling` inside a transaction!
> - There is error checking inside the ACK polling command. However, errors are only reported at the end of a transaction.


Input

 -  The timeout for ACK polling in micro seconds
 
Returns

- None

Example

- Perform an ACK polling with 10 msec timeout `brzo_i2c_ACK_polling(10000)`


Example of I2C Transactions
----------------
Examples of sketches are located in [/examples](https://github.com/pasko-zh/brzo_i2c/tree/master/examples) folder.

```c
#include "brzo_i2c.h"

uint8_t SDA_PIN = 5;
uint8_t SCL_PIN = 12;
uint8_t ADT7420_ADR = 0x49;
uint8_t buffer[3];
uint8_t return_code = 0;
uint32_t ADC_code = 0;
long temp;

void setup() {
  // Setup i2c with clock stretching timeout of 2000 usec
  brzo_i2c_setup(SDA_PIN, SCL_PIN, 2000);
...
}

...

// Start a transaction to the ADT7420 at 400 KHz

brzo_i2c_start_transaction(ADT7420_ADR, 400);
  buffer[0] = 0x03; // select configuration register
  buffer[1] = 0xA0; // select 16 bit resolution
  brzo_i2c_write(buffer, 2, false); // Write two bytes with no repeated start
  buffer[0] = 0x00; // select temperature register
  brzo_i2c_write(buffer, 1, true); // Write one byte WITH repeated start
  brzo_i2c_read(buffer, 2, false); // Read temperature, two bytes
return_code = brzo_i2c_end_transaction();

if (return_code == 0) {
  ADC_code = ((buffer[0] << 8) | buffer[1]);
  temp = ADC_code / 128.0;
 }
else {
  // Error Handling here...
}
```




