I2C not yet integrated

Dependencies:   mbed

Tested working with single and differential voltages.

Connect SCL (pin 11) to D15 Connect SDA (pin 10) to D14 Connect pin 16 to +5v Connect pin 9 to gnd

Revision:
0:1473318f27b6
Child:
1:4e4194db7cd6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LT_I2C.cpp	Wed Nov 16 15:54:08 2016 +0000
@@ -0,0 +1,527 @@
+
+/*!
+LT_I2C: Routines to communicate with ATmega328P's hardware I2C port.
+
+@verbatim
+
+LT_I2C contains the low level routines to communicate with devices using the
+ATMega328's onboard hardware I2C port. Each routine checks the Two Wire Status
+Register (TWSR) at the end of the transaction and returns 0 if successful and 1
+if not successful.
+
+I2C Frequency = (CPU Clock frequency)/(16+2(TWBR)*Prescaler)
+
+TWBR-Two Wire Bit Rate Register
+TWCR=Two Wire Control Register (TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE)
+TWSR=Two Wire Status Register
+
+Prescaler Values:
+TWSR1  TWSR0  Prescaler
+   0      0      1
+   0      1      4
+   1      0      16
+   1      1      64
+
+Examples:
+CPU Frequency = 16Mhz on Arduino Uno
+I2C Frequency  Prescaler  TWSR1  TWSR0  TWBR
+  1khz         64         1      1      125
+  10khz        64         1      1      12
+  50khz        16         1      0      10
+  100khz        4         0      1      18
+  400khz        1         0      0      12
+
+@endverbatim
+
+REVISION HISTORY
+$Revision: 5469 $
+$Date: 2016-07-22 17:01:32 -0700 (Fri, 22 Jul 2016) $
+
+Copyright (c) 2013, Linear Technology Corp.(LTC)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of Linear Technology Corp.
+
+The Linear Technology Linduino is not affiliated with the official Arduino team.
+However, the Linduino is only possible because of the Arduino team's commitment
+to the open-source community.  Please, visit http://www.arduino.cc and
+http://store.arduino.cc , and consider a purchase that will help fund their
+ongoing work.
+*/
+
+//! @defgroup LT_I2C LT_I2C: Routines to Communicate With ATmega328P's hardware I2C port.
+
+/*! @file
+    @ingroup LT_I2C
+    Library for LT_I2C: Routines to Communicate With ATmega328P's hardware I2C port.
+*/
+
+//#include <Arduino.h>
+#include <stdint.h>
+//#include <util/delay.h>
+#include "Linduino.h"
+#include "LT_I2C.h"
+
+//! CPU master clock frequency
+#ifndef F_CPU
+#define F_CPU 16000000UL
+#endif
+
+// Read a byte, store in "value".
+int8_t i2c_read_byte(uint8_t address, uint8_t *value)
+{
+  //uint8_t ret=0;
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_READ_BIT);                // Write the I2C 7-bit address with R bit
+//  if (ret != 0)                                   // Returns 1 if failed
+//    return(1);
+//
+//  *value = i2c_read(WITH_NACK);                           // Read byte from I2C Bus with NAK
+//  i2c_stop();                                     //I2C STOP
+//  return(0);                                      // Return success
+    return 0;
+
+}
+
+// Write "value" byte to device at "address"
+int8_t i2c_write_byte(uint8_t address, uint8_t value)
+{
+  //int8_t ret= 0 ;
+//
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_WRITE_BIT);        //Write the I2C 7 bit address with W bit
+//  ret |= i2c_write(value);            //Write value
+//  i2c_stop();                         //I2C STOP
+//  if (ret!=0)                            // Returns 1 if failed
+//    return(1);
+//  return(0);                          // Returns 0 if success
+    return 0;
+}
+
+// Read a byte of data at register specified by "command", store in "value"
+int8_t i2c_read_byte_data(uint8_t address, uint8_t command, uint8_t *value)
+{
+  //int8_t ret = 0;
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_WRITE_BIT);        // Write 7 bit address with W bit
+//  ret|= i2c_write(command);                 // Set register to be read to command
+//  if (i2c_start()!=0)                                 //I2C repeated START
+//  {
+//    i2c_stop();                                 //Attempt to issue I2C STOP
+//    return(1);                                  //Stop and return 0 if START fail
+//  }
+//  ret |= i2c_write((address<<1)|I2C_READ_BIT);     // Write 7 bit address with R bit
+//  *value = i2c_read(WITH_NACK);               // Read byte from buffer with NAK
+//  i2c_stop();                         // I2C STOP
+//  if (ret!=0)                         //If there was a NAK return 1
+//    return(1);
+//  return(0);                     // Return success
+    return 0;
+}
+
+// Write a byte of data to register specified by "command"
+int8_t i2c_write_byte_data(uint8_t address, uint8_t command, uint8_t value)
+{
+  //int8_t ret = 0;
+//
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_WRITE_BIT);        // Write 7 bit address with W bit
+//  ret|= i2c_write(command);                 // Set register to be read to command
+//  ret|= i2c_write(value);
+//  i2c_stop();                        // I2C STOP
+//
+//  if (ret!=0)                         //If there was a NAK return 1
+//    return(1);
+//  return(0);                     // Return success
+    return 0;
+}
+
+// Read a 16-bit word of data from register specified by "command"
+int8_t i2c_read_word_data(uint8_t address, uint8_t command, uint16_t *value)
+{
+  //int8_t ret = 0;
+//
+//  union
+//  {
+//    uint8_t b[2];
+//    uint16_t w;
+//  } data;
+//
+//
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_WRITE_BIT);        // Write 7 bit address with W bit
+//  ret |= i2c_write(command);                 // Set register to be read to command
+//  if (i2c_start()!=0)                                 //I2C START
+//  {
+//    i2c_stop();                                 //Attempt to issue I2C STOP
+//    return(1);                                  //Stop and return 0 if START fail
+//  }
+//  ret |= i2c_write((address<<1)|I2C_READ_BIT);     // Write 7 bit address with R bit
+//
+//  data.b[1] = i2c_read(WITH_ACK);                        // Read MSB from buffer
+//  data.b[0] = i2c_read(WITH_NACK);                        // Read LSB from buffer
+//  i2c_stop();                         //I2C STOP
+//
+//  *value = data.w;
+//
+//  if (ret!=0)                         //If NAK
+//    return (1);                     //return 1
+//  return(0);                                      // Return success
+    return 0;
+}
+
+// Write a 16-bit word of data to register specified by "command"
+int8_t i2c_write_word_data(uint8_t address, uint8_t command, uint16_t value)
+{
+  //int8_t ret=0;
+//
+//  union
+//  {
+//    uint8_t b[2];
+//    uint16_t w;
+//  } data;
+//  data.w = value;
+//
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_WRITE_BIT);       // Write 7 bit address with W bit
+//  ret|= i2c_write(command);                 // Set register to be read to command
+//  ret|= i2c_write(data.b[1]);         //Write MSB
+//  ret|= i2c_write(data.b[0]);         //Write LSB;
+//
+//  i2c_stop();                        // I2C STOP
+//
+//  if (ret!=0)                         //If there was a NAK return 1
+//    return(1);
+//  return(0);
+
+    return 0;
+}
+
+// Read a block of data, starting at register specified by "command" and ending at (command + length - 1)
+int8_t i2c_read_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values)
+{
+  //uint8_t i = (length-1);
+//  int8_t ret = 0;
+//
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_WRITE_BIT);       //Write 7-bit address with W bit
+//  if (ret!=0)   //If NACK return 1
+//  {
+//    i2c_stop();                         //I2C STOP
+//    return(1);
+//  }
+//  ret|= i2c_write(command);                           //Write 8 bit command word
+//  if (ret!=0)   //If NACK return 1
+//  {
+//    i2c_stop();                         //I2C STOP
+//    return(1);
+//  }
+//  if (i2c_start()!=0)                                 //I2C repeated START
+//  {
+//    i2c_stop();                                 //Attempt to issue I2C STOP
+//    return(1);                                  //Stop and return 0 if START fail
+//  }
+//  ret |= i2c_write((address<<1)|I2C_READ_BIT);        //Write 7-bit address with R bit
+//
+//  if (ret!=0)   //If NACK return 1
+//  {
+//    i2c_stop();                         //I2C STOP
+//    return(1);
+//  }
+//  while (i>0)                         //Begin read loop
+//  {
+//    values[i] = i2c_read(WITH_ACK); //Read from bus with ACK
+//    i--;
+//  }
+//
+//  values[0] = i2c_read(WITH_NACK);    //Read from bus with NACK for the last one;
+//
+//  i2c_stop();                         //I2C STOP
+//
+//
+//  return(0);                           // Success!
+    return 0;
+}
+
+
+// Read a block of data, no command byte, reads length number of bytes and stores it in values.
+int8_t i2c_read_block_data(uint8_t address, uint8_t length, uint8_t *values)
+{
+  //uint8_t i = (length-1);
+//  int8_t ret = 0;
+//
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_READ_BIT);        //Write 7-bit address with R bit
+//
+//  if (ret!=0)   //If NACK return 1
+//  {
+//    i2c_stop();                         //I2C STOP
+//    return(1);
+//  }
+//  while (i>0)                         //Begin read loop
+//  {
+//    values[i] = i2c_read(WITH_ACK); //Read from bus with ACK
+//    i--;
+//  }
+//
+//  values[0] = i2c_read(WITH_NACK);    //Read from bus with NACK for the last one;
+//
+//  i2c_stop();                         //I2C STOP
+//
+//
+//  return(0);                           // Success!
+    return 0;
+}
+
+
+// Write a block of data, starting at register specified by "command" and ending at (command + length - 1)
+int8_t i2c_write_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values)
+{
+ // int8_t i = length-1;
+//  int8_t ret = 0;
+//
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_WRITE_BIT);        // Write 7 bit address with W bit
+//  ret|= i2c_write(command);           // Set register to be read to command
+//
+//  while (i>=0)
+//  {
+//    ret|= i2c_write(values[i]);     //Write Value
+//    i--;
+//  }
+//  i2c_stop();                        // I2C STOP
+//
+//  if (ret!=0)
+//    return(1);
+//  else
+//    return(0);                      // Success!
+    return 0;
+}
+
+// Write two command bytes, then receive a block of data
+int8_t i2c_two_byte_command_read_block(uint8_t address, uint16_t command, uint8_t length, uint8_t *values)
+{
+//
+//  int8_t ret = 0;
+//
+//  union
+//  {
+//    uint8_t b[2];
+//    uint16_t w;
+//  } comm;
+//  comm.w = command;
+//
+//  uint8_t i = (length-1);
+//
+//
+//  if (i2c_start()!=0)                                //I2C START
+//    return(1);                                  //Stop and return 0 if START fail
+//  ret |= i2c_write((address<<1)|I2C_WRITE_BIT);           //Write 7-bit address with W bit
+//  ret |= i2c_write(comm.b[1]);                             //Write MSB command word
+//  ret |= i2c_write(comm.b[0]);                             // Write LSB of command
+//  if (i2c_start()!=0)                                 //I2C repeated START
+//  {
+//    i2c_stop();                                 //Attempt to issue I2C STOP
+//    return(1);                                  //Stop and return 0 if START fail
+//  }
+//  ret |= i2c_write((address<<1)|I2C_READ_BIT);            //Write 7-bit address with R bit
+//  if (ret!=0)                                              //If NACK return 1
+//  {
+//    i2c_stop();
+//    return(1);
+//  }
+//  while (i> 0)                         //Begin read loop
+//  {
+//    values[i] = i2c_read(WITH_ACK); //Read from bus with ACK
+//    i--;
+//  }
+//
+//  values[0] = i2c_read(WITH_NACK);    //Read from bus with NACK for the last one;
+//  i2c_stop();                         //I2C STOP
+//
+//
+//  return(0);                           // Success!
+    return 0;
+}
+
+// Initializes Linduino I2C port.
+// Before communicating to the I2C port throught the QuikEval connector, you must also run
+// quikeval_I2C_connect to connect the I2C port to the QuikEval connector throught the
+// QuikEval MUX (and disconnect SPI).
+void quikeval_I2C_init(void)
+{
+//  i2c_enable();  //! 1) Enable the I2C port;
+}
+
+// Switch MUX to connect I2C pins to QuikEval connector.
+// This will disconnect SPI pins.
+void quikeval_I2C_connect(void)
+{
+  //// Enable I2C
+//  pinMode(QUIKEVAL_MUX_MODE_PIN, OUTPUT);       //! 1) Set Mux pin as an output
+//  if (digitalRead(QUIKEVAL_MUX_MODE_PIN) == LOW) //! 2) If pin is already high, do nothing
+//  {
+//    digitalWrite(QUIKEVAL_MUX_MODE_PIN, HIGH);  //! 3) Set the Mux pin to high
+//    delay(55);                                  //! 4) And wait for LTC4315 to connect (required for rev B)
+//  }
+}
+
+// Setup the hardware I2C interface.
+// i2c_enable or quikeval_I2C_init must be called before using any of the other I2C routines.
+void i2c_enable()
+{
+ // // set these for 100KHz to match the DC590
+//  TWSR = (HARDWARE_I2C_PRESCALER_4 & 0x03);  //! 1) set the prescaler bits
+//  TWBR = 18;                                 //! 2) set the bit rate
+
+}
+
+
+// Write start bit to the hardware I2C port
+// return 0 if successful, 1 if not successful
+int8_t i2c_start()
+{
+  //uint8_t result;
+//  uint16_t timeout;
+//  TWCR=(1<<TWINT) | (1<<TWSTA) | (1<<TWEN);                 //! 1) I2C start
+//  for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++)    //! 2) START the timeout loop
+//  {
+//    _delay_us(1);
+//    if (TWCR & (1 << TWINT)) break;                         //! 3) Check the TWINT bit in TWCR
+//  }
+//  result=(TWSR & 0xF8);                                     //! 4) Mask the status
+//  if ((result == STATUS_START) || (result == STATUS_REPEATED_START))
+//    return(0);                                              //! 5) Return status
+//  else
+//    return(1);
+    return 0;
+}
+
+// Write a repeat start bit to the hardware I2C port
+// return 0 if successful, 1 if not successful
+int8_t i2c_repeated_start()
+{
+  //uint8_t result;
+//  uint16_t timeout;
+//  TWCR=(1<<TWINT) | (1<<TWSTA) | (1<<TWEN);                 //! 1) I2C repeated start
+//  for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++)    //! 2) START the timeout loop
+//  {
+//    _delay_us(1);
+//    if (TWCR & (1 << TWINT)) break;                         //! 3) Check the TWINT bit in TWCR
+//  }
+//  result=(TWSR & 0xF8);                                     //! 4) Mask the status
+//  if (result == STATUS_REPEATED_START)
+//    return(0);                                              //! 5) Return status
+//  else
+//    return(1);
+    return 0;
+}
+
+// Write stop bit to the hardware I2C port
+void i2c_stop()
+{
+  //TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);  //! 1) I2C stop
+//  while (TWCR & (1<<TWSTO));                 //! 2) Wait for stop to complete
+}
+
+// Send a data byte to hardware I2C port
+// return 0 if successful, 1 if not successful
+int8_t i2c_write(uint8_t data)
+{
+ // uint8_t result;
+//  uint16_t timeout;
+//  TWDR = data;                                              //! 1) Load data register
+//  TWCR =(1<<TWINT) | (1<<TWEN);                             //! 2) START transaction
+//  for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++)    //! 3) START the timeout loop
+//  {
+//    _delay_us(1);
+//    if (TWCR & (1 << TWINT)) break;                         //! 4) Check the TWINT bit in TWCR
+//  }
+//  result=(TWSR & 0xF8);                                     //! 5) Update status
+//  // For a generic write, need to consider all three of these cases (processor specific, some may not be this detailed.)
+//  if ((result == STATUS_WRITE_ACK) || (result == STATUS_ADDRESS_WRITE_ACK) || (result == STATUS_ADDRESS_READ_ACK))
+//    return(0);                                              //! 6) Return status
+//  else
+//    return(1);
+    return 0;
+}
+
+// Read a data byte from the hardware I2C port.
+// Returns the data byte read.
+uint8_t i2c_read(int8_t ack)
+{
+  //uint8_t result;
+//  uint8_t return_value = 1;
+//  uint16_t timeout;
+//  uint8_t data;
+//  if (ack == 0)
+//  {
+//    TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWEA);                //! 1) START transaction with ack
+//    for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++)  //! 2) START timeout loop
+//    {
+//      _delay_us(1);
+//      if (TWCR & (1 << TWINT)) break;                       //! 3) Check the TWINT bit in TWCR
+//    }
+//    data = TWDR;                                            //! 4) Get data
+//    result = TWSR & 0xF8;                                   //! 5) Update status
+//    if (result == STATUS_READ_ACK) return_value = 0;
+//  }
+//  else
+//  {
+//    TWCR=(1<<TWINT) | (1<<TWEN);                            //! 6) START transaction with NACK
+//    for (timeout = 0; timeout < HW_I2C_TIMEOUT; timeout++)
+//    {
+//      _delay_us(1);
+//      if (TWCR & (1 << TWINT)) break;                       //! 7) Check the TWINT bit in TWCR
+//    }
+//    data = TWDR;                                            //! 8) Get data
+//    result = TWSR & 0xF8;                                   //! 9) Update status
+//    if (result == STATUS_READ_NACK) return_value = 0;
+//  }
+//  return(data);
+    return 0;
+}
+
+// Poll the I2C port and look for an acknowledge
+// Returns 0 if successful, 1 if not successful
+int8_t i2c_poll(uint8_t i2c_address)
+
+{
+  //int8_t ack=0;
+//  ack |= i2c_start();                                  //! 1) I2C start
+//  ack |= i2c_write((i2c_address<<1) | I2C_WRITE_BIT); //! 2) I2C address + !write
+//  i2c_stop();                                   //! 3) I2C stop
+//  return(ack);                                  //! 4) Return ack status
+    return 0;
+}