Page 4 of 4

Re: Using RPI to listen SMBus(I2C)

Posted: Wed Sep 05, 2018 7:19 am
by joan
All the examples above (I think) were using passive sniffing to monitor the I2C bus. They would not alter the I2C traffic in any way.

The BSC Slave hardware can't be used to sniff the bus. It acts as a slave only. It will send the needed ACKs and NACKs automatically outside of any external control.

Re: Using RPI to listen SMBus(I2C)

Posted: Wed Sep 05, 2018 8:11 am
by reachparagm
yes you are right !! Looks like I'm almost close :( ; but on with below code I do not get the same bytes as that seen on total-phase sniffer -
below is the code, I see many bytes missing when I hex-dump bytes received. I tried playing with buffersize/sampling counter, but no help.
is the callback use correctly and call it enclose response buffers ?

Code: Select all

 
 #!/usr/bin/env python

import time
import pigpio

pi = pigpio.pi() # Connect to local Pi.

if not pi.connected:
    exit()

DSTADDR=0x32
SRCADDR=0x50

SDA=2
SCL=3

def i2c(id, tick):
   global pi

   s, b, d = pi.bsc_i2c(SRCADDR)

   if b:
      hexdump(d[:])

e = pi.event_callback(pigpio.EVENT_BSC, i2c)

# Add pull-ups in case external pull-ups haven't been added
pi.set_pull_up_down(SDA, pigpio.PUD_UP)
pi.set_pull_up_down(SCL, pigpio.PUD_UP)

CMD = packhexbytes("0F 1A A0 01 00 00 CB 02 00 01 00 42 15 00 00 00 00 00 00 00 00 00 00 00 FF FF EA BD 27")
hexdump(CMD)

h = pi.i2c_open(1, ADPADDR) # open device at address 0x53 on bus 1
pi.i2c_write_device(h, str(CMD))
pi.bsc_i2c(SRCADDR) # Configure BSC as I2C slave

time.sleep(3)

e.cancel()

pi.bsc_i2c(0) # Disable BSC peripheral

pi.stop()

Re: Using RPI to listen SMBus(I2C)

Posted: Thu Sep 06, 2018 5:10 pm
by reachparagm
Joan,
quick history - I have 2 RPi back to back (simulating a multi-master scenario). I am trying to read the remote-side transaction data via i2c.event_callback() method and find that some of the data remains missing. I tried few experiment of running I2C_sniffer.py and also a HW sniffer. I tried various sample params for pigpiod also.

I observe that - correct bytes detected via your I2C_sniffer.py and on HW sniffer too, but for some reason the api to event_callback is not producing all expected data. some bytes of transaction are missing after 32 bytes of data.

below is the data logs from I2C_sniffer.py and actual data in the handler of callback.

Code: Select all


log from I2C_sniffer.py
------------------------------------

[A0+0F+45+65+01+00+00+83+02+00+01+00+49+D0+00+00+75+00+00+00+00+00+00+00+00+00+00+00+00+00+00+02+A2+02+02+01+
00+00+4A+2F+00+51+4C+6F+67+69+63+20+46+61+73+74+4C+69+6E+51+20+51+4C+34+31+31+33+34+48+4C+52+4A+20+31+30+47+4C+]
[A0+0F+45+65+01+00+00+13+62+45+20+41+64+61+70+74+65+72+20+2D+20+4C+41+4E+34+00+51+4C+6F+67+69+63+20+46+61+73+
74+4C+69+6E+51+20+51+4C+34+31+31+33+34+48+4C+52+4A+20+31+30+47+62+45+20+41+64+61+70+74+65+72+20+2D+20+4C+41+42+]
[A0+0F+12+65+01+00+00+63+4E+2B+52+44+4D+41+00+00+00+FF+F0+58+9D+EE+]

log from event_callback api (read back as i2c slave and dumped)
---------------------------------------------------------------------------------------------------------

