pig2i2c.c
Go to the documentation of this file.
00001 /*
00002 */
00003 
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <stdint.h>
00007 #include <unistd.h>
00008 #include <time.h>
00009 #include <sys/types.h>
00010 #include <sys/stat.h>
00011 #include <sys/time.h>
00012 #include <fcntl.h>
00013 
00014 #include "pigpio.h"
00015 
00016 /*
00017 This software reads pigpio notification reports monitoring the I2C signals.
00018 
00019 Notifications are pipe based so this software must be run on the Pi
00020 being monitored.
00021 
00022 It should be able to handle a 100kHz bus.  You are unlikely to get any
00023 usable results if the bus is running at 400kHz.
00024 
00025 gcc -o pig2i2c pig2i2c.c
00026 
00027 Do something like
00028 
00029 sudo pigpiod -s 2
00030 
00031 # get a notification handle, assume handle 0 was returned
00032 
00033 pigs no
00034 
00035 # start notifications for SCL/SDA
00036 
00037 e.g. pigs nb 0 0x3   # Rev. 1 select gpios 0/1
00038 e.g. pigs nb 0 0xC   # Rev. 2 select gpios 2/3
00039 e.g. pigs nb 0 0xA00 # select gpios 9/11 (1<<9|1<<11)
00040 
00041 # run the program, specifying SCL/SDA and notification pipe
00042 
00043 ./pig2i2c SCL SDA </dev/pigpioN # specify gpios for SCL/SDA and pipe N
00044 
00045 e.g. ./pig2i2c 1  0 </dev/pigpio0 # Rev.1 I2C gpios
00046 e.g. ./pig2i2c 3  2 </dev/pigpio0 # Rev.2 I2C gpios
00047 e.g. ./pig2i2c 9 11 </dev/pigpio0 # monitor external bus 
00048 */
00049 
00050 #define RS (sizeof(gpioReport_t))
00051 
00052 #define SCL_FALLING 0
00053 #define SCL_RISING  1
00054 #define SCL_STEADY  2
00055 
00056 #define SDA_FALLING 0
00057 #define SDA_RISING  4
00058 #define SDA_STEADY  8
00059 
00060 static char * timeStamp()
00061 {
00062    static char buf[32];
00063 
00064    struct timeval now;
00065    struct tm tmp;
00066 
00067    gettimeofday(&now, NULL);
00068 
00069    localtime_r(&now.tv_sec, &tmp);
00070    strftime(buf, sizeof(buf), "%F %T", &tmp);
00071 
00072    return buf;
00073 }
00074 
00075 void parse_I2C(int SCL, int SDA)
00076 {
00077    static int in_data=0, byte=0, bit=0;
00078    static int oldSCL=1, oldSDA=1;
00079 
00080    int xSCL, xSDA;
00081 
00082    if (SCL != oldSCL)
00083    {
00084       oldSCL = SCL;
00085       if (SCL) xSCL = SCL_RISING;
00086       else     xSCL = SCL_FALLING;
00087    }
00088    else        xSCL = SCL_STEADY;
00089 
00090    if (SDA != oldSDA)
00091    {
00092       oldSDA = SDA;
00093       if (SDA) xSDA = SDA_RISING;
00094       else     xSDA = SDA_FALLING;
00095    }
00096    else        xSDA = SDA_STEADY;
00097 
00098    switch (xSCL+xSDA)
00099    {
00100       case SCL_RISING + SDA_RISING:
00101       case SCL_RISING + SDA_FALLING:
00102       case SCL_RISING + SDA_STEADY:
00103          if (in_data)
00104          {
00105             if (bit++ < 8)
00106             {
00107                byte <<= 1;
00108                byte |= SDA;
00109             }
00110             else
00111             {
00112                printf("%02X", byte);
00113                if (SDA) printf("-"); else printf("+");
00114                bit = 0;
00115                byte = 0;
00116             }
00117          }
00118          break;
00119 
00120       case SCL_FALLING + SDA_RISING:
00121          break;
00122 
00123       case SCL_FALLING + SDA_FALLING:
00124          break;
00125 
00126       case SCL_FALLING + SDA_STEADY:
00127          break;
00128 
00129       case SCL_STEADY + SDA_RISING:
00130          if (SCL)
00131          {
00132             in_data = 0;
00133             byte = 0;
00134             bit = 0;
00135 
00136             printf("]\n"); // stop
00137             fflush(NULL);
00138          }
00139          break;
00140 
00141       case SCL_STEADY + SDA_FALLING:
00142          if (SCL)
00143          {
00144             in_data = 1;
00145             byte = 0;
00146             bit = 0;
00147 
00148             printf("["); // start
00149          }
00150          break;
00151 
00152       case SCL_STEADY + SDA_STEADY:
00153          break;
00154 
00155    }
00156 }
00157 
00158 int main(int argc, char * argv[])
00159 {
00160    int gSCL, gSDA, SCL, SDA, xSCL;
00161    int r;
00162    uint32_t level, changed, bI2C, bSCL, bSDA;
00163 
00164    gpioReport_t report;
00165 
00166    if (argc > 2)
00167    {
00168       gSCL = atoi(argv[1]);
00169       gSDA = atoi(argv[2]);
00170 
00171       bSCL = 1<<gSCL;
00172       bSDA = 1<<gSDA;
00173 
00174       bI2C = bSCL | bSDA;
00175    }
00176    else
00177    {
00178       exit(-1);
00179    }
00180 
00181    /* default to SCL/SDA high */
00182 
00183    SCL = 1;
00184    SDA = 1;
00185    level = bI2C;
00186 
00187    while ((r=read(STDIN_FILENO, &report, RS)) == RS)
00188    {
00189       report.level &= bI2C;
00190 
00191       if (report.level != level)
00192       {
00193          changed = report.level ^ level;
00194 
00195          level = report.level;
00196 
00197          if (level & bSCL) SCL = 1; else SCL = 0;
00198          if (level & bSDA) SDA = 1; else SDA = 0;
00199 
00200          parse_I2C(SCL, SDA);
00201       }
00202    }
00203    return 0;
00204 }
00205 


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:43:57