--- /dev/null
+/*\r
+  twi.c - TWI/I2C library for Atmega32U4\r
+\r
+  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.\r
+\r
+  This library is free software; you can redistribute it and/or\r
+  modify it under the terms of the GNU Lesser General Public\r
+  License as published by the Free Software Foundation; either\r
+  version 2.1 of the License, or (at your option) any later version.\r
+\r
+  This library is distributed in the hope that it will be useful,\r
+  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+  Lesser General Public License for more details.\r
+\r
+  You should have received a copy of the GNU Lesser General Public\r
+  License along with this library; if not, write to the Free Software\r
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
+\r
+  Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts\r
+\r
+  Modified 2017 by Adrian Weber to use I2C without Arduino librarys\r
+*/\r
+\r
+#include <math.h>\r
+#include <stdlib.h>\r
+#include <inttypes.h>\r
+#include <avr/io.h>\r
+#include <avr/interrupt.h>\r
+#include <compat/twi.h>\r
+#include <stdbool.h>\r
+\r
+#ifndef cbi\r
+#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))\r
+#endif\r
+\r
+#ifndef sbi\r
+#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))\r
+#endif\r
+#include "twi.h"\r
+\r
+static volatile uint8_t twi_state;\r
+static volatile uint8_t twi_slarw;\r
+static volatile uint8_t twi_sendStop;                  // should the transaction end with a stop\r
+static volatile uint8_t twi_inRepStart;                        // in the middle of a repeated start\r
+\r
+static void (*twi_onSlaveTransmit)(void);\r
+static void (*twi_onSlaveReceive)(uint8_t*, int);\r
+\r
+static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];\r
+static volatile uint8_t twi_masterBufferIndex;\r
+static volatile uint8_t twi_masterBufferLength;\r
+\r
+static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];\r
+static volatile uint8_t twi_txBufferIndex;\r
+static volatile uint8_t twi_txBufferLength;\r
+\r
+static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];\r
+static volatile uint8_t twi_rxBufferIndex;\r
+\r
+static volatile uint8_t twi_error;\r
+\r
+\r
+/* \r
+ * Function twi_init\r
+ * Desc     readys twi pins and sets twi bitrate\r
+ * Input    none\r
+ * Output   none\r
+ */\r
+void twi_init(void)\r
+{\r
+  // initialize state\r
+  twi_state = TWI_READY;\r
+  twi_sendStop = true;         // default value\r
+  twi_inRepStart = false;\r
+  \r
+  // activate internal pullups for twi.\r
+  DDRD |= (0 << 1);\r
+  DDRD |= (0 << 0);\r
+  PORTD |= (1 << 1);\r
+  PORTD |= (1 << 0);\r
+\r
+  // initialize twi prescaler and bit rate\r
+  cbi(TWSR, TWPS0);\r
+  cbi(TWSR, TWPS1);\r
+  TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;\r
+\r
+  sei();\r
+\r
+  /* twi bit rate formula from atmega128 manual pg 204\r
+  SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))\r
+  note: TWBR should be 10 or higher for master mode\r
+  It is 72 for a 16mhz Wiring board with 100kHz TWI */\r
+\r
+  // enable twi module, acks, and twi interrupt\r
+  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);\r
+}\r
+\r
+/* \r
+ * Function twi_disable\r
+ * Desc     disables twi pins\r
+ * Input    none\r
+ * Output   none\r
+ */\r
+void twi_disable(void)\r
+{\r
+  // disable twi module, acks, and twi interrupt\r
+  TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA));\r
+\r
+  // deactivate internal pullups for twi.\r
+  DDRD |= (1 << 0);\r
+  DDRD |= (1 << 1);\r
+  PORTD |= (1 << 0);\r
+  PORTD |= (1 << 1);\r
+\r
+}\r
+\r
+/* \r
+ * Function twi_slaveInit\r
+ * Desc     sets slave address and enables interrupt\r
+ * Input    none\r
+ * Output   none\r
+ */\r
+void twi_setAddress(uint8_t address)\r
+{\r
+  // set twi slave address (skip over TWGCE bit)\r
+  TWAR = address << 1;\r
+}\r
+\r
+/* \r
+ * Function twi_setClock\r
+ * Desc     sets twi bit rate\r
+ * Input    Clock Frequency\r
+ * Output   none\r
+ */\r
+void twi_setFrequency(uint32_t frequency)\r
+{\r
+  TWBR = ((F_CPU / frequency) - 16) / 2;\r
+  \r
+  /* twi bit rate formula from atmega128 manual pg 204\r
+  SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))\r
+  note: TWBR should be 10 or higher for master mode\r
+  It is 72 for a 16mhz Wiring board with 100kHz TWI */\r
+}\r
+\r
+/* \r
+ * Function twi_readFrom\r
+ * Desc     attempts to become twi bus master and read a\r
+ *          series of bytes from a device on the bus\r
+ * Input    address: 7bit i2c device address\r
+ *          data: pointer to byte array\r
+ *          length: number of bytes to read into array\r
+ *          sendStop: Boolean indicating whether to send a stop at the end\r
+ * Output   number of bytes read\r
+ */\r
+uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)\r
+{\r
+  uint8_t i;\r
+\r
+  // ensure data will fit into buffer\r
+  if(TWI_BUFFER_LENGTH < length){\r
+    return 0;\r
+  }\r
+  // wait until twi is ready, become master receiver\r
+  while(TWI_READY != twi_state){\r
+    continue;\r
+  } \r
+  twi_state = TWI_MRX;\r
+  twi_sendStop = sendStop;\r
+  // reset error state (0xFF.. no error occured)\r
+  twi_error = 0xFF;\r
+\r
+  // initialize buffer iteration vars\r
+  twi_masterBufferIndex = 0;\r
+  twi_masterBufferLength = length-1;  // This is not intuitive, read on...\r
+  // On receive, the previously configured ACK/NACK setting is transmitted in\r
+  // response to the received byte before the interrupt is signalled. \r
+  // Therefor we must actually set NACK when the _next_ to last byte is\r
+  // received, causing that NACK to be sent in response to receiving the last\r
+  // expected byte of data.\r
+\r
+  // build sla+w, slave device address + w bit\r
+  twi_slarw = TW_READ;\r
+  twi_slarw |= address << 1;\r
+\r
+  if (true == twi_inRepStart) {\r
+    // if we're in the repeated start state, then we've already sent the start,\r
+    // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.\r
+    // We need to remove ourselves from the repeated start state before we enable interrupts,\r
+    // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning\r
+    // up. Also, don't enable the START interrupt. There may be one pending from the \r
+    // repeated start that we sent ourselves, and that would really confuse things.\r
+    twi_inRepStart = false;                    // remember, we're dealing with an ASYNC ISR\r
+    do {\r
+      TWDR = twi_slarw;\r
+    } while(TWCR & _BV(TWWC));\r
+    TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);     // enable INTs, but not START\r
+  }\r
+  else\r
+    // send start condition\r
+    TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);\r
+\r
+  // wait for read operation to complete\r
+  while(TWI_MRX == twi_state){\r
+    continue;\r
+  }\r
+\r
+  if (twi_masterBufferIndex < length)\r
+    length = twi_masterBufferIndex;\r
+\r
+  // copy twi buffer to data\r
+  for(i = 0; i < length; ++i){\r
+    data[i] = twi_masterBuffer[i];\r
+  }\r
+       \r
+  return length;\r
+}\r
+\r
+/* \r
+ * Function twi_writeTo\r
+ * Desc     attempts to become twi bus master and write a\r
+ *          series of bytes to a device on the bus\r
+ * Input    address: 7bit i2c device address\r
+ *          data: pointer to byte array\r
+ *          length: number of bytes in array\r
+ *          wait: boolean indicating to wait for write or not\r
+ *          sendStop: boolean indicating whether or not to send a stop at the end\r
+ * Output   0 .. success\r
+ *          1 .. length to long for buffer\r
+ *          2 .. address send, NACK received\r
+ *          3 .. data send, NACK received\r
+ *          4 .. other twi error (lost bus arbitration, bus error, ..)\r
+ */\r
+uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)\r
+{\r
+  uint8_t i;\r
+\r
+  // ensure data will fit into buffer\r
+  if(TWI_BUFFER_LENGTH < length){\r
+    return 1;\r
+  }\r
+\r
+  // wait until twi is ready, become master transmitter\r
+  while(TWI_READY != twi_state){\r
+    continue;\r
+  }\r
+  twi_state = TWI_MTX;\r
+  twi_sendStop = sendStop;\r
+  // reset error state (0xFF.. no error occured)\r
+  twi_error = 0xFF;\r
+\r
+  // initialize buffer iteration vars\r
+  twi_masterBufferIndex = 0;\r
+  twi_masterBufferLength = length;\r
+  \r
+  // copy data to twi buffer\r
+  for(i = 0; i < length; ++i){\r
+    twi_masterBuffer[i] = data[i];\r
+  }\r
+  \r
+  // build sla+w, slave device address + w bit\r
+  twi_slarw = TW_WRITE;\r
+  twi_slarw |= address << 1;\r
+  \r
+\r
+  // if we're in a repeated start, then we've already sent the START\r
+  // in the ISR. Don't do it again.\r
+  //\r
+  if (true == twi_inRepStart) {\r
+    // if we're in the repeated start state, then we've already sent the start,\r
+    // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.\r
+    // We need to remove ourselves from the repeated start state before we enable interrupts,\r
+    // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning\r
+    // up. Also, don't enable the START interrupt. There may be one pending from the \r
+    // repeated start that we sent outselves, and that would really confuse things.\r
+    twi_inRepStart = false;                    // remember, we're dealing with an ASYNC ISR\r
+    do {\r
+      TWDR = twi_slarw;                                \r
+    } while(TWCR & _BV(TWWC));\r
+    TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);     // enable INTs, but not START\r
+  }\r
+  else\r
+    // send start condition\r
+    TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA);        // enable INTs\r
+\r
+\r
+  // wait for write operation to complete\r
+  while(wait && (TWI_MTX == twi_state)){\r
+    continue;\r
+  }\r
+\r
+  if (twi_error == 0xFF)\r
+    return 0;  // success\r
+  else if (twi_error == TW_MT_SLA_NACK)\r
+    return 2;  // error: address send, nack received\r
+  else if (twi_error == TW_MT_DATA_NACK)\r
+    return 3;  // error: data send, nack received\r
+  else\r
+    return 4;  // other twi error\r
+}\r
+\r
+/* \r
+ * Function twi_transmit\r
+ * Desc     fills slave tx buffer with data\r
+ *          must be called in slave tx event callback\r
+ * Input    data: pointer to byte array\r
+ *          length: number of bytes in array\r
+ * Output   1 length too long for buffer\r
+ *          2 not slave transmitter\r
+ *          0 ok\r
+ */\r
+uint8_t twi_transmit(const uint8_t* data, uint8_t length)\r
+{\r
+  uint8_t i;\r
+\r
+  // ensure data will fit into buffer\r
+  if(TWI_BUFFER_LENGTH < length){\r
+    return 1;\r
+  }\r
+  \r
+  // ensure we are currently a slave transmitter\r
+  if(TWI_STX != twi_state){\r
+    return 2;\r
+  }\r
+  \r
+  // set length and copy data into tx buffer\r
+  twi_txBufferLength = length;\r
+  for(i = 0; i < length; ++i){\r
+    twi_txBuffer[i] = data[i];\r
+  }\r
+  \r
+  return 0;\r
+}\r
+\r
+/* \r
+ * Function twi_attachSlaveRxEvent\r
+ * Desc     sets function called before a slave read operation\r
+ * Input    function: callback function to use\r
+ * Output   none\r
+ */\r
+void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) )\r
+{\r
+  twi_onSlaveReceive = function;\r
+}\r
+\r
+/* \r
+ * Function twi_attachSlaveTxEvent\r
+ * Desc     sets function called before a slave write operation\r
+ * Input    function: callback function to use\r
+ * Output   none\r
+ */\r
+void twi_attachSlaveTxEvent( void (*function)(void) )\r
+{\r
+  twi_onSlaveTransmit = function;\r
+}\r
+\r
+/* \r
+ * Function twi_reply\r
+ * Desc     sends byte or readys receive line\r
+ * Input    ack: byte indicating to ack or to nack\r
+ * Output   none\r
+ */\r
+void twi_reply(uint8_t ack)\r
+{\r
+  // transmit master read ready signal, with or without ack\r
+  if(ack){\r
+    TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);\r
+  }else{\r
+         TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);\r
+  }\r
+}\r
+\r
+/* \r
+ * Function twi_stop\r
+ * Desc     relinquishes bus master status\r
+ * Input    none\r
+ * Output   none\r
+ */\r
+void twi_stop(void)\r
+{\r
+  // send stop condition\r
+  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);\r
+\r
+  // wait for stop condition to be exectued on bus\r
+  // TWINT is not set after a stop condition!\r
+  while(TWCR & _BV(TWSTO)){\r
+    continue;\r
+  }\r
+\r
+  // update twi state\r
+  twi_state = TWI_READY;\r
+}\r
+\r
+/* \r
+ * Function twi_releaseBus\r
+ * Desc     releases bus control\r
+ * Input    none\r
+ * Output   none\r
+ */\r
+void twi_releaseBus(void)\r
+{\r
+  // release bus\r
+  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);\r
+\r
+  // update twi state\r
+  twi_state = TWI_READY;\r
+}\r
+\r
+ISR(TWI_vect)\r
+{\r
+  switch(TW_STATUS){\r
+    // All Master\r
+    case TW_START:     // sent start condition\r
+    case TW_REP_START: // sent repeated start condition\r
+      // copy device address and r/w bit to output register and ack\r
+      TWDR = twi_slarw;\r
+      twi_reply(1);\r
+      break;\r
+\r
+    // Master Transmitter\r
+    case TW_MT_SLA_ACK:  // slave receiver acked address\r
+    case TW_MT_DATA_ACK: // slave receiver acked data\r
+      // if there is data to send, send it, otherwise stop \r
+      if(twi_masterBufferIndex < twi_masterBufferLength){\r
+        // copy data to output register and ack\r
+        TWDR = twi_masterBuffer[twi_masterBufferIndex++];\r
+        twi_reply(1);\r
+      }else{\r
+       if (twi_sendStop)\r
+          twi_stop();\r
+       else {\r
+         twi_inRepStart = true;        // we're gonna send the START\r
+         // don't enable the interrupt. We'll generate the start, but we \r
+         // avoid handling the interrupt until we're in the next transaction,\r
+         // at the point where we would normally issue the start.\r
+         TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;\r
+         twi_state = TWI_READY;\r
+       }\r
+      }\r
+      break;\r
+    case TW_MT_SLA_NACK:  // address sent, nack received\r
+      twi_error = TW_MT_SLA_NACK;\r
+      twi_stop();\r
+      break;\r
+    case TW_MT_DATA_NACK: // data sent, nack received\r
+      twi_error = TW_MT_DATA_NACK;\r
+      twi_stop();\r
+      break;\r
+    case TW_MT_ARB_LOST: // lost bus arbitration\r
+      twi_error = TW_MT_ARB_LOST;\r
+      twi_releaseBus();\r
+      break;\r
+\r
+    // Master Receiver\r
+    case TW_MR_DATA_ACK: // data received, ack sent\r
+      // put byte into buffer\r
+      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;\r
+    case TW_MR_SLA_ACK:  // address sent, ack received\r
+      // ack if more bytes are expected, otherwise nack\r
+      if(twi_masterBufferIndex < twi_masterBufferLength){\r
+        twi_reply(1);\r
+      }else{\r
+        twi_reply(0);\r
+      }\r
+      break;\r
+    case TW_MR_DATA_NACK: // data received, nack sent\r
+      // put final byte into buffer\r
+      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;\r
+       if (twi_sendStop)\r
+          twi_stop();\r
+       else {\r
+         twi_inRepStart = true;        // we're gonna send the START\r
+         // don't enable the interrupt. We'll generate the start, but we \r
+         // avoid handling the interrupt until we're in the next transaction,\r
+         // at the point where we would normally issue the start.\r
+         TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;\r
+         twi_state = TWI_READY;\r
+       }    \r
+       break;\r
+    case TW_MR_SLA_NACK: // address sent, nack received\r
+      twi_stop();\r
+      break;\r
+    // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case\r
+\r
+    // Slave Receiver\r
+    case TW_SR_SLA_ACK:   // addressed, returned ack\r
+    case TW_SR_GCALL_ACK: // addressed generally, returned ack\r
+    case TW_SR_ARB_LOST_SLA_ACK:   // lost arbitration, returned ack\r
+    case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack\r
+      // enter slave receiver mode\r
+      twi_state = TWI_SRX;\r
+      // indicate that rx buffer can be overwritten and ack\r
+      twi_rxBufferIndex = 0;\r
+      twi_reply(1);\r
+      break;\r
+    case TW_SR_DATA_ACK:       // data received, returned ack\r
+    case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack\r
+      // if there is still room in the rx buffer\r
+      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){\r
+        // put byte in buffer and ack\r
+        twi_rxBuffer[twi_rxBufferIndex++] = TWDR;\r
+        twi_reply(1);\r
+      }else{\r
+        // otherwise nack\r
+        twi_reply(0);\r
+      }\r
+      break;\r
+    case TW_SR_STOP: // stop or repeated start condition received\r
+      // ack future responses and leave slave receiver state\r
+      twi_releaseBus();\r
+      // put a null char after data if there's room\r
+      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){\r
+        twi_rxBuffer[twi_rxBufferIndex] = '\0';\r
+      }\r
+      // callback to user defined callback\r
+      twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);\r
+      // since we submit rx buffer to "wire" library, we can reset it\r
+      twi_rxBufferIndex = 0;\r
+      break;\r
+    case TW_SR_DATA_NACK:       // data received, returned nack\r
+    case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack\r
+      // nack back at master\r
+      twi_reply(0);\r
+      break;\r
+    \r
+    // Slave Transmitter\r
+    case TW_ST_SLA_ACK:          // addressed, returned ack\r
+    case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack\r
+      // enter slave transmitter mode\r
+      twi_state = TWI_STX;\r
+      // ready the tx buffer index for iteration\r
+      twi_txBufferIndex = 0;\r
+      // set tx buffer length to be zero, to verify if user changes it\r
+      twi_txBufferLength = 0;\r
+      // request for txBuffer to be filled and length to be set\r
+      // note: user must call twi_transmit(bytes, length) to do this\r
+      twi_onSlaveTransmit();\r
+      // if they didn't change buffer & length, initialize it\r
+      if(0 == twi_txBufferLength){\r
+        twi_txBufferLength = 1;\r
+        twi_txBuffer[0] = 0x00;\r
+      }\r
+      // transmit first byte from buffer, fall\r
+    case TW_ST_DATA_ACK: // byte sent, ack returned\r
+      // copy data to output register\r
+      TWDR = twi_txBuffer[twi_txBufferIndex++];\r
+      // if there is more to send, ack, otherwise nack\r
+      if(twi_txBufferIndex < twi_txBufferLength){\r
+        twi_reply(1);\r
+      }else{\r
+        twi_reply(0);\r
+      }\r
+      break;\r
+    case TW_ST_DATA_NACK: // received nack, we are done \r
+    case TW_ST_LAST_DATA: // received ack, but we are done already!\r
+      // ack future responses\r
+      twi_reply(1);\r
+      // leave slave receiver state\r
+      twi_state = TWI_READY;\r
+      break;\r
+\r
+    // All\r
+    case TW_NO_INFO:   // no state information\r
+      break;\r
+    case TW_BUS_ERROR: // bus error, illegal stop/start\r
+      twi_error = TW_BUS_ERROR;\r
+      twi_stop();\r
+      break;\r
+  }\r
+}\r
+\r