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:
2:c9e727dcd00e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LT_I2C.h	Wed Nov 16 15:54:08 2016 +0000
@@ -0,0 +1,388 @@
+
+/*!
+LT_I2C: Routines to communicate with ATmega328P's hardware I2C port.
+
+REVISION HISTORY
+$Revision: 3659 $
+$Date: 2015-07-01 10:19:20 -0700 (Wed, 01 Jul 2015) $
+
+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.
+*/
+
+/*! @file
+    @ingroup LT_I2C
+    Library Header File for LT_I2C: Routines to communicate with ATmega328P's hardware I2C port.
+*/
+
+#ifndef LT_I2C_H
+#define LT_I2C_H
+
+#include <stdint.h>
+//#include <Wire.h>
+
+//! @name HARDWARE I2C PRESCALER VALUES
+//! @{
+#define HARDWARE_I2C_PRESCALER_1  0
+#define HARDWARE_I2C_PRESCALER_4  1
+#define HARDWARE_I2C_PRESCALER_16 2
+#define HARDWARE_I2C_PRESCALER_64 3
+//! @}
+
+//! @name I2C READ and WRITE BITS
+//! @{
+//! Eighth bit (LSB) of I2C address indicates a "read" or "write".
+//! (The first seven bits are the 7-bit I2C address.)
+#define I2C_READ_BIT    0x01
+#define I2C_WRITE_BIT   0x00
+//! @}
+
+//! @name STATUS BITS
+//! @{
+#define STATUS_START               0x08
+#define STATUS_REPEATED_START      0x10
+#define STATUS_ADDRESS_WRITE_ACK   0x18
+#define STATUS_ADDRESS_WRITE_NACK  0x20
+#define STATUS_WRITE_ACK           0x28
+#define STATUS_WRITE_NACK          0x30
+#define STATUS_ARBITRATION_LOST    0x38
+#define STATUS_ADDRESS_READ_ACK    0x40
+#define STATUS_ADDRESS_READ_NACK   0x48
+#define STATUS_READ_ACK            0x50
+#define STATUS_READ_NACK           0x58
+//! @}
+
+//! @name TIMEOUT AND DELAY IN US
+//! @{
+#define HW_I2C_DELAY  1
+#define HW_I2C_TIMEOUT  20000
+//! @}
+
+//! @name ACK OR NACK PARAMETER PASSED TO I2C_READ
+//! @{
+#define WITH_ACK  0  //!<  Use with i2c_read(WITH_ACK) to read with an acknowledge
+#define WITH_NACK 1  //!<  Use with i2c_read(WITH_NACK) to read without an acknowledge.  Normally used after the last byte of a multi-byte read.
+//! @}
+
+//! @name OPTIONAL I2C Address MACRO
+//! @{
+#define I2C_8ADDR(address) (address >> 1)  //!< Use to convert an 8-bit I2C address to 7 bits.
+//! @}
+
+//! Read a byte, store in "value".
+//! @return 0 on success, 1 on failure
+int8_t i2c_read_byte(uint8_t address,  //!< 7-bit I2C address
+                     uint8_t *value  //!< Byte to be read
+                    );
+
+//! Write "value" byte to device at "address"
+//! @return 0 on success, 1 on failure
+int8_t i2c_write_byte(uint8_t address, //!< 7-bit I2C address
+                      uint8_t value  //!< Byte to be written
+                     );
+
+//! Read a byte of data at register specified by "command", store in "value"
+//! @return 0 on success, 1 on failure
+int8_t i2c_read_byte_data(uint8_t address,     //!< 7-bit I2C address
+                          uint8_t command,   //!< Command byte
+                          uint8_t *value     //!< Byte to be read
+                         );
+
+//! Write a byte of data to register specified by "command"
+//! @return 0 on success, 1 on failure
+int8_t i2c_write_byte_data(uint8_t address,    //!< 7-bit I2C address
+                           uint8_t command,  //!< Command byte
+                           uint8_t value     //!< Byte to be written
+                          );
+
+//! Read a 16-bit word of data from register specified by "command"
+//! @return 0 on success, 1 on failure
+int8_t i2c_read_word_data(uint8_t address,     //!< 7-bit I2C address
+                          uint8_t command,   //!< Command byte
+                          uint16_t *value    //!< Word to be read
+                         );
+
+//! Write a 16-bit word of data to register specified by "command"
+//! @return 0 on success, 1 on failure
+int8_t i2c_write_word_data(uint8_t address,    //!< 7-bit I2C address
+                           uint8_t command,  //!< Command byte
+                           uint16_t value    //!< Word to be written
+                          );
+
+//! Read a block of data, starting at register specified by "command" and ending at (command + length - 1)
+//! @return 0 on success, 1 on failure
+int8_t i2c_read_block_data(uint8_t address,     //!< 7-bit I2C address
+                           uint8_t command,  //!< Command byte
+                           uint8_t length,   //!< Length of array
+                           uint8_t *values   //!< Byte array to be read
+                          );
+
+//! Read a block of data, no command byte, reads length number of bytes and stores it in values.
+//! @return 0 on success, 1 on failure
+int8_t i2c_read_block_data(uint8_t address,     //!< 7-bit I2C address
+                           uint8_t length,   //!< Length of array
+                           uint8_t *values   //!< Byte array to be read
+                          );
+
+
+//! Write a block of data, starting at register specified by "command" and ending at (command + length - 1)
+//! @return 0 on success, 1 on failure
+int8_t i2c_write_block_data(uint8_t address,       //!< 7-bit I2C address
+                            uint8_t command,     //!< Command byte
+                            uint8_t length,      //!< Length of array
+                            uint8_t *values      //!< Byte array to be written
+                           );
+
+//! Write a two command bytes, then receive a block of data
+//! @return 0 on success, 1 on failure
+int8_t i2c_two_byte_command_read_block(uint8_t address,    //!< 7-bit I2C address
+                                       uint16_t command,   //!< Command word
+                                       uint8_t length,     //!< Length of array
+                                       uint8_t *values     //!< Byte array to be read
+                                      );
+
+//! Initializes Linduino I2C port.
+//! Before communicating to the I2C port through the QuikEval connector, you must also run
+//! quikeval_I2C_connect to connect the I2C port to the QuikEval connector through the
+//! QuikEval MUX (and disconnect SPI).
+void quikeval_I2C_init(void);
+
+//! Switch MUX to connect I2C pins to QuikEval connector.
+//! This will disconnect SPI pins.
+void quikeval_I2C_connect(void);
+
+//! i2c_enable or quikeval_I2C_init must be called before using any of the other I2C routines.
+void i2c_enable(void);
+
+//! Write start bit to the hardware I2C port
+//! @return 0 if successful, 1 if not successful
+int8_t i2c_start();
+
+//! Write a repeat start bit to the hardware I2C port
+//! @return 0 if successful, 1 if not successful
+int8_t i2c_repeated_start();
+
+//! Write stop bit to the hardware I2C port
+void i2c_stop();
+
+//! Send a data byte to hardware I2C port
+//! @return 0 if successful, 1 if not successful
+int8_t i2c_write(uint8_t data   //!< byte that will be written to hardware I2C port.
+                );
+
+//! Read a data byte from the hardware I2C port.
+//! If ack is 0 then an acknowledge (ACK) is generated, else a NACK is generated.
+//! @return the data byte read.
+uint8_t i2c_read(int8_t ack //!< If ACK is 0 then an acknowledge is generated, else a NACK is generated.
+                );
+
+//! Poll the I2C port and look for an acknowledge
+//! @return Returns 0 if successful, 1 if not successful
+int8_t i2c_poll(uint8_t i2c_address //!< i2c_address is the address of the slave being polled.
+               );
+
+
+// //! Read a byte, store in "value".
+// //! @return -1 if failed or value if it succeeds
+// int32_t i2c_read_byte(uint8_t address,  //!< 7-bit I2C address
+//                         uint8_t *value  //!< Byte to be read
+//                        );
+//
+// //! Write "value" byte to device at "address"
+// //! @return -1 if failed or 0 if it succeeds
+// int32_t i2c_write_byte(uint8_t address, //!< 7-bit I2C address
+//                          uint8_t value  //!< Byte to be written
+//                         );
+//
+// //! Read a byte of data at register specified by "command", store in "value"
+// //! @return -1 if failed or value if it succeeds
+// int32_t i2c_read_byte_data(uint8_t address,     //!< 7-bit I2C address
+//                              uint8_t command,   //!< Command byte
+//                              uint8_t *value     //!< Byte to be read
+//                             );
+//
+// //! Write a byte of data to register specified by "command"
+// //! @return -1 if failed or 0 if it succeeds
+// int32_t i2c_write_byte_data(uint8_t address,    //!< 7-bit I2C address
+//                               uint8_t command,  //!< Command byte
+//                               uint8_t value     //!< Byte to be written
+//                              );
+//
+// //! Read a 16-bit word of data from register specified by "command"
+// //! @return -1 if failed or value if it succeeds
+// int32_t i2c_read_word_data(uint8_t address,     //!< 7-bit I2C address
+//                              uint8_t command,   //!< Command byte
+//                              uint16_t *value    //!< Word to be read
+//                             );
+//
+// //! Write a 16-bit word of data to register specified by "command"
+// //! @return -1 if failed or 0 if it succeeds
+// int32_t i2c_write_word_data(uint8_t address,    //!< 7-bit I2C address
+//                               uint8_t command,  //!< Command byte
+//                               uint16_t value    //!< Word to be written
+//                              );
+//
+//
+// //! Read a block of data, starting at register specified by "command" and ending at (command + length - 1)
+// //! @return Byte count
+// int32_t i2c_read_block_data(uint8_t address,    //!< 7-bit I2C address
+//                               uint8_t command,  //!< Command byte
+//                               uint8_t length,   //!< Length of array
+//                               uint8_t *values   //!< Byte array to be read
+//                              );
+//
+// //! Write a block of data, starting at register specified by "command" and ending at (command + length - 1)
+// //! @return Byte count
+// int32_t i2c_write_block_data(uint8_t address,       //!< 7-bit I2C address
+//                                uint8_t command,     //!< Command byte
+//                                uint8_t length,      //!< Length of array
+//                                uint8_t *values      //!< Byte array to be written
+//                               );
+//
+// //! Write a two command bytes, then receive a block of data
+// //! @return Byte count
+// int32_t i2c_two_byte_command_read_block(uint8_t address,    //!< 7-bit I2C address
+//                                         uint16_t command,   //!< Command word
+//                                         uint8_t length,     //!< Length of array
+//                                         uint8_t *values     //!< Byte array to be read
+//                                        );
+//
+// //! Initializes Linduino I2C port.
+// //! Before communicating to the I2C port through the QuikEval connector, you must also run
+// //! quikeval_I2C_connect to connect the I2C port to the QuikEval connector through the
+// //! QuikEval MUX (and disconnect SPI).
+// void quikeval_I2C_init(void);
+//
+// //! Switch MUX to connect I2C pins to QuikEval connector
+// //! This will disconnect SPI pins.
+// void quikeval_I2C_connect(void);
+//
+// //! Setup and enable the hardware I2C interface.
+// //! Must be called before using any of the other routines.
+// // 100kHz example:
+// //  uint8 bit_rate = 18;
+// //  hw_i2c_enable(bit_rate, HARDWARE_I2C_PRESCALER_4);
+// void i2c_enable(uint8_t bit_rate,   //!< I2C Bit Rate
+//                 uint8_t prescaler   //!< I2C prescaler
+//                );
+
+
+// LT I2C functions to emulate Linux SMBus functions for E-Z porting. There does not appear to be
+// a single source of the "correct" way to implement these functions.
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//// From http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/i2c/dev-interface
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//// You can do plain I2C transactions by using read(2) and write(2) calls.
+//// You do not need to pass the address byte; instead, set it through
+//// ioctl I2C_SLAVE before you try to access the device.
+////
+//// You can do SMBus level transactions (see documentation file smbus-protocol
+//// for details) through the following functions:
+//// __s32 i2c_smbus_write_quick(int file, __u8 value);
+//// __s32 i2c_smbus_read_byte(int file);
+//// __s32 i2c_smbus_write_byte(int file, __u8 value);
+//// __s32 i2c_smbus_read_byte_data(int file, __u8 command);
+//// __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);
+//// __s32 i2c_smbus_read_word_data(int file, __u8 command);
+//// __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
+//// __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
+//// __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
+//// __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
+////                                 // __u8 *values);
+//// All these transactions return -1 on failure; you can read errno to see
+//// what happened. The 'write' transactions return 0 on success; the
+//// 'read' transactions return the read value, except for read_block, which
+//// returns the number of values read. The block buffers need not be longer
+//// than 32 bytes.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+/*
+
+// Begin "LT-ified" versions of these functions:
+
+// Original Linux prototype: __s32 i2c_smbus_write_quick(int file, __u8 value);
+// Write a single bit in the R/W bit of the address. Note - we are using 8-bit addresses,
+// we should probably AND with 0xFE before appending the "value" bit. Also, should we obligate the user
+// to send a value with a "1" in the LSB, or any nonzero value to assert a 1?
+int8_t LT_i2c_write_quick(uint8_t address, uint8_t value);
+
+// Original Linux prototype: __s32 i2c_smbus_read_byte(int file);
+// Read a byte, store in "value".
+int8_t LT_i2c_read_byte(uint8_t address, uint8_t *value);
+
+// Original Linux prototype: __s32 i2c_smbus_write_byte(int file, __u8 value);
+// Write "value" byte to device at "address"
+int8_t LT_i2c_write_byte(uint8_t address, uint8_t value);
+
+// Original Linux prototype: __s32 i2c_smbus_read_byte_data(int file, __u8 command);
+// Read a byte of data at register specified by "command", store in "value"
+int8_t LT_i2c_read_byte_data(uint8_t address, uint8_t command, uint8_t *value);
+
+// Original Linux prototype: __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);
+// Write a byte of data to register specified by "command"
+int8_t LT_i2c_write_byte_data(uint8_t address, uint8_t command, uint8_t value);
+
+// Original Linux prototype: __s32 i2c_smbus_read_word_data(int file, __u8 command);
+// Read a 16-bit word of data from register specified by "command"
+int8_t LT_i2c_read_word_data(uint8_t address, uint8_t command, uint16_t *value);
+
+// Original Linux prototype: __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
+// Write a 16-bit word of data to register specified by "command"
+int8_t LT_i2c_write_word_data(uint8_t address, uint8_t command, uint16_t value);
+
+// Original Linux prototype: __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
+int8_t LT_i2c_process_call(uint8_t address, uint8_t command, uint16_t value);
+
+// For block read / write, this explains the lack of length parameter in some versions:
+// "Until kernel 2.6.22, the length is hard coded to 32 bytes. If you
+//   ask for less than 32 bytes, your code will only work with kernels
+//   2.6.23 and later."
+
+// Original Linux prototype: __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
+// Read a block of data, starting at register specified by "command" and ending at (command + length - 1)
+int8_t LT_i2c_read_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values);
+
+// Original Linux prototype: __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, __u8 *values);
+// Write a block of data, starting at register specified by "command" and ending at (command + length - 1)
+int8_t LT_i2c_write_block_data(uint8_t address, uint8_t command, uint8_t length, uint8_t *values);
+
+// Proposed additional function to handle cases like the LTC2495 / 97 / 99 family, which require
+// a 16-bit command, and can return either 3 or 4 bytes of data.
+// Write a two command bytes, then receive a block of data
+int8_t LT_i2c_two_byte_command_read_block(uint8_t address, uint16_t command, uint8_t length, uint8_t *values);
+
+*/
+
+#endif  // LT_I2C_H