0000   0F 45 65 01 00 00 83 02  00 01 00 49 D0 00 00 75
0000   00 00 00 00 00 00 00 00  00 00 00 00 00 00 02 A2
--- after this many more bytes of transaction is missing ...
0000   74 4C 69 6E 51 20 51 4C  34 31 31 33 34 48 4C 52 --> same
0000   0F 45 65 01 00 00 13 62  45 20 41 64 61 70 74 65
0000   41 4E 34 00 51 4C 6F 67  69 63 20 46 61 73 74 4C
0000   34 48 4C 52 4A 20 31 30  47 62 45 20 41 64 61 70
0000   0F 12 65 01 00 00 63 4E  2B 52 44 4D 41 00 00 00


Re: Using RPI to listen SMBus(I2C)

Posted: Thu Sep 06, 2018 6:08 pm
by joan
It sounds like data is being lost because the BSC I2C slave buffer can't be emptied/filled fast enough.

The hardware buffer is only 16 bytes (I think) so the software needs to respond to data arriving before the time taken to receive 16 bytes or so.

If possible run the slave reading software on the Pi acting as the slave - that will minimise the network overheads. If that still doesn't work you'll need to try a C solution rather than Python.

Re: Using RPI to listen SMBus(I2C)

Posted: Wed Sep 12, 2018 5:25 am
by reachparagm
Joan,

Seem like there seem some race/buffer-overwrite issue in consuming the bcs_xfer buffer even while linking with local pigpio library.
it would be helpful for community if you have any equivalent C/C++ code of bsc_slave.py (like pi.i2c_bsc() example using "int eventSetFuncEx(unsigned event, eventFuncEx_t f, void *userdata)".

Is it possible to add a API bsc_read(), bsc_write(), which can callback-api returning the same full transaction (as that like I2C_sniffer.py) from a START to STOP instead of 16-byte buffer.

after trying C code - I see that the bytes after every 32 bytes seem to not show 5 bytes. Please let me know if any bad call to pigpio API.

Code: Select all


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pigpio.h>

#define DATASZ  2048

#define SELFADDR 

void simple_bsc_event_callback(int event, uint32_t tick) {
    bsc_xfer_t xfer;
    int i = 0, status;

    xfer.control = (SELFADDR << 16) | 0x305;
    status = bscXfer(&xfer);
    if (! status ) {
        fprintf(stderr, "process register failed.\n");
    }
    if (xfer.rxCnt){
        for (i=0; i<xfer.rxCnt; i++)
            fprintf(stderr, " %02x", xfer.rxBuf[i]);
        fprintf(stderr, "\n");
    }

}

int main(int argc, char *argv[]) {

    bsc_xfer_t xfer;
    int status;
    if (gpioInitialise() < 0) {
        fprintf(stderr, "pigpio initialisation failed.\n");
        return 1;
    }
    if ( ! eventSetFunc(PI_EVENT_BSC, simple_bsc_event_callback) ){
        xfer.control = (SELFADDR << 16) | 0x305;
        status = bscXfer(&xfer);
        if (! status ) {
            fprintf(stderr, "process register failed.\n");
        }
    }

    sleep(20);
    gpioTerminate();
}

pi@raspberrypi:~/venv/sandbox $ sudo ./prog
 0f 45 65 01 00 00 83 02 00 01 00 ec d0 00 00 75  00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 a2
 4a 2f 00 51 4c 6f 67 69 63 20 46 61 73 74 4c 69  51 4c 34 31 31 33 34 48 4c 52 4a 20 31 30 47 f1
 [b]^^^^ (some bytes missing as seen below) -[/b]
 
 0f 45 65 01 00 00 13 62 45 20 41 64 61 70 74 65  72 20 2d 20 4c 41 4e 34 00 51 4c 6f 67 69 63 20
 69 6e 51 20 51 4c 34 31 31 33 34 48 4c 52 4a 20  62 45 20 41 64 61 70 74 65 72 20 2d 20 4c 41 42
 12 65 01 00 00 63 4e 2b 52 44 4d 41 00 00 00 ff 
 
below observed on i2csniffer

radix: hexadecimal
0F 45 65 01 00 00 83 02 00 01 00 EC D0 00 00 75 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 A2
[b]02 02 01 00 00[/b] 4A 2F 00 51 4C 6F 67 69 63 20 46  61 73 74 4C 69 6E 51 20 51 4C 34 31 31 33 34 48 4C 52 4A 20 31 30 47 F1
^^^^^^^^^^^^^^^^ (missing of 1st transaction)                                         ^^^^^^^^^