summaryrefslogtreecommitdiff
path: root/recipes/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/i2c')
-rw-r--r--recipes/i2c/files/Config.h41
-rw-r--r--recipes/i2c/files/Crc8.c149
-rw-r--r--recipes/i2c/files/Crc8.h54
-rw-r--r--recipes/i2c/files/DumpMem.c93
-rw-r--r--recipes/i2c/files/DumpMem.h49
-rw-r--r--recipes/i2c/files/Log.c335
-rw-r--r--recipes/i2c/files/Log.h232
-rw-r--r--recipes/i2c/files/i2c-api.c522
-rw-r--r--recipes/i2c/files/i2c-api.h143
-rw-r--r--recipes/i2c/files/i2c-dev.h365
-rw-r--r--recipes/i2c/files/i2c-io-api.h52
-rw-r--r--recipes/i2c/files/i2c-io.h220
-rw-r--r--recipes/i2c/files/i2c.c710
-rw-r--r--recipes/i2c/files/i2c.h135
-rwxr-xr-xrecipes/i2c/files/i2c.init37
-rw-r--r--recipes/i2c/i2c.bb45
16 files changed, 3182 insertions, 0 deletions
diff --git a/recipes/i2c/files/Config.h b/recipes/i2c/files/Config.h
new file mode 100644
index 0000000000..83bb46de84
--- /dev/null
+++ b/recipes/i2c/files/Config.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file Config.h
+*
+* @brief Global Configuration information.
+*
+****************************************************************************/
+
+#if !defined( CONFIG_H )
+#define CONFIG_H /**< Include Guard */
+
+/* ---- Include Files ---------------------------------------------------- */
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+/**
+ * Sets Logging parameters
+ */
+
+#define CFG_LOG_TO_BUFFER 0
+
+#define CFG_CRC8BLOCK 1
+
+/** @} */
+
+#endif // CONFIG_H
+
diff --git a/recipes/i2c/files/Crc8.c b/recipes/i2c/files/Crc8.c
new file mode 100644
index 0000000000..87dcf5c2f4
--- /dev/null
+++ b/recipes/i2c/files/Crc8.c
@@ -0,0 +1,149 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file Crc8.c
+*
+* @brief This file contains the definition of the CRC-8 algorithim
+* used by SMBus
+*
+*
+*****************************************************************************/
+
+/* ---- Include Files ----------------------------------------------------- */
+
+#include "Config.h"
+
+#include "Crc8.h"
+
+#include "Log.h"
+
+/* ---- Public Variables -------------------------------------------------- */
+/* ---- Private Constants and Types --------------------------------------- */
+/* ---- Private Variables ------------------------------------------------- */
+/* ---- Private Function Prototypes --------------------------------------- */
+/* ---- Functions --------------------------------------------------------- */
+
+/****************************************************************************/
+/**
+* Calculates the CRC-8 used as part of SMBus.
+*
+* CRC-8 is defined to be x^8 + x^2 + x + 1
+*
+* To use this function use the following template:
+*
+* crc = Crc8( crc, data );
+*/
+
+#if 0 // Traditional implementation
+
+#define POLYNOMIAL (0x1070U << 3)
+
+unsigned char Crc8( unsigned char inCrc, unsigned char inData )
+{
+ int i;
+ unsigned short data;
+
+ data = inCrc ^ inData;
+ data <<= 8;
+
+ for ( i = 0; i < 8; i++ )
+ {
+ if (( data & 0x8000 ) != 0 )
+ {
+ data = data ^ POLYNOMIAL;
+ }
+ data = data << 1;
+ }
+
+#if 0
+#if defined( LogBuf2 )
+ LogBuf2( "Crc8: data:0x%02x crc:0x%02x\n", inData, (unsigned char)( data >> 8 ));
+#else
+
+ Log( "Crc8: data:0x%02x crc:0x%02x\n", inData, (unsigned char)( data >> 8 ));
+#endif
+
+#endif
+
+
+ return (unsigned char)( data >> 8 );
+
+} // Crc8
+
+#else // Optimized for 8 bit CPUs (0x22 bytes on ATMega128 versus 0x30 for above version)
+
+unsigned char Crc8( unsigned char inCrc, unsigned char inData )
+{
+ unsigned char i;
+ unsigned char data;
+
+ data = inCrc ^ inData;
+
+ for ( i = 0; i < 8; i++ )
+ {
+ if (( data & 0x80 ) != 0 )
+ {
+ data <<= 1;
+ data ^= 0x07;
+ }
+ else
+ {
+ data <<= 1;
+ }
+ }
+
+#if 0
+#if defined( LogBuf2 )
+ LogBuf2( "Crc8: data:0x%02x crc:0x%02x\n", inData, data );
+#else
+
+ Log( "Crc8: data:0x%02x crc:0x%02x\n", inData, data );
+#endif
+
+#endif
+
+
+ return data;
+
+} // Crc8
+
+#endif
+
+
+#if defined( CFG_CRC8BLOCK )
+
+/****************************************************************************/
+/**
+* Calculates the CRC-8 used as part of SMBus over a block of memory.
+*/
+
+uint8_t Crc8Block( uint8_t crc, uint8_t *data, uint8_t len )
+{
+ while ( len > 0 )
+ {
+ crc = Crc8( crc, *data++ );
+ len--;
+ }
+
+ return crc;
+
+} // Crc8Block
+
+#endif // CFG_CRC8BLOCK
+
+/** @} */
+
+
diff --git a/recipes/i2c/files/Crc8.h b/recipes/i2c/files/Crc8.h
new file mode 100644
index 0000000000..2d1f74b82c
--- /dev/null
+++ b/recipes/i2c/files/Crc8.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file Crc8.h
+*
+* @brief This file contains the definition of the CRC-8 algorithim
+* used by SMBus
+*
+****************************************************************************/
+
+#if !defined( CRC8_H )
+#define CRC_H ///< Include Guard
+
+/* ---- Include Files ----------------------------------------------------- */
+
+#include <inttypes.h>
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif
+
+
+/* ---- Constants and Types ---------------------------------------------- */
+/* ---- Variable Externs ------------------------------------------------- */
+/* ---- Function Prototypes ---------------------------------------------- */
+
+uint8_t Crc8( uint8_t crc, uint8_t data );
+
+uint8_t Crc8Block( uint8_t crc, uint8_t *data, uint8_t len );
+
+
+#if defined( __cplusplus )
+}
+#endif
+
+
+/** @} */
+
+#endif // CRC8_H
+
diff --git a/recipes/i2c/files/DumpMem.c b/recipes/i2c/files/DumpMem.c
new file mode 100644
index 0000000000..e13e94b0f8
--- /dev/null
+++ b/recipes/i2c/files/DumpMem.c
@@ -0,0 +1,93 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file DumpMem.c
+*
+* @brief Memmory dump routine
+*
+****************************************************************************/
+
+// ---- Include Files -------------------------------------------------------
+
+#include <inttypes.h>
+#include "DumpMem.h"
+#include "Log.h"
+
+// ---- Public Variables ----------------------------------------------------
+// ---- Private Constants and Types -----------------------------------------
+// ---- Private Variables ---------------------------------------------------
+// ---- Private Function Prototypes -----------------------------------------
+// ---- Functions -----------------------------------------------------------
+
+/**************************************************************************/
+/**
+* Dumps a page of output for debugging purposes.
+*/
+
+void DumpMem( const char *prefix, unsigned address, const void *inData, unsigned numBytes )
+{
+ const uint8_t *data = (const uint8_t *)inData;
+ unsigned byteOffset;
+
+ if ( numBytes == 0 )
+ {
+ Log( "%s: No data\n", prefix );
+ return;
+ }
+
+#define LINE_WIDTH 16
+
+ for ( byteOffset = 0; byteOffset < numBytes; byteOffset += LINE_WIDTH )
+ {
+ unsigned i;
+
+ Log( "%s: %04x: ", prefix, address + byteOffset );
+
+ for ( i = 0; i < LINE_WIDTH; i++ )
+ {
+ if (( byteOffset + i ) < numBytes )
+ {
+ Log( "%02.2X ", data[ byteOffset + i ] );
+ }
+ else
+ {
+ Log( " " );
+ }
+ }
+ for ( i = 0; i < LINE_WIDTH; i++ )
+ {
+ if (( byteOffset + i ) < numBytes )
+ {
+ unsigned char ch = data[ byteOffset + i ];
+ if (( ch < ' ' ) || ( ch > '~' ))
+ {
+ Log( "." );
+ }
+ else
+ {
+ Log( "%c", ch );
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ Log( "\n" );
+ }
+
+} // DumpMem
+
diff --git a/recipes/i2c/files/DumpMem.h b/recipes/i2c/files/DumpMem.h
new file mode 100644
index 0000000000..5d536f49e8
--- /dev/null
+++ b/recipes/i2c/files/DumpMem.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file DumpMem.h
+*
+* @brief Debug routine for dumping memory
+*
+****************************************************************************/
+
+#if !defined( DUMPMEM_H )
+#define DUMPMEM_H ///< Include Guard
+
+// ---- Include Files -------------------------------------------------------
+
+/**
+ * @addtogroup Log
+ * @{
+ */
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif
+
+
+void DumpMem( const char *prefix, unsigned address, const void *data, unsigned numBytes );
+
+#if defined( __cplusplus )
+}
+#endif
+
+
+/** @} */
+
+#endif // DUMPMEM_H
+
diff --git a/recipes/i2c/files/Log.c b/recipes/i2c/files/Log.c
new file mode 100644
index 0000000000..e32783391b
--- /dev/null
+++ b/recipes/i2c/files/Log.c
@@ -0,0 +1,335 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file Log.cpp
+*
+* @brief This file contains the implementation of the logging functions.
+*
+****************************************************************************/
+
+// ---- Include Files -------------------------------------------------------
+
+#include "Log.h"
+
+#if CFG_LOG_USE_STDIO
+# include <stdio.h>
+#else
+
+# include "Str.h"
+# include "UART.h"
+#endif
+
+
+// ---- Public Variables ----------------------------------------------------
+// ---- Private Constants and Types -----------------------------------------
+
+#if defined( AVR )
+
+#undef Log
+#undef LogError
+#undef vLog
+
+#define Log Log_P
+#define LogError LogError_P
+#define vLog vLog_P
+#define LogBuf LogBuf_P
+
+#define char prog_char
+
+#else
+
+
+#define PSTR(str) str
+
+int gVerbose = 0;
+int gDebug = 0;
+int gQuiet = 0;
+
+#endif
+
+
+#if CFG_LOG_TO_BUFFER
+
+volatile LOG_Buffer_t LOG_gBuffer;
+
+#endif
+
+
+// ---- Private Variables ---------------------------------------------------
+
+#if CFG_LOG_USE_STDIO
+
+FILE *gLogFs = NULL;
+
+#endif
+
+
+// ---- Private Function Prototypes -----------------------------------------
+
+// ---- Functions -----------------------------------------------------------
+
+/**
+ * @addtogroup Log
+ * @{
+ */
+
+#if !defined( AVR )
+
+void DefaultLogFunc( int logLevel, const char *fmt, va_list args )
+{
+ FILE *fs;
+
+ if ( gQuiet && ( logLevel == LOG_LEVEL_NORMAL ))
+ {
+ return;
+ }
+
+ if ( gLogFs == NULL )
+ {
+ fs = stderr;
+ }
+ else
+ {
+ fs = gLogFs;
+ }
+
+ if ( logLevel == LOG_LEVEL_ERROR )
+ {
+ fprintf( fs, "ERROR: " );
+ }
+ vfprintf( fs, fmt, args );
+ fflush( fs );
+
+} // DefaultLogFunc
+
+static LogFunc_t gLogFunc = DefaultLogFunc;
+
+void SetLogFunc( LogFunc_t logFunc )
+{
+
+ gLogFunc = logFunc;
+
+} // SetLogFunc
+
+#endif
+
+
+//***************************************************************************
+/**
+* Sets the logging stream
+*/
+
+#if CFG_LOG_USE_STDIO
+void LogInit( FILE *logFs )
+{
+ gLogFs = logFs;
+
+} // LogInit
+
+#else
+
+
+static int LogToUartFunc( void *outParm, int ch )
+{
+ UART0_PutChar( ch );
+
+ return 1;
+}
+#endif
+
+
+//***************************************************************************
+/**
+* Logs a string using printf like semantics
+*/
+
+void Log
+(
+ const char *fmt, ///< printf style format specifier
+ ... ///< variable list of arguments
+)
+{
+ va_list args;
+
+ va_start( args, fmt );
+ vLog( fmt, args );
+ va_end( args );
+}
+
+//***************************************************************************
+/**
+* Logs a string using printf like semantics
+*/
+
+void vLog
+(
+ const char *fmt, ///< printf style format specified
+ va_list args ///< variable list of arguments
+)
+{
+ // For now we call printf directly. A better way would be to install
+ // a callback which does the real work
+
+#if defined( AVR )
+# if CFG_LOG_USE_STDIO
+ if ( gLogFs != NULL )
+ {
+ vfprintf_P( gLogFs, fmt, args );
+ }
+# else
+
+ vStrXPrintf_P( LogToUartFunc, NULL, fmt, args );
+# endif
+
+#else
+
+ if ( gLogFunc != NULL )
+ {
+ gLogFunc( LOG_LEVEL_NORMAL, fmt, args );
+ }
+#endif
+
+}
+
+#if !defined( AVR )
+
+//***************************************************************************
+/**
+* Logs an error.
+*/
+
+void vLogError
+(
+ const char *fmt, ///< printf style format specified
+ va_list args ///< variable list of arguments
+)
+{
+ if ( gLogFunc != NULL )
+ {
+ gLogFunc( LOG_LEVEL_ERROR, fmt, args );
+ }
+}
+
+#endif
+
+
+/***************************************************************************/
+/**
+* Logs an error
+*/
+
+void LogError
+(
+ const char *fmt, ///< printf style format specifier
+ ... ///< variable list of arguments
+)
+{
+ va_list args;
+
+#if defined( AVR )
+ //Log( "ERROR: " );
+ //Log_P( PSTR( "ERROR: " ));
+
+ va_start( args, fmt );
+ vLog( fmt, args );
+ va_end( args );
+#else
+
+ va_start( args, fmt );
+ vLogError( fmt, args );
+ va_end( args );
+#endif
+
+
+} // LogError
+
+/***************************************************************************/
+/**
+* Logs an entry to the log buffer
+*/
+
+#if CFG_LOG_TO_BUFFER
+
+void LogBuf( const char *fmt, uint8_t arg1, uint8_t arg2 LOG_EXTRA_PARAMS_DECL )
+{
+#if defined( AVR )
+ uint8_t sreg = SREG;
+ cli();
+#endif
+
+
+ if ( CBUF_IsFull( LOG_gBuffer ))
+ {
+ volatile LOG_Entry_t *entry = CBUF_GetLastEntryPtr( LOG_gBuffer );
+
+ entry->fmt = PSTR( "*** Lost Messages ***\n" );
+ }
+ else
+ {
+ volatile LOG_Entry_t *entry = CBUF_GetPushEntryPtr( LOG_gBuffer );
+
+ entry->fmt = fmt;
+ entry->param1 = arg1;
+ entry->param2 = arg2;
+
+#if CFG_LOG_EXTRA_PARAMS
+ entry->param3 = arg3;
+ entry->param4 = arg4;
+#endif
+
+
+ CBUF_AdvancePushIdx( LOG_gBuffer );
+ }
+
+#if defined( AVR )
+ SREG = sreg;
+#endif
+
+
+} // LogBuf
+
+#endif // CFG_LOG_TO_BUFFER
+
+/***************************************************************************/
+/**
+* Dumps any unlogged entries from the log buffer
+*/
+
+#if CFG_LOG_TO_BUFFER
+
+void LogBufDump( void )
+{
+ while ( !CBUF_IsEmpty( LOG_gBuffer ))
+ {
+ volatile LOG_Entry_t *entry = CBUF_GetPopEntryPtr( LOG_gBuffer );
+
+#if CFG_LOG_EXTRA_PARAMS
+ Log( entry->fmt, entry->param1, entry->param2, entry->param3, entry->param4 );
+#else
+
+ Log( entry->fmt, entry->param1, entry->param2 );
+#endif
+
+
+ CBUF_AdvancePopIdx( LOG_gBuffer );
+ }
+
+} // LogBufDump
+
+#endif // CFG_LOG_TO_BUFFER
+
+/** @} */
+
diff --git a/recipes/i2c/files/Log.h b/recipes/i2c/files/Log.h
new file mode 100644
index 0000000000..d12d482fc6
--- /dev/null
+++ b/recipes/i2c/files/Log.h
@@ -0,0 +1,232 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file Log.h
+*
+* @brief Contains some logging macros.
+*
+****************************************************************************/
+/**
+* @defgroup Log Logging
+*
+* @brief Provides a common interface for logging.
+*
+****************************************************************************/
+
+#if !defined( LOG_H )
+#define LOG_H ///< Include Guard
+
+// ---- Include Files -------------------------------------------------------
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#if !defined( CONFIG_H )
+# include "Config.h"
+#endif
+
+#if !defined( CFG_LOG_USE_STDIO )
+# define CFG_LOG_USE_STDIO 1
+#endif
+
+
+#if defined( AVR )
+# include <avr/pgmspace.h>
+# include <avr/interrupt.h>
+#endif
+
+
+#if CFG_LOG_TO_BUFFER
+# if !defined( CBUF_H )
+# include "CBUF.h"
+# endif
+
+#endif
+
+
+
+/**
+ * @addtogroup Log
+ * @{
+ */
+
+#if !defined( CFG_LOG_ENABLED )
+# define CFG_LOG_ENABLED 1
+#endif
+
+
+#if !CFG_LOG_ENABLED
+
+#define Log( fmt, args... )
+#define LogError( fmt, args... )
+
+#else
+
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif
+
+
+/***************************************************************************
+*
+* Log Buffer support
+*/
+
+#if CFG_LOG_TO_BUFFER
+
+#if defined( AVR )
+
+typedef struct
+{
+ const prog_char *fmt;
+ uint8_t param1;
+ uint8_t param2;
+#if CFG_LOG_EXTRA_PARAMS
+ uint8_t param3;
+ uint8_t param4;
+#endif
+
+
+} LOG_Entry_t;
+
+#if CFG_LOG_EXTRA_PARAMS
+# define LOG_EXTRA_PARAMS_DECL , uint8_t arg3, uint8_t arg4
+# define LOG_EXTRA_PARAMS , 0, 0
+#else
+
+# define LOG_EXTRA_PARAMS_DECL
+# define LOG_EXTRA_PARAMS
+#endif
+
+
+void LogBuf_P( const prog_char *fmt, uint8_t arg1, uint8_t arg2 LOG_EXTRA_PARAMS_DECL );
+
+#define LogBuf0( fmt ) LogBuf_P( PSTR( fmt ), 0, 0 LOG_EXTRA_PARAMS )
+#define LogBuf1( fmt, arg1 ) LogBuf_P( PSTR( fmt ), arg1, 0 LOG_EXTRA_PARAMS )
+#define LogBuf2( fmt, arg1, arg2 ) LogBuf_P( PSTR( fmt ), arg1, arg2 LOG_EXTRA_PARAMS )
+
+#if CFG_LOG_EXTRA_PARAMS
+#define LogBuf3( fmt, arg1, arg2, arg3 ) LogBuf_P( PSTR( fmt ), arg1, arg2, arg3, 0 )
+#define LogBuf4( fmt, arg1, arg2, arg3, arg4 ) LogBuf_P( PSTR( fmt ), arg1, arg2, arg3, arg4 )
+#endif
+
+
+#else
+
+
+typedef struct
+{
+ const char *fmt;
+ uint8_t param1;
+ uint8_t param2;
+
+} LOG_Entry_t;
+
+void LogBuf( const char *fmt, uint8_t arg1, uint8_t arg2 );
+
+#define LogBuf0( fmt, arg1 ) LogBuf( fmt, 0, 0 )
+#define LogBuf1( fmt, arg1 ) LogBuf( fmt, arg1, 0 )
+#define LogBuf2( fmt, arg1, arg2 ) LogBuf( fmt, arg1, arg2 )
+
+#endif // AVR
+
+#if ( CFG_LOG_NUM_BUFFER_ENTRIES > 128 )
+typedef uint16_t LOG_BufferIdx_t;
+#else
+
+typedef uint8_t LOG_BufferIdx_t;
+#endif
+
+
+typedef struct
+{
+ LOG_BufferIdx_t m_getIdx;
+ LOG_BufferIdx_t m_putIdx;
+ LOG_Entry_t m_entry[ CFG_LOG_NUM_BUFFER_ENTRIES ];
+
+} LOG_Buffer_t;
+
+extern volatile LOG_Buffer_t LOG_gBuffer;
+
+#define LOG_gBuffer_SIZE ( sizeof( LOG_gBuffer.m_entry ) / sizeof( LOG_gBuffer.m_entry[ 0 ] ))
+
+void LogBufDump( void );
+
+#endif // CFG_LOG_TO_BUFFER
+
+/***************************************************************************
+*
+* Regular logging support
+*/
+
+#if CFG_LOG_USE_STDIO
+extern FILE *gLogFs;
+
+void LogInit( FILE *logFs );
+#endif
+
+
+#if defined( AVR )
+
+void Log_P( const prog_char *fmt, ... );
+void LogError_P( const prog_char *fmt, ... );
+void vLog_P( const prog_char *fmt, va_list args );
+
+#define Log( fmt, args... ) Log_P( PSTR( fmt ), ## args )
+#define LogError( fmt, args... ) LogError_P( PSTR( fmt ), ## args )
+#define vLog( fmt, va_list, args ) vLog_P( PSTR( fmt ), args )
+
+#else // AVR
+
+#define LOG_LEVEL_NORMAL 0
+#define LOG_LEVEL_ERROR 1
+
+typedef void (*LogFunc_t)( int logLevel, const char *fmt, va_list args );
+
+extern int gVerbose;
+extern int gDebug;
+extern int gQuiet;
+
+void Log( const char *fmt, ... );
+void LogError( const char *fmt, ... );
+void vLog( const char *fmt, va_list args );
+void vLogError( const char *fmt, va_list args );
+
+#define Log_P( fmt, args... ) Log( fmt, ## args )
+#define LogError_P( fmt, args... ) LogError( fmt, ## args )
+#define vLog_P( fmt, args ) vLog( fmt, args )
+
+#define LogDebug( fmt, args... ) do { if ( gDebug ) { Log( fmt, ## args ); }} while (0)
+#define LogVerbose( fmt, args... ) do { if ( gVerbose ) { Log( fmt, ## args ); }} while (0)
+
+void SetLogFunc( LogFunc_t logFunc );
+void DefaultLogFunc( int logLevel, const char *fmt, va_list args );
+
+#endif // AVR
+
+#if defined( __cplusplus )
+}
+#endif
+
+
+#endif // CFG_LOG_ENABLED
+
+/** @} */
+
+#endif // LOG_H
+
diff --git a/recipes/i2c/files/i2c-api.c b/recipes/i2c/files/i2c-api.c
new file mode 100644
index 0000000000..cfc41565a4
--- /dev/null
+++ b/recipes/i2c/files/i2c-api.c
@@ -0,0 +1,522 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file i2c-api.c
+*
+* @brief This file contains the implementation for performing I2C operations
+* on the gumstix.
+*
+****************************************************************************/
+
+// ---- Include Files -------------------------------------------------------
+
+#include <string.h>
+#include <errno.h>
+
+#include "i2c.h"
+#include "i2c-dev.h"
+#include "i2c-api.h"
+
+#include "Crc8.h"
+#include "DumpMem.h"
+#include "Log.h"
+
+// ---- Public Variables ----------------------------------------------------
+
+// ---- Private Constants and Types -----------------------------------------
+
+// ---- Private Variables ---------------------------------------------------
+
+static I2C_Addr_t gI2cAddr;
+static int gUseCrc;
+
+// ---- Private Function Prototypes -----------------------------------------
+
+// ---- Functions -----------------------------------------------------------
+
+//***************************************************************************
+/**
+*
+* Sets the I2C address that we'll be communicating with, as well as whether
+* the device uses smbus PEC (CRC).
+*/
+
+void I2cSetSlaveAddress( int i2cDev, I2C_Addr_t i2cAddr, int useCrc )
+{
+ gI2cAddr = i2cAddr;
+ gUseCrc = useCrc;
+
+ LogDebug( "----- I2cSetSlaveAddress i2cAddr:0x%02x useCrc:%d -----\n",
+ i2cAddr, useCrc );
+
+ // Indicate which slave we wish to speak to
+
+ if ( ioctl( i2cDev, I2C_SLAVE, gI2cAddr ) < 0 )
+ {
+ LogError( "I2cSetSlaveAddress: Error trying to set slave address to 0x%02x (%d %s)\n",
+ gI2cAddr, errno, strerror( errno ));
+ }
+
+ // We do the CRC calculation ourself, so we don't need to tell the driver
+ // that we're using it.
+
+#if 0
+ // Indicate that we use PEC (aka CRCs)
+
+ if ( ioctl( i2cDev, I2C_PEC, 1 ) < 0 )
+ {
+ LogError( "I2cSetSlaveAddress: Error trying to set PEC mode\n" );
+ }
+#endif
+
+} // I2cSetSlaveAddress
+
+//***************************************************************************
+/**
+* Transfer data to/from an i2c device.
+*
+* This function implements the equivalent of the smbus functions using
+* I2C_RDWR.
+*
+* The PXA driver doesn't support the smbus transfers.
+*
+* This function can perform the following SMBUS transactions:
+*
+* Write Byte: wrLen == 1, rdLen == 0
+* Read Byte: wrLen == 0, rdLen == 1
+* Write Word: wrLen == 2, rdLen == 0
+* Read Word: wrLen == 0, rdLen == 2
+* Process Call: wrLen == 2, rdLen == 2
+* Write Block: wrLen == 0x80 + numBytes, rdLen == 0
+* Read Block: wrLen == 0, rdLen == 0x80 + numBytes
+* Process Block: wrLen == 0x80 + numBytes, rdLen == 0x80 + numBytes
+*/
+
+int I2cTransfer
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ const void *wrData, ///< Data to write
+ uint8_t wrLen, ///< Number of bytes to write (or in 0x80 for a block write)
+ void *rdData, ///< Place to store data read
+ uint8_t rdLen, ///< Number of bytes to read (or in 0x80 for a block read)
+ uint8_t *bytesReadp ///< Place to store number of bytes read
+)
+{
+ struct i2c_rdwr_ioctl_data rdwr;
+ struct i2c_msg msg[ 2 ];
+ uint8_t wrBuf[ I2C_MAX_DATA_LEN + 3 ]; // +1 for cmd, +1 for len, +1 for CRC
+ uint8_t rdBuf[ I2C_MAX_DATA_LEN + 2 ]; // +1 for len, +1 for CRC
+ uint8_t crc = 0;
+ uint8_t wrBlock = (( wrLen & 0x80 ) != 0 );
+ uint8_t rdBlock = (( rdLen & 0x80 ) != 0 );
+ int rc = 0;
+
+ LogDebug( "----- I2cTransfer: cmd:0x%02x wrLen:0x%02x rdLen:0x%02x wrBlock:%d rdBlock:%d -----\n",
+ cmd, wrLen, rdLen, wrBlock, rdBlock );
+ if ( wrData != NULL )
+ {
+ LogDebug( "----- wrData:0x%08x *wrData:0x%02x -----\n", wrData, *(const uint8_t *)wrData );
+ }
+
+ rdLen &= 0x7f;
+ wrLen &= 0x7f;
+
+ if ( bytesReadp != NULL )
+ {
+ *bytesReadp = 0;
+ }
+
+ if ( wrLen > I2C_MAX_DATA_LEN )
+ {
+ LogError( "I2cTransfer: wrLen too big: %d, max is %d\n",
+ wrLen, I2C_MAX_DATA_LEN );
+ errno = ENOBUFS;
+ return -1;
+ }
+
+ if ( rdLen > I2C_MAX_DATA_LEN )
+ {
+ LogError( "I2cTransfer: rdLen too big: %d, max is %d\n",
+ rdLen, I2C_MAX_DATA_LEN );
+ errno = ENOBUFS;
+ return -1;
+ }
+
+ // Whether we're doing a read or a write, we always send
+ // the command.
+
+ msg[ 0 ].addr = gI2cAddr;
+ msg[ 0 ].flags = 0;
+ msg[ 0 ].len = wrLen + 1 + wrBlock; // +1 for cmd
+ msg[ 0 ].buf = (char *)&wrBuf[ 0 ];
+
+ if ( gUseCrc )
+ {
+ crc = Crc8( 0, gI2cAddr << 1 );
+ crc = Crc8( crc, cmd );
+ }
+
+ wrBuf[ 0 ] = cmd;
+
+ if ( wrLen > 0 )
+ {
+ // We have some data to send down to the device
+
+ if ( wrBlock )
+ {
+ wrBuf[ 1 ] = wrLen;
+ memcpy( &wrBuf[ 2 ], wrData, wrLen );
+ wrLen++; // Add in cmd to the length
+ }
+ else
+ {
+ memcpy( &wrBuf[ 1 ], wrData, wrLen );
+ }
+ if ( gUseCrc )
+ {
+ crc = Crc8Block( crc, &wrBuf[ 1 ], wrLen );
+
+ if ( rdLen == 0 )
+ {
+ // This is a write-only, so we need to send the CRC
+
+ wrBuf[ wrLen + 1 ] = crc;
+ msg[ 0 ].len++;
+ }
+ }
+ }
+
+ if ( gDebug )
+ {
+ Log( "msg[ 0 ].addr = 0x%02x\n", msg[ 0 ].addr );
+ Log( "msg[ 0 ].flags = 0x%04x\n", msg[ 0 ].flags );
+ Log( "msg[ 0 ].len = %d\n", msg[ 0 ].len );
+ DumpMem( "I2cTransfer W", 0, &wrBuf[ 0 ], msg[ 0 ].len );
+ }
+
+ rdwr.msgs = msg;
+ rdwr.nmsgs = 1;
+
+ if ( rdLen > 0 )
+ {
+ // We're expecting some data to come back
+
+ msg[ 1 ].addr = gI2cAddr;
+ msg[ 1 ].flags = I2C_M_RD;
+ msg[ 1 ].len = rdLen + rdBlock + gUseCrc;
+ msg[ 1 ].buf = (char *)&rdBuf[ 0 ];
+
+ rdwr.nmsgs = 2;
+
+ if ( gUseCrc )
+ {
+ crc = Crc8( crc, ( gI2cAddr << 1 ) | 1 );
+ }
+
+ if ( gDebug )
+ {
+ Log( "msg[ 1 ].addr = 0x%02x\n", msg[ 1 ].addr );
+ Log( "msg[ 1 ].flags = 0x%04x\n", msg[ 1 ].flags );
+ Log( "msg[ 1 ].len = %d\n", msg[ 1 ].len );
+ }
+ }
+
+ if ( ioctl( i2cDev, I2C_RDWR, &rdwr ) < 0 )
+ {
+ LogError( "I2cTransfer: ioctl failed: %s (%d)\n", strerror( errno ), errno );
+ return -1;
+ }
+
+ if ( rdLen > 0 )
+ {
+ if ( rdBlock )
+ {
+ if ( rdBuf[ 0 ] > rdLen )
+ {
+ LogError( "I2cTransfer: length is too big: %d max: %d\n", rdBuf[ 0 ], rdLen );
+
+ rc = EMSGSIZE;
+ }
+ else
+ {
+ rdLen = rdBuf[ 0 ];
+ }
+ }
+
+ if ( gUseCrc )
+ {
+ crc = Crc8Block( crc, &rdBuf[ 0 ], rdLen + rdBlock );
+
+ if ( crc != rdBuf[ rdLen + rdBlock ] )
+ {
+ LogError( "I2cTransfer: CRC failed: Rcvd: 0x%02x, expecting: 0x%02x\n",
+ rdBuf[ rdLen + rdBlock ], crc );
+ rc = EBADMSG;
+ }
+ }
+
+ if ( gDebug )
+ {
+ DumpMem( "I2cTransfer R", 0, &rdBuf[ 0 ], msg[ 1 ].len );
+ }
+ memcpy( rdData, &rdBuf[ rdBlock ], rdLen );
+
+ if ( bytesReadp != NULL )
+ {
+ *bytesReadp = rdLen;
+ }
+ }
+ return rc;
+
+} // I2cTransfer
+
+//***************************************************************************
+/**
+* Uses the SMBUS Process-Block protocol to read data from a device.
+*/
+
+int I2cProcessBlock
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ const void *wrData, ///< Data to write
+ uint8_t wrLen, ///< Number of bytes to write
+ void *rdData, ///< Place to store data read
+ uint8_t rdLen, ///< Number of bytes to read
+ uint8_t *bytesReadp ///< Place to store number of bytes read
+)
+{
+ LogDebug( "----- I2cProcessBlock cmd: 0x%02x wrLen:0x%02x rdLen:0x%02x -----\n", cmd, wrLen, rdLen );
+
+ return I2cTransfer( i2cDev, cmd, wrData, 0x80 | wrLen, rdData, 0x80 | rdLen, bytesReadp );
+
+} // I2cProcessBlock
+
+//***************************************************************************
+/**
+* Uses the SMBUS Read-Block protocol to read data from a device.
+*/
+
+int I2cReadBlock
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ void *rdData, ///< Place to store data read
+ uint8_t rdLen, ///< Number of bytes to read
+ uint8_t *bytesReadp ///< Place to store number of bytes read
+)
+{
+ LogDebug( "----- I2cReadBlock cmd: 0x%02x rdLen:0x%02x -----\n", cmd, rdLen );
+
+ return I2cTransfer( i2cDev, cmd, NULL, 0, rdData, 0x80 | rdLen, bytesReadp );
+
+} // I2cReadBlock
+
+//***************************************************************************
+/**
+* Uses the SMBUS Read-Byte protocol to read a byte.
+*/
+
+int I2cReadByte
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ uint8_t *rdByte ///< Place to store byte read
+)
+{
+ LogDebug( "----- I2cReadByte cmd: 0x%02x -----\n", cmd );
+
+ return I2cTransfer( i2cDev, cmd, NULL, 0, rdByte, 1, NULL );
+
+} // I2cReadByte
+
+//***************************************************************************
+/**
+* Reads an array of bytes usinng i2c (not compatible with SMBUS)
+*/
+
+int I2cReadBytes
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ void *rdByte, ///< Place to store bytes read
+ uint8_t rdLen ///< Number of bytes to read
+)
+{
+ LogDebug( "----- I2cReadBytes cmd: 0x%02x rdLen: 0x%02x -----\n", cmd, rdLen );
+
+ return I2cTransfer( i2cDev, cmd, NULL, 0, rdByte, rdLen, NULL );
+
+} // I2cReadBytes
+
+//***************************************************************************
+/**
+* Uses the SMBUS Write-Block protocol to write data from a device.
+*/
+
+int I2cWriteBlock
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ const void *wrData, ///< Data to write
+ uint8_t wrLen ///< Number of bytes to write
+)
+{
+ LogDebug( "----- I2cWriteBlock cmd: 0x%02x wrLen:0x%02x -----\n", cmd, wrLen );
+
+ return I2cTransfer( i2cDev, cmd, wrData, 0x80 | wrLen, NULL, 0, NULL );
+
+} // I2cWriteBlock
+
+//***************************************************************************
+/**
+* Uses the SMBUS Write-Byte protocol to write a byte.
+*/
+
+int I2cWriteByte
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ uint8_t wrByte ///< Byte to write
+)
+{
+ LogDebug( "----- I2cWriteByte cmd: 0x%02x wrByte:0x%02x -----\n", cmd, wrByte );
+ LogDebug( "----- &wrByte = 0x%08x wrByte = 0x%02x -----\n", &wrByte, *&wrByte );
+
+ return I2cTransfer( i2cDev, cmd, &wrByte, 1, NULL, 0, NULL );
+
+} // I2cWriteByte
+
+//***************************************************************************
+/**
+* Writes an array of bytes using i2c (not compatible with SMBUS)
+*/
+
+int I2cWriteBytes
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ const void *wrByte, ///< Bytes to write
+ uint8_t wrLen ///< Number of bytes to write
+)
+{
+ LogDebug( "----- I2cWriteBytes cmd: 0x%02x wrLen: 0x%02x -----\n", cmd, wrLen );
+
+ return I2cTransfer( i2cDev, cmd, wrByte, wrLen, NULL, 0, NULL );
+
+} // I2cWriteBytes
+
+//***************************************************************************
+/**
+* Uses the SMBUS Receive-Byte protocol to read a byte.
+*/
+
+int I2cReceiveByte
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t *rdByte ///< Place to store byte read
+)
+{
+ return I2cReceiveBytes( i2cDev, rdByte, 1 );
+
+} // I2cReceiveByte
+
+//***************************************************************************
+/**
+* Uses the SMBUS Receive-Byte protocol to read multiple (or one or zero) bytes.
+*/
+
+int I2cReceiveBytes
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t *rdData, ///< Place to store data read
+ uint8_t rdLen ///< Number of bytes to read
+)
+{
+ struct i2c_rdwr_ioctl_data rdwr;
+ struct i2c_msg msg;
+
+ LogDebug( "----- I2cReceiveBytes -----\n" );
+
+ msg.addr = gI2cAddr;
+ msg.flags = I2C_M_RD;
+ msg.len = rdLen;
+ msg.buf = (char *)rdData;
+
+ rdwr.msgs = &msg;
+ rdwr.nmsgs = 1;
+
+ if ( ioctl( i2cDev, I2C_RDWR, &rdwr ) < 0 )
+ {
+ LogError( "I2cReceiveBytes: ioctl failed: %s (%d)\n", strerror( errno ), errno );
+ return -1;
+ }
+
+ return 0;
+
+} // I2cReceiveBytes
+
+//***************************************************************************
+/**
+* Uses the SMBUS Send-Byte protocol to write a byte.
+*/
+
+int I2cSendByte
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t wrByte ///< Byte to write
+)
+{
+ return I2cSendBytes( i2cDev, &wrByte, 1 );
+
+} // I2cSendByte
+
+//***************************************************************************
+/**
+* Uses the SMBUS Send-Byte protocol to write multiple (or zero or one) bytes.
+*/
+
+int I2cSendBytes
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t *wrData, ///< Pointer to data to write
+ uint8_t wrLen ///< NUmber of bytes to write
+)
+{
+ struct i2c_rdwr_ioctl_data rdwr;
+ struct i2c_msg msg;
+
+ LogDebug( "----- I2cSendBytes wrLen = 0x%02x -----\n", wrLen );
+
+ msg.addr = gI2cAddr;
+ msg.flags = 0;
+ msg.len = wrLen;
+ msg.buf = (char *)wrData;
+
+ rdwr.msgs = &msg;
+ rdwr.nmsgs = 1;
+
+ if ( ioctl( i2cDev, I2C_RDWR, &rdwr ) < 0 )
+ {
+ LogError( "I2cSendBytes: ioctl failed: %s (%d)\n", strerror( errno ), errno );
+ return -1;
+ }
+
+ return 0;
+
+} // I2cSendBytes
+
diff --git a/recipes/i2c/files/i2c-api.h b/recipes/i2c/files/i2c-api.h
new file mode 100644
index 0000000000..73f9f20990
--- /dev/null
+++ b/recipes/i2c/files/i2c-api.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file i2c-api.h
+*
+* @brief This file contains definitions for performing i2c operations
+* on the gumstix.
+*
+****************************************************************************/
+
+#if !defined( I2C_API_H )
+#define I2C_API_H
+
+// ---- Include Files -------------------------------------------------------
+
+#include <inttypes.h>
+#include "i2c.h"
+
+// ---- Constants and Types -------------------------------------------------
+
+#define I2C_USE_CRC 1
+#define I2C_NO_CRC 0
+
+// ---- Variable Externs ----------------------------------------------------
+
+// ---- Function Prototypes -------------------------------------------------
+
+void I2cSetSlaveAddress
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ I2C_Addr_t i2cAddr, ///< 7 bit i2c address to use
+ int useCrc ); ///< Should CRC's be used?
+
+int I2cTransfer
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ const void *wrData, ///< Data to write
+ uint8_t wrLen, ///< Number of bytes to write (or in 0x80 for a block write)
+ void *rdData, ///< Place to store data read
+ uint8_t rdLen, ///< Number of bytes to read (or in 0x80 for a block read)
+ uint8_t *bytesReadp ///< Place to store number of bytes read
+);
+
+int I2cProcessBlock
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ const void *wrData, ///< Data to write
+ uint8_t wrLen, ///< Number of bytes to write
+ void *rdData, ///< Place to store data read
+ uint8_t rdLen, ///< Number of bytes to read
+ uint8_t *bytesReadp ///< Place to store number of bytes read
+);
+
+int I2cReadBlock
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ void *rdData, ///< Place to store data read
+ uint8_t rdLen, ///< Number of bytes to read
+ uint8_t *bytesReadp ///< Place to store number of bytes read
+);
+
+int I2cReadByte
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ uint8_t *rdByte ///< Place to store byte to read
+);
+
+int I2cReadBytes
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ void *rdByte, ///< Place to store bytes read
+ uint8_t rdLen ///< Number of bytes to read
+);
+
+int I2cWriteBlock
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ const void *wrData, ///< Data to write
+ uint8_t wrLen ///< Number of bytes to write
+);
+
+int I2cWriteByte
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ uint8_t wrByte ///< Byte to write
+);
+
+int I2cWriteBytes
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t cmd, ///< Command to send
+ const void *wrByte, ///< Bytes to write
+ uint8_t wrLen ///< Number of bytes to write
+);
+
+int I2cReceiveByte
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t *rdByte ///< Place to store byte read
+);
+
+int I2cReceiveBytes
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t *rdData, ///< Place to store byte read
+ uint8_t rdLen ///< Number of bytes to read
+);
+
+int I2cSendByte
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t wrByte ///< Byte to write
+);
+
+int I2cSendBytes
+(
+ int i2cDev, ///< Handle to i2c-dev file
+ uint8_t *wrData, ///< Pointer to data to write.
+ uint8_t wrLen ///< Number of bytes to write.
+);
+
+#endif // I2C_API_H
+
diff --git a/recipes/i2c/files/i2c-dev.h b/recipes/i2c/files/i2c-dev.h
new file mode 100644
index 0000000000..cd20965ede
--- /dev/null
+++ b/recipes/i2c/files/i2c-dev.h
@@ -0,0 +1,365 @@
+/*
+ i2c-dev.h - i2c-bus driver, char device interface
+
+ Copyright (C) 1995-97 Simon G. Vogl
+ Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* $Id: i2c-dev.h,v 1.4 2003/11/27 23:08:06 tat Exp $ */
+
+#ifndef LIB_I2CDEV_H
+#define LIB_I2CDEV_H
+
+#include <linux/types.h>
+#include <sys/ioctl.h>
+
+
+/* -- i2c.h -- */
+
+
+/*
+ * I2C Message - used for pure i2c transaction, also from /dev interface
+ */
+struct i2c_msg {
+ __u16 addr; /* slave address */
+ unsigned short flags;
+#define I2C_M_TEN 0x10 /* we have a ten bit chip address */
+#define I2C_M_RD 0x01
+#define I2C_M_NOSTART 0x4000
+#define I2C_M_REV_DIR_ADDR 0x2000
+#define I2C_M_IGNORE_NAK 0x1000
+#define I2C_M_NO_RD_ACK 0x0800
+ short len; /* msg length */
+ char *buf; /* pointer to msg data */
+};
+
+/* To determine what functionality is present */
+
+#define I2C_FUNC_I2C 0x00000001
+#define I2C_FUNC_10BIT_ADDR 0x00000002
+#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
+#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_QUICK 0x00010000
+#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
+#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
+#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
+#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */
+
+#define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \
+ I2C_FUNC_SMBUS_WRITE_BYTE
+#define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA
+#define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \
+ I2C_FUNC_SMBUS_WRITE_WORD_DATA
+#define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA
+#define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
+#define I2C_FUNC_SMBUS_I2C_BLOCK_2 I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \
+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2
+#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC
+#define I2C_FUNC_SMBUS_WORD_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \
+ I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC
+
+#define I2C_FUNC_SMBUS_READ_BYTE_PEC I2C_FUNC_SMBUS_READ_BYTE_DATA
+#define I2C_FUNC_SMBUS_WRITE_BYTE_PEC I2C_FUNC_SMBUS_WRITE_BYTE_DATA
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA_PEC I2C_FUNC_SMBUS_WRITE_WORD_DATA
+#define I2C_FUNC_SMBUS_BYTE_PEC I2C_FUNC_SMBUS_BYTE_DATA
+#define I2C_FUNC_SMBUS_BYTE_DATA_PEC I2C_FUNC_SMBUS_WORD_DATA
+
+#define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \
+ I2C_FUNC_SMBUS_BYTE | \
+ I2C_FUNC_SMBUS_BYTE_DATA | \
+ I2C_FUNC_SMBUS_WORD_DATA | \
+ I2C_FUNC_SMBUS_PROC_CALL | \
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \
+ I2C_FUNC_SMBUS_I2C_BLOCK
+
+/*
+ * Data for SMBus Messages
+ */
+#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
+#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */
+union i2c_smbus_data {
+ __u8 byte;
+ __u16 word;
+ __u8 block[I2C_SMBUS_BLOCK_MAX + 3]; /* block[0] is used for length */
+ /* one more for read length in block process call */
+ /* and one more for PEC */
+};
+
+/* smbus_access read or write markers */
+#define I2C_SMBUS_READ 1
+#define I2C_SMBUS_WRITE 0
+
+/* SMBus transaction types (size parameter in the above functions)
+ Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
+#define I2C_SMBUS_QUICK 0
+#define I2C_SMBUS_BYTE 1
+#define I2C_SMBUS_BYTE_DATA 2
+#define I2C_SMBUS_WORD_DATA 3
+#define I2C_SMBUS_PROC_CALL 4
+#define I2C_SMBUS_BLOCK_DATA 5
+#define I2C_SMBUS_I2C_BLOCK_DATA 6
+#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
+#define I2C_SMBUS_BLOCK_DATA_PEC 8 /* SMBus 2.0 */
+#define I2C_SMBUS_PROC_CALL_PEC 9 /* SMBus 2.0 */
+#define I2C_SMBUS_BLOCK_PROC_CALL_PEC 10 /* SMBus 2.0 */
+#define I2C_SMBUS_WORD_DATA_PEC 11 /* SMBus 2.0 */
+
+
+/* ----- commands for the ioctl like i2c_command call:
+ * note that additional calls are defined in the algorithm and hw
+ * dependent layers - these can be listed here, or see the
+ * corresponding header files.
+ */
+ /* -> bit-adapter specific ioctls */
+#define I2C_RETRIES 0x0701 /* number of times a device address */
+ /* should be polled when not */
+ /* acknowledging */
+#define I2C_TIMEOUT 0x0702 /* set timeout - call with int */
+
+
+/* this is for i2c-dev.c */
+#define I2C_SLAVE 0x0703 /* Change slave address */
+ /* Attn.: Slave address is 7 or 10 bits */
+#define I2C_SLAVE_FORCE 0x0706 /* Change slave address */
+ /* Attn.: Slave address is 7 or 10 bits */
+ /* This changes the address, even if it */
+ /* is already taken! */
+#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
+
+#define I2C_FUNCS 0x0705 /* Get the adapter functionality */
+#define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/
+#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */
+#if 0
+#define I2C_ACK_TEST 0x0710 /* See if a slave is at a specific address */
+#endif
+
+#define I2C_SMBUS 0x0720 /* SMBus-level access */
+
+/* -- i2c.h -- */
+
+
+/* Note: 10-bit addresses are NOT supported! */
+
+/* This is the structure as used in the I2C_SMBUS ioctl call */
+struct i2c_smbus_ioctl_data {
+ char read_write;
+ __u8 command;
+ int size;
+ union i2c_smbus_data *data;
+};
+
+/* This is the structure as used in the I2C_RDWR ioctl call */
+struct i2c_rdwr_ioctl_data {
+ struct i2c_msg *msgs; /* pointers to i2c_msgs */
+ int nmsgs; /* number of i2c_msgs */
+};
+
+
+static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
+ int size, union i2c_smbus_data *data)
+{
+ struct i2c_smbus_ioctl_data args;
+ int rc;
+
+ args.read_write = read_write;
+ args.command = command;
+ args.size = size;
+ args.data = data;
+
+ rc = ioctl(file,I2C_SMBUS,&args);
+
+ return rc;
+}
+
+
+static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
+{
+ return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
+}
+
+static inline __s32 i2c_smbus_read_byte(int file)
+{
+ union i2c_smbus_data data;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
+ return -1;
+ else
+ return 0x0FF & data.byte;
+}
+
+static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
+{
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
+ I2C_SMBUS_BYTE,NULL);
+}
+
+static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
+{
+ union i2c_smbus_data data;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ I2C_SMBUS_BYTE_DATA,&data))
+ return -1;
+ else
+ return 0x0FF & data.byte;
+}
+
+static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
+ __u8 value)
+{
+ union i2c_smbus_data data;
+ data.byte = value;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_BYTE_DATA, &data);
+}
+
+static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
+{
+ union i2c_smbus_data data;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ I2C_SMBUS_WORD_DATA,&data))
+ return -1;
+ else
+ return 0x0FFFF & data.word;
+}
+
+static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
+ __u16 value)
+{
+ union i2c_smbus_data data;
+ data.word = value;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_WORD_DATA, &data);
+}
+
+static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
+{
+ union i2c_smbus_data data;
+ data.word = value;
+ if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_PROC_CALL,&data))
+ return -1;
+ else
+ return 0x0FFFF & data.word;
+}
+
+
+/* Returns the number of read bytes */
+static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
+ __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ I2C_SMBUS_BLOCK_DATA,&data))
+ return -1;
+ else {
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+ }
+}
+
+static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
+ __u8 length, __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (length > 32)
+ length = 32;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_BLOCK_DATA, &data);
+}
+
+/* Returns the number of read bytes */
+static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
+ __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ I2C_SMBUS_I2C_BLOCK_DATA,&data))
+ return -1;
+ else {
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+ }
+}
+
+static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
+ __u8 length, __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (length > 32)
+ length = 32;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_I2C_BLOCK_DATA, &data);
+}
+
+/* Returns the number of read bytes */
+static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
+ __u8 length, __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (length > 32)
+ length = 32;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+ i = i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_BLOCK_PROC_CALL,&data);
+ if ( i )
+ return -1;
+ else {
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+ }
+}
+
+
+#endif /* LIB_I2CDEV_H */
+
diff --git a/recipes/i2c/files/i2c-io-api.h b/recipes/i2c/files/i2c-io-api.h
new file mode 100644
index 0000000000..35ab45865c
--- /dev/null
+++ b/recipes/i2c/files/i2c-io-api.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file i2c-io-api.h
+*
+* @brief This file contains definitions for performing i2c-io operations
+* on the gumstix.
+*
+****************************************************************************/
+
+#if !defined( I2C_IO_API_H )
+#define I2C_IO_API_H
+
+// ---- Include Files -------------------------------------------------------
+
+#include <inttypes.h>
+#include "i2c-io.h"
+
+// ---- Constants and Types -------------------------------------------------
+
+// ---- Variable Externs ----------------------------------------------------
+
+// ---- Function Prototypes -------------------------------------------------
+
+int I2C_IO_CheckVersion( const I2C_IO_Info_t *info );
+
+int I2C_IO_GetInfo( int i2cDev, I2C_IO_Info_t *info );
+int I2C_IO_GetGPIO( int i2cDev, uint8_t portNum, uint8_t *pinVal );
+int I2C_IO_SetGPIO( int i2cDev, uint8_t portNum, uint8_t pinMask, uint8_t pinVal );
+int I2C_IO_GetGPIODir( int i2cDev, uint8_t portNum, uint8_t *pinVal );
+int I2C_IO_SetGPIODir( int i2cDev, uint8_t portNum, uint8_t pinMask, uint8_t pinVal );
+int I2C_IO_GetADC( int i2cDev, uint8_t mux, uint16_t *adcVal );
+int I2C_IO_ReadReg8( int i2cDev, uint8_t reg, uint8_t *regVal );
+int I2C_IO_ReadReg16( int i2cDev, uint8_t reg, uint16_t *regVal );
+int I2C_IO_WriteReg8( int i2cDev, uint8_t reg, uint8_t regVal );
+int I2C_IO_WriteReg16( int i2cDev, uint8_t reg, uint16_t regVal );
+
+#endif // I2C_IO_API_H
+
diff --git a/recipes/i2c/files/i2c-io.h b/recipes/i2c/files/i2c-io.h
new file mode 100644
index 0000000000..3ffb5e9c0e
--- /dev/null
+++ b/recipes/i2c/files/i2c-io.h
@@ -0,0 +1,220 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file i2c-io.h
+*
+* @brief This file defines the interface to the i2c-io program which
+* runs on the robostix.
+*
+*****************************************************************************/
+
+#if !defined( I2C_IO_H )
+#define I2C_IO_H /**< Include Guard */
+
+/* ---- Include Files ---------------------------------------------------- */
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+//---------------------------------------------------------------------------
+/**
+ * Defines the version of this API. This includes the layout of the
+ * various structures, along with the semantics associated with the
+ * protocol. Any changes require the version number to be incremented.
+ *
+ * Version 2 - Introduced READ/WRITE_REG_8/16
+ */
+
+#define I2C_IO_API_VERSION 2
+
+//---------------------------------------------------------------------------
+/**
+ * The min version, determines the minimum version that this API is
+ * compatable with. This allows old host side programs to determine
+ * that they're not compatible.
+ */
+
+#define I2C_IO_API_MIN_VERSION 1
+
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_GET_INFO command retrieves information about the i2c-io
+* program running on the robostix.
+*/
+
+#define I2C_IO_GET_INFO 0x01
+
+typedef struct
+{
+ uint8_t version;
+ uint8_t minVersion;
+ uint16_t svnRevision;
+
+} I2C_IO_Info_t;
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_GET_GPIO command retrieves the values of the pins indicated
+* by portNum.
+*
+* The portNum is set such that 0 = A, 1 = B, etc.
+*
+* A block-reply with a single 8 bit value is returned.
+*/
+
+typedef struct
+{
+ uint8_t portNum;
+
+} I2C_IO_Get_GPIO_t;
+
+#define I2C_IO_GET_GPIO 0x02
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_SET_GPIO command sets the values of the pins specified
+* by pinMask to the correponding bits in ponVal.
+*
+* Note: Setting a pin that's configured for input will enable a pullup
+* resistor.
+*
+* The portNum is set such that 0 = A, 1 = B, etc.
+*/
+
+typedef struct
+{
+ uint8_t portNum;
+ uint8_t pinMask;
+ uint8_t pinVal;
+
+} I2C_IO_Set_GPIO_t;
+
+#define I2C_IO_SET_GPIO 0x03
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_GET_GPIO_DIR command retrieves the data direction
+* register (DDR) for the indicated portNum.
+*
+* The I2C_IO_Get_GPIO_t structure is used for this command.
+*
+* Note: It's ok to read the values of pins which are set for output.
+*
+* The portNum is set such that 0 = A, 1 = B, etc.
+*
+* A block-reply with a single 8 bit value is returned.
+* A 1 bit means that the pin is set for output and a 0 bit means that
+* the pin is set for input.
+*/
+
+#define I2C_IO_GET_GPIO_DIR 0x04
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_SET_GPIO_DIR command sets the data direction
+* register (DDR) for the indicated portNum.
+*
+* The I2C_IO_Set_GPIO_t structure is used for this command.
+*
+* The portNum is set such that 0 = A, 1 = B, etc.
+*/
+
+#define I2C_IO_SET_GPIO_DIR 0x05
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_GET_ADC command performs an ADC sample and returns the result.
+*
+* mux values 0 thru 7 read singled ended ADC values. Values 8 thru 31
+* return a variety of values. See the data sheet for specifics.
+*
+* A block-reply with a 16 bit value is returned, although only the
+* lower 10 bits are significant.
+*/
+
+typedef struct
+{
+ uint8_t mux;
+
+} I2C_IO_Get_ADC_t;
+
+#define I2C_IO_GET_ADC 0x06
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_READ_REG_8 command reads a 8-bit register.
+*
+* A block reply with an 8 bit value is returned.
+*/
+
+typedef struct
+{
+ uint8_t reg; ///< Index of the register to be read.
+
+} I2C_IO_ReadReg8_t;
+
+#define I2C_IO_READ_REG_8 0x07
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_READ_REG_16 command reads a 16-bit register.
+*
+* A block reply with a 16 bit value is returned.
+*/
+
+typedef struct
+{
+ uint8_t reg; ///< Index of the register to be read.
+
+} I2C_IO_ReadReg16_t;
+
+#define I2C_IO_READ_REG_16 0x08
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_WRITE_REG_8 command writes an 8-bit register.
+*/
+
+typedef struct
+{
+ uint8_t reg; ///< Index of the register to be read.
+ uint8_t val; ///< Value to write into the register
+
+} I2C_IO_WriteReg8_t;
+
+#define I2C_IO_WRITE_REG_8 0x09
+
+//---------------------------------------------------------------------------
+/**
+* The I2C_IO_WRITE_REG_16 command writes a 16-bit register.
+*/
+
+typedef struct
+{
+ uint8_t reg; ///< Index of the register to be read.
+ uint8_t pad; ///< Pad for alignment on the host.
+ uint16_t val; ///< Value to write
+
+} I2C_IO_WriteReg16_t;
+
+#define I2C_IO_WRITE_REG_16 0x0A
+
+/* ---- Variable Externs ------------------------------------------------- */
+
+/* ---- Function Prototypes ---------------------------------------------- */
+
+#endif /* I2C_IO_H */
+
diff --git a/recipes/i2c/files/i2c.c b/recipes/i2c/files/i2c.c
new file mode 100644
index 0000000000..9f0bafdba1
--- /dev/null
+++ b/recipes/i2c/files/i2c.c
@@ -0,0 +1,710 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file i2c.c
+*
+* @brief This program allows basic i2c commands to be sent out the i2c
+* bus,
+*
+****************************************************************************/
+
+// ---- Include Files -------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/timeb.h>
+
+#include "i2c-dev.h"
+#include "i2c-api.h"
+#include "i2c-io-api.h"
+#include "Log.h"
+
+// #include "svn-version.h"
+
+// ---- Public Variables ----------------------------------------------------
+// ---- Private Constants and Types -----------------------------------------
+
+// ---- Private Variables ---------------------------------------------------
+
+enum
+{
+ OPT_MEM_DEFAULT = 0,
+
+ // Options assigned a single character code can use that charater code
+ // as a short option.
+
+ OPT_COUNT = 'c',
+
+ // Options from this point onwards don't have any short option equivalents
+
+ OPT_FIRST_LONG_OPT = 0x80,
+
+ OPT_HELP,
+ OPT_VERSION,
+};
+
+enum
+{
+ CMD_DEFAULT,
+
+ CMD_READ_BYTE,
+ CMD_READ_BYTE_2,
+ CMD_READ_BYTE_4,
+
+ CMD_WRITE_BYTE,
+ CMD_WRITE_BYTE_2,
+ CMD_WRITE_BYTE_4,
+
+ CMD_RECV_BYTE,
+ CMD_RECV_BYTE_2,
+ CMD_RECV_BYTE_4,
+
+ CMD_SEND_BYTE,
+ CMD_SEND_BYTE_2,
+ CMD_SEND_BYTE_4,
+};
+
+struct
+{
+ int cmd;
+ const char *cmdStr;
+
+} gCmdMap[] =
+{
+ { CMD_READ_BYTE, "ReadByte" },
+ { CMD_READ_BYTE, "rb" },
+ { CMD_READ_BYTE_2, "ReadByte2" },
+ { CMD_READ_BYTE_2, "rb2" },
+ { CMD_READ_BYTE_4, "ReadByte4" },
+ { CMD_READ_BYTE_4, "rb4" },
+
+ { CMD_WRITE_BYTE, "WriteByte" },
+ { CMD_WRITE_BYTE, "wb" },
+ { CMD_WRITE_BYTE_2, "WriteByte2" },
+ { CMD_WRITE_BYTE_2, "wb2" },
+ { CMD_WRITE_BYTE_4, "WriteByte4" },
+ { CMD_WRITE_BYTE_4, "wb4" },
+
+ { CMD_RECV_BYTE, "RecvByte" },
+ { CMD_RECV_BYTE, "vb" },
+ { CMD_RECV_BYTE_2, "RecvByte2" },
+ { CMD_RECV_BYTE_2, "vb2" },
+ { CMD_RECV_BYTE_4, "RecvByte4" },
+ { CMD_RECV_BYTE_4, "vb4" },
+
+ { CMD_SEND_BYTE, "SendByte" },
+ { CMD_SEND_BYTE, "sb" },
+ { CMD_SEND_BYTE_2, "SendByte2" },
+ { CMD_SEND_BYTE_2, "sb2" },
+ { CMD_SEND_BYTE_4, "SendByte4" },
+ { CMD_SEND_BYTE_4, "sb4" },
+};
+
+int gNumCmds = sizeof( gCmdMap ) / sizeof( gCmdMap[ 0 ]);
+
+int gI2cAddr = -1;
+int gByteCount = 1;
+
+const char *gCmdStr;
+int gCmd = CMD_DEFAULT;
+const char *gAddrStr = NULL;
+const char *gDataStr = NULL;
+
+struct option gOption[] =
+{
+ { "count", required_argument, NULL, OPT_COUNT },
+ { "version", no_argument, NULL, OPT_VERSION },
+ { "verbose", no_argument, &gVerbose, 1 },
+ { "debug", no_argument, &gDebug, 1 },
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL }
+};
+
+#define TRUE 1
+#define FALSE 0
+
+typedef enum
+{
+ NoADC,
+ AllowADC,
+
+} AllowADC_t;
+
+#define ADC_PORT 8
+
+// ---- Private Function Prototypes -----------------------------------------
+
+static int ParseByte( const char *byteStr, uint8_t *byte );
+static int ParseBytes( const char *byteStr, uint8_t *byte, uint8_t maxBytes, uint8_t *bytesParsed );
+
+static void ProcessReadByteCommand( int i2cDev, const char *addrStr );
+static void ProcessWriteByteCommand( int i2cDev, const char *addrStr, const char *dataStr );
+static void ProcessRecvByteCommand( int i2cDev );
+static void ProcessSendByteCommand( int i2cDev, const char *dataStr );
+static void Usage( void );
+
+// ---- Functions -----------------------------------------------------------
+
+//***************************************************************************
+/**
+* Main entry point
+*/
+
+int main( int argc, char **argv )
+{
+ char shortOptsStr[ sizeof( gOption ) / sizeof( gOption[ 0 ] ) + 1 ];
+ char *shortOpts = shortOptsStr;
+ struct option *scanOpt;
+ int opt;
+ const char *i2cDevName = "/dev/i2c-0";
+ int i2cDev;
+ int cmdIdx;
+
+ LogInit( stdout );
+
+ // Figure out the short options from our options structure
+
+ for ( scanOpt = gOption; scanOpt->name != NULL; scanOpt++ )
+ {
+ if (( scanOpt->flag == NULL ) && ( scanOpt->val < OPT_FIRST_LONG_OPT ))
+ {
+ *shortOpts++ = (char)scanOpt->val;
+
+ if ( scanOpt->has_arg != no_argument )
+ {
+ *shortOpts++ = ':';
+ }
+ }
+ }
+ *shortOpts++ = '\0';
+
+ // Parse the command line options
+
+ while (( opt = getopt_long( argc, argv, shortOptsStr, gOption, NULL )) != -1 )
+ {
+ switch ( opt )
+ {
+ case 0:
+ {
+ // getopt_long returns 0 for entries where flag is non-NULL
+
+ break;
+ }
+
+ case OPT_COUNT:
+ {
+ gByteCount = (int)strtol( optarg, NULL, 0 );
+ if ( gByteCount <= 0 )
+ {
+ LogError( "Expecting byte count >= 0, found: '%s'\n", optarg );
+ Usage();
+ exit( 1 );
+ }
+ if ( gByteCount > I2C_MAX_DATA_LEN )
+ {
+ LogError( "Max byte count supported: %d, found %d\n", I2C_MAX_DATA_LEN, gByteCount );
+ Usage();
+ exit( 1 );
+ }
+ break;
+ }
+
+// case OPT_VERSION:
+// {
+// Log( "i2c SVN Revision: %d\n", SVN_REVISION );
+// exit( 0 );
+// break;
+// }
+
+ case '?':
+ case OPT_HELP:
+ default:
+ {
+ LogError( "opt:%d\n", opt );
+ Usage();
+ exit( 1 );
+ }
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ // Verify that an i2c-address was specified
+
+ if ( argc < 1 )
+ {
+ LogError( "Must specify an i2c address\n\n" );
+ Usage();
+ exit( 1 );
+ }
+ gI2cAddr = strtol( argv[ 0 ], NULL, 0 );
+ if (( gI2cAddr <= 0 ) || ( gI2cAddr > 127 ))
+ {
+ LogError( "Expecting i2c address in the range of 1-127, Found: %d\n", gI2cAddr );
+ Usage();
+ exit( 1 );
+ }
+
+ // Verify that a command has been specified
+
+ if ( argc < 2 )
+ {
+ LogError( "Must specify a command\n" );
+ Usage();
+ exit( 1 );
+ }
+ gCmdStr = argv[ 1 ];
+ for ( cmdIdx = 0; cmdIdx < gNumCmds; cmdIdx++ )
+ {
+ if ( strcasecmp( gCmdStr, gCmdMap[ cmdIdx ].cmdStr ) == 0 )
+ {
+ gCmd = gCmdMap[ cmdIdx ].cmd;
+ break;
+ }
+ }
+ if ( gCmd == CMD_DEFAULT )
+ {
+ LogError( "Unrecognized command '%s'\n", gCmdStr );
+ exit( 1 );
+ }
+
+ // Process command specific arguments
+
+ if (( gCmd == CMD_READ_BYTE_2 )
+ || ( gCmd == CMD_WRITE_BYTE_2 )
+ || ( gCmd == CMD_RECV_BYTE_2 )
+ || ( gCmd == CMD_SEND_BYTE_2 ))
+ {
+ gByteCount = 2;
+ }
+ else
+ if (( gCmd == CMD_READ_BYTE_4 )
+ || ( gCmd == CMD_WRITE_BYTE_4 )
+ || ( gCmd == CMD_RECV_BYTE_4 )
+ || ( gCmd == CMD_SEND_BYTE_4 ))
+ {
+ gByteCount = 4;
+ }
+
+ if (( gCmd == CMD_READ_BYTE )
+ || ( gCmd == CMD_READ_BYTE_2 )
+ || ( gCmd == CMD_READ_BYTE_4 ))
+ {
+ if ( argc < 3 )
+ {
+ LogError( "Expecting address\n" );
+ Usage();
+ exit( 1 );
+ }
+ if ( argc > 3 )
+ {
+ LogError( "Unexpected extra parameters\n" );
+ Usage();
+ exit( 1 );
+ }
+
+ gAddrStr = argv[ 2 ];
+ }
+ else
+ if (( gCmd == CMD_WRITE_BYTE )
+ || ( gCmd == CMD_WRITE_BYTE_2 )
+ || ( gCmd == CMD_WRITE_BYTE_4 ))
+ {
+ if ( argc < 4 )
+ {
+ LogError( "Expecting address and data\n" );
+ Usage();
+ exit( 1 );
+ }
+ if ( argc > 4 )
+ {
+ LogError( "Unexpected extra parameters\n" );
+ Usage();
+ exit( 1 );
+ }
+
+ gAddrStr = argv[ 2 ];
+ gDataStr = argv[ 3 ];
+ }
+ else
+ if (( gCmd == CMD_RECV_BYTE )
+ || ( gCmd == CMD_RECV_BYTE_2 )
+ || ( gCmd == CMD_RECV_BYTE_4 ))
+ {
+ if ( argc > 2 )
+ {
+ LogError( "Unexpected extra parameters\n" );
+ Usage();
+ exit( 1 );
+ }
+ }
+ else
+ if (( gCmd == CMD_SEND_BYTE )
+ || ( gCmd == CMD_SEND_BYTE_2 )
+ || ( gCmd == CMD_SEND_BYTE_4 ))
+ {
+ if ( argc < 3 )
+ {
+ LogError( "Expecting data\n" );
+ Usage();
+ exit( 1 );
+ }
+ if ( argc > 3 )
+ {
+ LogError( "Unexpected extra parameters\n" );
+ Usage();
+ exit( 1 );
+ }
+ gDataStr = argv[ 2 ];
+ }
+
+ if ( gDebug )
+ {
+ Log( "i2cAddr:0x%02x Cmd: %s (%d)", gI2cAddr, gCmdStr, gCmd );
+ if ( gAddrStr != NULL )
+ {
+ Log( " Addr: %s", gAddrStr );
+ }
+ if ( gDataStr != NULL )
+ {
+ Log( " Data: %s", gDataStr );
+ }
+ Log( "\n" );
+ }
+
+ // Try to open the i2c device
+
+ if (( i2cDev = open( i2cDevName, O_RDWR )) < 0 )
+ {
+ LogError( "Error opening '%s': %s\n", i2cDevName, strerror( errno ));
+ exit( 1 );
+ }
+
+ // Indicate which slave we wish to speak to
+
+ I2cSetSlaveAddress( i2cDev, gI2cAddr, I2C_NO_CRC );
+
+ switch ( gCmd )
+ {
+ case CMD_READ_BYTE:
+ case CMD_READ_BYTE_2:
+ case CMD_READ_BYTE_4:
+ {
+ ProcessReadByteCommand( i2cDev, gAddrStr );
+ break;
+ }
+
+ case CMD_WRITE_BYTE:
+ case CMD_WRITE_BYTE_2:
+ case CMD_WRITE_BYTE_4:
+ {
+ ProcessWriteByteCommand( i2cDev, gAddrStr, gDataStr );
+ break;
+ }
+
+ case CMD_RECV_BYTE:
+ case CMD_RECV_BYTE_2:
+ case CMD_RECV_BYTE_4:
+ {
+ ProcessRecvByteCommand( i2cDev );
+ break;
+ }
+
+ case CMD_SEND_BYTE:
+ case CMD_SEND_BYTE_2:
+ case CMD_SEND_BYTE_4:
+ {
+ ProcessSendByteCommand( i2cDev, gDataStr );
+ break;
+ }
+ }
+
+ close( i2cDev );
+
+ return 0;
+
+} // main
+
+//***************************************************************************
+/**
+* Parse a string looking for a single byte.
+*/
+
+int ParseByte( const char *byteStr, uint8_t *byte )
+{
+ char *endPtr;
+
+ *byte = (uint8_t)strtol( byteStr, &endPtr, 0 );
+
+ if ( *endPtr != '\0' )
+ {
+ LogError( "Expecting numeric value, found '%s'\n", byteStr );
+ return FALSE;
+ }
+
+ return TRUE;
+
+} // ParseByte
+
+//***************************************************************************
+/**
+* Parse a string looking for an array of bytes.
+*/
+
+int ParseBytes( const char *byteStr, uint8_t *byte, uint8_t maxBytes, uint8_t *bytesParsed )
+{
+ char *endPtr;
+
+ if (( byteStr[ 0 ] == '0' ) && ( byteStr[ 1 ] == 'x' ))
+ {
+ const char *s = &byteStr[ 2 ];
+ *bytesParsed = 0;
+
+ // Could be a multi-byte hex string
+
+ while ( *s != '\0' )
+ {
+ if ( *bytesParsed >= maxBytes )
+ {
+ LogError( "Too many bytes, max: %d\n", maxBytes );
+ return FALSE;
+ }
+
+ (*bytesParsed)++;
+ *byte = 0;
+
+ if (( *s >= 'A' ) && ( *s <= 'F' ))
+ {
+ *byte = *s - 'A' + 10;
+ }
+ else
+ if (( *s >= 'a' ) && ( *s <= 'f' ))
+ {
+ *byte = *s - 'a' + 10;
+ }
+ else
+ if (( *s >= '0' ) && ( *s <= '9' ))
+ {
+ *byte = *s - '0';
+ }
+ else
+ {
+ LogError( "Expecting hex digit, found '%c'\n", *s );
+ return FALSE;
+ }
+ s++;
+
+ if ( *s == '\0' )
+ {
+ break;
+ }
+
+ *byte <<= 4;
+ if (( *s >= 'A' ) && ( *s <= 'F' ))
+ {
+ *byte |= *s - 'A' + 10;
+ }
+ else
+ if (( *s >= 'a' ) && ( *s <= 'f' ))
+ {
+ *byte |= *s - 'a' + 10;
+ }
+ else
+ if (( *s >= '0' ) && ( *s <= '9' ))
+ {
+ *byte |= *s - '0';
+ }
+ else
+ {
+ LogError( "Expecting hex digit, found '%c'\n", *s );
+ return FALSE;
+ }
+ s++;
+ byte++;
+ }
+ }
+ else
+ {
+ // It's decimal or octal - only a single byte
+
+ *byte = (uint8_t)strtol( byteStr, &endPtr, 0 );
+
+ if ( *endPtr != '\0' )
+ {
+ LogError( "Expecting numeric value, found '%s'\n", byteStr );
+ return FALSE;
+ }
+ *bytesParsed = 1;
+ }
+
+ return TRUE;
+
+} // ParseBytes
+
+//***************************************************************************
+/**
+* Issues a read byte command to read a byte from a particular address.
+*/
+
+void ProcessReadByteCommand( int i2cDev, const char *addrStr )
+{
+ uint8_t addr;
+ uint8_t dataByte[ I2C_MAX_DATA_LEN ];
+ int rc;
+ int i;
+
+ if ( !ParseByte( addrStr, &addr ))
+ {
+ return;
+ }
+
+ if (( rc = I2cReadBytes( i2cDev, addr, dataByte, gByteCount )) != 0 )
+ {
+ LogError( "I2cReadByte failed: %d\n", rc );
+ return;
+ }
+
+ Log( "0x", dataByte[0] );
+
+ for ( i = 0; i < gByteCount; i++ )
+ {
+ Log( "%02x", dataByte[i] );
+ }
+ Log( "\n" );
+
+} // ProcessReadByteCommand
+
+//***************************************************************************
+/**
+* Issues a recv byte command to read bytes with no address.
+*/
+
+void ProcessRecvByteCommand( int i2cDev )
+{
+ uint8_t dataByte[ I2C_MAX_DATA_LEN ];
+ int rc;
+ int i;
+
+ if (( rc = I2cReceiveBytes( i2cDev, dataByte, gByteCount )) != 0 )
+ {
+ LogError( "I2cRecvBytes failed: %d\n", rc );
+ return;
+ }
+
+ Log( "0x", dataByte[0] );
+
+ for ( i = 0; i < gByteCount; i++ )
+ {
+ Log( "%02x", dataByte[i] );
+ }
+ Log( "\n" );
+
+} // ProcessRecvByteCommand
+
+//***************************************************************************
+/**
+* Issues a write byte command to write a byte to a particular address.
+*/
+
+void ProcessWriteByteCommand( int i2cDev, const char *addrStr, const char *dataStr )
+{
+ uint8_t addr;
+ uint8_t dataByte[ I2C_MAX_DATA_LEN ];
+ uint8_t bytesParsed;
+ int rc;
+
+ if ( !ParseByte( addrStr, &addr ))
+ {
+ return;
+ }
+
+ if ( !ParseBytes( dataStr, dataByte, sizeof( dataByte ), &bytesParsed ))
+ {
+ return;
+ }
+
+ if (( rc = I2cWriteBytes( i2cDev, addr, dataByte, bytesParsed )) != 0 )
+ {
+ LogError( "I2cWriteBytes failed: %d\n", rc );
+ return;
+ }
+
+} // ProcessWriteByteCommand
+
+//***************************************************************************
+/**
+* Issues a send byte command to write bytes with no address specified.
+*/
+
+void ProcessSendByteCommand( int i2cDev, const char *dataStr )
+{
+ uint8_t dataByte[ I2C_MAX_DATA_LEN ];
+ uint8_t bytesParsed;
+ int rc;
+
+ if ( !ParseBytes( dataStr, dataByte, sizeof( dataByte ), &bytesParsed ))
+ {
+ return;
+ }
+
+ if (( rc = I2cSendBytes( i2cDev, dataByte, bytesParsed )) != 0 )
+ {
+ LogError( "I2cSendBytes failed: %d\n", rc );
+ return;
+ }
+
+} // ProcessSendByteCommand
+
+//***************************************************************************
+/**
+* Usage
+*/
+
+void Usage( void )
+{
+ fprintf( stderr, "Usage: i2c [options] i2c-addr cmd [cmd-arguments]\n" );
+ fprintf( stderr, "Send I2C commands\n" );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "The following commands are supported:\n" );
+ fprintf( stderr, "ReadByte addr Retrieves byte(s) starting at the indicated address\n" );
+ fprintf( stderr, "WriteByte addr data Write byte(s) starting at the indicated address\n" );
+ fprintf( stderr, "ReadByte2 addr Retrieves two bytes from the indicated address\n" );
+ fprintf( stderr, "WriteByte2 addr data Writes two bytes into the indicated address\n" );
+ fprintf( stderr, "ReadByte4 addr Retrieves four bytes from the indicated address\n" );
+ fprintf( stderr, "WriteByte4 addr data Writes four bytes into the indicated address\n" );
+ fprintf( stderr, "RecvByte Retrieves byte(s)(no address specified)\n" );
+ fprintf( stderr, "SendByte data Writes byte(s)(no address specified)\n" );
+ fprintf( stderr, "RecvByte2 Retrieves 2 bytes (no address specified)\n" );
+ fprintf( stderr, "SendByte2 data Writes 2 bytes(no address specified)\n" );
+ fprintf( stderr, "RecvByte4 Retrieves 4 bytes (no address specified)\n" );
+ fprintf( stderr, "SendByte4 data Writes 4 bytes(no address specified)\n" );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "The above commands can be shortened to rb, wb, rb2, wb2, rb4, wb4, vb, sd, vb2 sb2 vb4, and sb4 \n" );
+ fprintf( stderr, "respectively.\n" );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "The following options may be used:\n" );
+ fprintf( stderr, "--count=n Specifies how many bytes to read for ReadByte or RecvByte\n" );
+ fprintf( stderr, "--version Prints the SVN version of this program\n" );
+ fprintf( stderr, "--verbose Print additional information\n" );
+ fprintf( stderr, "--help Prints this information\n" );
+}
+
diff --git a/recipes/i2c/files/i2c.h b/recipes/i2c/files/i2c.h
new file mode 100644
index 0000000000..bbfd276cec
--- /dev/null
+++ b/recipes/i2c/files/i2c.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+*
+* Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* Alternatively, this software may be distributed under the terms of BSD
+* license.
+*
+* See README and COPYING for more details.
+*
+****************************************************************************/
+/**
+*
+* @file i2c.h
+*
+* @brief Global definitions for interfacing with the AVR TWI (aka I2C)
+* hardware
+*
+****************************************************************************/
+/**
+* @defgroup xxx Readable version of xxx.
+*
+* @brief Brief description of what xxx does.
+*
+* Longer description of what xxx does.
+*
+****************************************************************************/
+
+#if !defined( I2C_H )
+#define I2C_H /**< Include Guard */
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <inttypes.h>
+
+#if !defined( CONFIG_H )
+# include "Config.h"
+#endif
+
+
+/**
+ * @addtogroup I2C
+ * @{
+ */
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+/**
+ * Error Codes
+ */
+
+#define I2C_ERROR_NONE 0 // No Error
+#define I2C_ERROR_ADDR_NACK -1 // No response to SLA+R/W
+#define I2C_ERROR_DATA_NACK -2 // NACK during data transmission
+#define I2C_ERROR_ARBITRATION_LOST -3 // Lost arbitration
+#define I2C_ERROR_BAD_LEN -4 // Length is wonky
+#define I2C_ERROR_BAD_CRC -5 // CRC failed
+#define I2C_ERROR_BUS_ERROR -6 // Someting weird on the i2c bus
+
+typedef int8_t I2C_Error_t;
+
+/**
+ * Since we're loosely following the SMBus spec, we restrict the amount
+ * of data in each transaction to 32 bytes.
+ */
+
+#define I2C_MAX_DATA_LEN 32
+
+/**
+ * I2C_Addr_t can contain the address of any device on the bus. This
+ * module only supports 7 bit addressing.
+ */
+
+typedef uint8_t I2C_Addr_t;
+
+/**
+ * The I2C_CRC macro can be used to remove all CRC support at compile time.
+ */
+
+#if CFG_I2C_USE_CRC
+# define I2C_CRC(x) x
+#else
+
+# define I2C_CRC(x)
+#endif
+
+
+/**
+ * I2C_Data_t encapsulates the data being read or written on the i2c bus.
+ * This module follows the SMBus spec, whihch specifies a maximum payload
+ * of 32 bytes.
+ */
+
+typedef struct
+{
+#if CFG_I2C_USE_CRC
+ uint8_t m_crc;
+#endif
+
+
+ // For reads, m_len is the number of bytes actually read (doesn't include
+ // the CRC - if present). If a block transfer was performed which has a
+ // length byte, this length will include the length byte.
+
+ uint8_t m_len;
+
+ // Note: Under SMBus, a block write can consist of a command, a length,
+ // 32 bytes of payload, and a CRC.
+ //
+ // A read response can consist of a length, 32 bytes of data, and a CRC.
+
+ uint8_t m_data[ I2C_MAX_DATA_LEN + 2]; // +1 for the command, +1 for length
+
+} I2C_Data_t;
+
+/* ---- Variable Externs ------------------------------------------------- */
+
+/**
+ * Description of variable.
+ */
+
+/* ---- Function Prototypes ---------------------------------------------- */
+
+/*
+ * Just include prototypes here. Put full descriptions in the .c files.
+ */
+
+/** @} */
+
+#endif /* I2C_H */
+
+
diff --git a/recipes/i2c/files/i2c.init b/recipes/i2c/files/i2c.init
new file mode 100755
index 0000000000..957ce68c7b
--- /dev/null
+++ b/recipes/i2c/files/i2c.init
@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# Start i2c support
+#
+
+start() {
+ echo "Starting i2c..."
+
+ /sbin/modprobe i2c-pxa
+ /sbin/modprobe i2c-dev
+}
+stop() {
+ echo "Stopping i2c..."
+
+}
+restart() {
+ stop
+ start
+}
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ restart)
+ restart
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|restart}"
+ exit 1
+esac
+
+exit $?
+
diff --git a/recipes/i2c/i2c.bb b/recipes/i2c/i2c.bb
new file mode 100644
index 0000000000..69b4c1cc32
--- /dev/null
+++ b/recipes/i2c/i2c.bb
@@ -0,0 +1,45 @@
+DESCRIPTION = "i2c init file and command line tool"
+SECTION = "base"
+PRIORITY = "required"
+PR = "r2"
+
+SRC_URI = " \
+ file://Config.h \
+ file://Crc8.h \
+ file://Crc8.c \
+ file://DumpMem.h \
+ file://DumpMem.c \
+ file://Log.h \
+ file://Log.c \
+ file://i2c-api.h \
+ file://i2c-api.c \
+ file://i2c-dev.h \
+ file://i2c-io.h \
+ file://i2c-io-api.h \
+ file://i2c.h \
+ file://i2c.c \
+ file://i2c.init \
+ "
+
+S = "${WORKDIR}"
+
+do_compile () {
+ ${CC} -o i2c *.c
+}
+
+do_install () {
+ install -d ${D}${bindir}/
+ install -m 0755 ${WORKDIR}/i2c ${D}${bindir}/
+
+ install -d ${D}${sysconfdir}/init.d/
+ install -m 0755 ${WORKDIR}/i2c.init ${D}${sysconfdir}/init.d/i2c
+}
+
+inherit update-rc.d
+INITSCRIPT_NAME = "i2c"
+INITSCRIPT_PARAMS = "defaults 90"
+
+PACKAGES = "${PN}"
+FILES_${PN} = "${bindir}/*"
+FILES_${PN} += "${sysconfdir}/*"
+