pico-dlpcontrol: use a modified version of the gumstix 'i2c' program and wrap it...
authorKoen Kooi <koen@openembedded.org>
Sat, 10 Jan 2009 21:20:34 +0000 (22:20 +0100)
committerKoen Kooi <koen@openembedded.org>
Sat, 10 Jan 2009 21:20:34 +0000 (22:20 +0100)
* 'picodlp-control hflip 1' will turn on horizontil flipping

17 files changed:
packages/i2c-tools/picodlp-control/Config.h [new file with mode: 0644]
packages/i2c-tools/picodlp-control/Crc8.c [new file with mode: 0644]
packages/i2c-tools/picodlp-control/Crc8.h [new file with mode: 0644]
packages/i2c-tools/picodlp-control/DumpMem.c [new file with mode: 0644]
packages/i2c-tools/picodlp-control/DumpMem.h [new file with mode: 0644]
packages/i2c-tools/picodlp-control/Log.c [new file with mode: 0644]
packages/i2c-tools/picodlp-control/Log.h [new file with mode: 0644]
packages/i2c-tools/picodlp-control/i2c-api.c [new file with mode: 0644]
packages/i2c-tools/picodlp-control/i2c-api.h [new file with mode: 0644]
packages/i2c-tools/picodlp-control/i2c-dev.h
packages/i2c-tools/picodlp-control/i2c-io-api.h [new file with mode: 0644]
packages/i2c-tools/picodlp-control/i2c-io.h [new file with mode: 0644]
packages/i2c-tools/picodlp-control/i2c.c [new file with mode: 0644]
packages/i2c-tools/picodlp-control/i2c.h [new file with mode: 0644]
packages/i2c-tools/picodlp-control/picodlp-control [new file with mode: 0755]
packages/i2c-tools/picodlp-control/picodlp-control.c [deleted file]
packages/i2c-tools/picodlp-control_0.1.bb

diff --git a/packages/i2c-tools/picodlp-control/Config.h b/packages/i2c-tools/picodlp-control/Config.h
new file mode 100644 (file)
index 0000000..83bb46d
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/Crc8.c b/packages/i2c-tools/picodlp-control/Crc8.c
new file mode 100644 (file)
index 0000000..87dcf5c
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/Crc8.h b/packages/i2c-tools/picodlp-control/Crc8.h
new file mode 100644 (file)
index 0000000..2d1f74b
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/DumpMem.c b/packages/i2c-tools/picodlp-control/DumpMem.c
new file mode 100644 (file)
index 0000000..e13e94b
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/DumpMem.h b/packages/i2c-tools/picodlp-control/DumpMem.h
new file mode 100644 (file)
index 0000000..5d536f4
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/Log.c b/packages/i2c-tools/picodlp-control/Log.c
new file mode 100644 (file)
index 0000000..e327833
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/Log.h b/packages/i2c-tools/picodlp-control/Log.h
new file mode 100644 (file)
index 0000000..d12d482
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/i2c-api.c b/packages/i2c-tools/picodlp-control/i2c-api.c
new file mode 100644 (file)
index 0000000..cfc4156
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/i2c-api.h b/packages/i2c-tools/picodlp-control/i2c-api.h
new file mode 100644 (file)
index 0000000..73f9f20
--- /dev/null
@@ -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
+
index 98a87f2..cd20965 100644 (file)
@@ -19,7 +19,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-/* $Id: i2c-dev.h 3177 2005-11-05 17:11:47Z khali $ */
+/* $Id: i2c-dev.h,v 1.4 2003/11/27 23:08:06 tat Exp $ */
 
 #ifndef LIB_I2CDEV_H
 #define LIB_I2CDEV_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                  */
+        __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_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_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_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_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_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 */
+#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 + 2]; /* block[0] is used for length */
-                                                   /* and one more for PEC */
+        __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
+#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_QUICK             0
+#define I2C_SMBUS_BYTE              1
+#define I2C_SMBUS_BYTE_DATA         
+#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_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.
+ *      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                   */
-
-#define I2C_SMBUS      0x0720  /* SMBus-level access */
+                                /* -> 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 -- */
 
