4

As already mentioned in this question Reading and writing with smbus package, there are chips that, apart for standard SDA and SCL lines, use a third communication line. This means that this "modified" I2C communication cannot be made using standard kernel and smbus library, which advantage is that communication is very orderly (perfect SCL pulses).

I already managed to bitbang communication using RPi.GPIO library. The communication works, but it is uneven and each clock pulse has different length, since RPi.GPIO library (and probably Python itself) is just too slow.

Now I want to write my own library for the communication with the chip. In order for library to work properly, I have to solve two problems:

  1. Would it be appropriate to use standard I2C Raspberry Pi pins (GPIO2, GPIO3) plus one arbitrary GPIO for that? Maybe this is not good idea because it might create a conflict with kernel and smbus library? What do you think?

  2. How should I write this communication to be as orderly as possible - should I write special C routines within my Python program and what commands should I use to access the GPIOs?

I would prefer stand-alone solutions that don't use existing communication libraries (e.g. RPi.GPIO, pigpio), since they contain a lot of capabilities completely unnecessary for the problem.

F1Linux
  • 1,677
  • 1
  • 15
  • 32
Pygmalion
  • 458
  • 2
  • 7
  • 25

2 Answers2

3

A few thoughts:

  1. Using dedicated I2C pins for your bit-banged I2C should be fine as long as you don't use smbus at the same time.

  2. Improving GPIO timing in userspace can be done by increasing process priority (see man nice). Re-writing your bit-banging routines in C will help on average, but the worst case will be just as bad as with Python. The only way to get consistent timing is to move your code to a kernel module.

I2C is designed to handle inconsistent timing (both master and slave can make a clock cycle almost arbitrarily long if they need more time), so as long as the communication works, I wouldn't worry about uneven clock pulses too much.

Dmitry Grigoryev
  • 28,277
  • 6
  • 54
  • 147
3

That LDAC signal is truly nasty.

I have read the datasheet and your messages a few times and I can't quite focus on a specific issue so I figure out you're just brainstorming. I will start from what I know from direct experience.

How should I write this communication to be as orderly as possible - should I write special C routines within my Python program and what commands should I use to access the GPIOs?

I can confirm an ad-hoc, C (then C++) program to drive the pins improves regularity massively. I observed this in multiple experiments over a few significantly different devices with scope. At work, I use this to switch our radio chip from 'end of transmission' to 'be back in receive mode' and it has >99% reliability vs <66% for the higher level approaches. To reach this, you need to write the program in a peculiar way:

  • no-alloc: everything must be on stack so no malloc and no new.
  • GPIO access: just memory map /dev/gpiomem. That exposes the hardware-level ARM AXI AMBA registers. You can't get any faster than that!
  • for I/O I suggest a Unix-domain socket. I encourage use of a binary protocol.

I speculate the result is the OS sees a minuscule program which it can schedule easily. Compare to higher level languages which often have threading and task facilities, an extensive io.

Nice helps. The new realtime priority system helps. Neither gave me the same result as writing this program. I doubt just binding python to a C library would do either.

I suspect the choice of pins could be subjective.

MaxDZ8
  • 339
  • 1
  • 7