@@ -144,99 +178,103 @@ union i2c_smbus_data {
 
 /* 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;
+        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 */
+        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;
+        struct i2c_smbus_ioctl_data args;
+    int rc;
+
+        args.read_write = read_write;
+        args.command = command;
+        args.size = size;
+        args.data = data;
 
-       args.read_write = read_write;
-       args.command = command;
-       args.size = size;
-       args.data = data;
-       return ioctl(file,I2C_SMBUS,&args);
+        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);
+        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;
+        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);
+        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;
+        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);
+        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;
+        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);
+        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;
+        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;
 }
 
 
@@ -244,82 +282,84 @@ static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
 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];
-       }
+        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);
+        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];
-       }
+        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);
+        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;
-       if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
-                            I2C_SMBUS_BLOCK_PROC_CALL,&data))
-               return -1;
-       else {
-               for (i = 1; i <= data.block[0]; i++)
-                       values[i-1] = data.block[i];
-               return data.block[0];
-       }
+        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/packages/i2c-tools/picodlp-control/i2c-io-api.h b/packages/i2c-tools/picodlp-control/i2c-io-api.h
new file mode 100644 (file)
index 0000000..35ab458
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/i2c-io.h b/packages/i2c-tools/picodlp-control/i2c-io.h
new file mode 100644 (file)
index 0000000..3ffb5e9
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/i2c.c b/packages/i2c-tools/picodlp-control/i2c.c
new file mode 100644 (file)
index 0000000..6c752b3
--- /dev/null
@@ -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-3";
+    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/packages/i2c-tools/picodlp-control/i2c.h b/packages/i2c-tools/picodlp-control/i2c.h
new file mode 100644 (file)
index 0000000..bbfd276
--- /dev/null
@@ -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/packages/i2c-tools/picodlp-control/picodlp-control b/packages/i2c-tools/picodlp-control/picodlp-control
new file mode 100755 (executable)
index 0000000..4254dfb
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+I2C_APP="/usr/bin/bus3-i2c"
+WORD_ON="0xf0000000"
+WORD_OFF="0x00000001"
+PICO_ADDRESS="0x1b"
+
+PICO_OPTION="$1"
+PICO_OPTION_VALUE="$2"
+
+case ${PICO_OPTION_VALUE} in
+"0")
+                       ;;
+"1")
+                       ;;
+*)
+                       echo "Invalid value" ; PICO_OPTION="invalid-as-well";;
+esac
+
+case ${PICO_OPTION} in
+"hflip")
+                       if [ $2 -gt 0 ] ; then
+                               ${I2C_APP} ${PICO_ADDRESS} wb4 0x08 ${WORD_ON}
+                       else
+                               ${I2C_APP} ${PICO_ADDRESS} wb4 0x08 ${WORD_OFF}
+                       fi;;
+
+"vflip")
+                       if [ $2 -gt 0 ] ; then
+                               ${I2C_APP} ${PICO_ADDRESS} wb4 0x09 ${WORD_ON}
+                       else
+                               ${I2C_APP} ${PICO_ADDRESS} wb4 0x09 ${WORD_OFF}
+                       fi;;
+
+"temporal-enhance")
+                       if [ $2 -gt 0 ] ; then
+                               ${I2C_APP} ${PICO_ADDRESS} wb4 0x26 ${WORD_ON}
+                       else
+                               ${I2C_APP} ${PICO_ADDRESS} wb4 0x26 ${WORD_OFF}
+                       fi;;
+
+*)
+                       echo "Usage: $0 vflip|hflip|temporal-enhance 0/1";;
+esac
+
+
+
diff --git a/packages/i2c-tools/picodlp-control/picodlp-control.c b/packages/i2c-tools/picodlp-control/picodlp-control.c
deleted file mode 100644 (file)
index 632ca83..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) Koen Kooi <<koen@beagleboard.org>
- *
- * The pico DLP Controller Driver is free software; you
- * can redistribute it and/or modify it under the terms of the GNU
- * General Public License version 3 as published by the Free Software
- * Foundation.
- *
- * The pico DLP Controller Driver 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 The pico DLP Controller Driver ; if not,
- * write to the Free Software Foundation, Inc., 59 Temple Place,
- * Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include "i2c-dev.h"
-
-#define ADDRESS 0x1b
-
-int main(int argc, char **argv)
-{
-
-       int fd = 0;
-
-       /* Attempt to open I2C device (/dev/i2c-3) */
-       fd = open("/dev/i2c-3", O_RDWR);
-       if (fd == -1) {
-               fprintf(stderr, "Failed to open pico DLP I2C device: %m\n");
-               exit(0);
-       }
-
-       /* Set the slave address of type I2C_SLAVE */
-       if (ioctl(fd, I2C_SLAVE, ADDRESS) < 0) {
-               fprintf(stderr, "Failed to access pico DLp: %m\n");
-               exit(0);
-       }
-
-       /* Attempt to enable checksumming */
-       if (ioctl(fd, I2C_PEC, 1) < 0) {
-               fprintf(stderr, "Failed to enable PEC\n");
-               exit(0);
-       }
-
-       uint16_t hflip;         /* The horizontal flip bit */
-       uint16_t vflip;         /* The vertical flip bit */
-
-    uint16_t hflip_temp;     /* The horizontal flip bit */
-    uint16_t vflip_temp;     /* The vertical flip bit */
-
-
-       /* Read the status bits for horizontal and vertical vlip */
-       fprintf(stdout, "Getting flip bits \n");
-       hflip = i2c_smbus_read_word_data(fd, 0x08);
-       vflip = i2c_smbus_read_word_data(fd, 0x09);
-
-    /* Output the values to stdout */
-    fprintf(stdout, "hflip: %d - vflip: %d\n", hflip, vflip);
-
-       /* set flip bits to 0 */
-       fprintf(stdout, "Setting flip bits to zero\n");
-       i2c_smbus_write_word_data(fd, 0x08, 0);
-       i2c_smbus_write_word_data(fd, 0x09, 0);
-    
-       hflip_temp = i2c_smbus_read_word_data(fd, 0x08);
-    vflip_temp = i2c_smbus_read_word_data(fd, 0x09);
-       fprintf(stdout, "hflip: %d - vflip: %d\n", hflip_temp, vflip_temp);
-
-       sleep(2);
-
-       /* set flip bits to 1 */
-       fprintf(stdout, "Setting flip bits to one\n");
-       i2c_smbus_write_word_data(fd, 0x08, 1);
-       i2c_smbus_write_word_data(fd, 0x09, 1);
-
-    hflip_temp = i2c_smbus_read_word_data(fd, 0x08);
-    vflip_temp = i2c_smbus_read_word_data(fd, 0x09);
-    fprintf(stdout, "hflip: %d - vflip: %d\n", hflip_temp, vflip_temp);
-
-       sleep(2);
-
-       /* restore values */
-       fprintf(stdout, "Restoring flip bits \n");
-       i2c_smbus_write_word_data(fd, 0x08, hflip);
-       i2c_smbus_write_word_data(fd, 0x09, vflip);
-
-    /* Read the status bits for horizontal and vertical vlip */
-    hflip = i2c_smbus_read_word_data(fd, 0x08);
-    vflip = i2c_smbus_read_word_data(fd, 0x09);
-
-       /* Output the values to stdout */
-       fprintf(stdout, "hflip: %d - vflip: %d\n", hflip, vflip);
-
-       return 0;
-
-}
index 94b2b50..79a896b 100644 (file)
@@ -1,19 +1,20 @@
 DESCRIPTION = "Small application to control the pico DLP over I2C"
 LICENSE = "GPLv3"
-PR = "r1"
+PR = "r2"
 
-SRC_URI = "file://${PN}.c file://i2c-dev.h"
+SRC_URI = "file://*.c file://*.h file://${PN}"
 
 do_configure() {
-       cp ${WORKDIR}/*.[ch] ${S}
+       cp ${WORKDIR}/*.[ch] ${WORKDIR}/${PN} ${S}
 }
 
 do_compile() {
-       ${CC} -o ${PN} ${PN}.c ${CFGLAGS} ${LDFLAGS}
+       ${CC} -o bus3-i2c *.c ${CFLAGS} ${LDFLAGS}
 }
 
 do_install() {
        install -d ${D}/${bindir}
        install -m 0755 ${S}/${PN} ${D}/${bindir}
+       install -m 0755 ${S}/bus3-i2c ${D}/${bindir}
 }