thetechnobear Ive noticed that linux these days supports both master/slave, however its dependent on chipset support.
(just what Ive read... no expert/experience in this area really!))
I don't have any experience either, but I read the same thing following your question. The AM3358 SoC has support for I2C slave according to its datasheet. However, most linux docs I found related to i2c slave behaiour are for kernel-space interaction. The only mention of user space is via sysfs.
According to https://www.kernel.org/doc/html/latest/i2c/slave-interface.html, "User manual" section:
I2C slave backends behave like standard I2C clients. So, you can instantiate them as described in the document ‘instantiating-devices’. The only difference is that i2c slave backends have their own address space. So, you have to add 0x1000 to the address you would originally request. An example for instantiating the slave-eeprom driver from userspace at the 7 bit address 0x64 on bus 1:
# echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-1/new_device
Each backend should come with separate documentation to describe its specific behaviour and setup.
... I tried that and I can indeed create a device at that bus address:
cd /sys/bus/i2c/devices/i2c-1
echo mydevice 0x1064 > new_device
results in a new device being created. dmesg
gives i2c i2c-1: new_device: Instantiated device mydevice at 0x64
and a new folder comes up at /sys/bus/i2c/devices/i2c-1/1-1064
... however I don't know how to interact with it. It seems like the usual i2c-dev or smbus user-space libraries do not have any explicit support for slave operation ... but maybe you can just call read()
or write()
and these will block until an external master performs a start condition on the bus and starts driving the clock? Who knows ... the "instantiating-devices" page the above section refers to seems to indicate that this is about manually instantiating https://www.kernel.org/doc/html/latest/i2c/instantiating-devices.html kernel drivers from user space but that then the operation would be entirely down to the driver, so this is not particularly useful unless you are into writing kernel code ...
It may even make sense that Linux can only run in kernel space for i2c slaves: the i2c slave needs to respond pretty fast when the i2c master generates a start condition and it may well be that Linux thinks that no one would attempt to meet a sort-of hard deadline by going to user space. "sort-of-hard deadline": there are things like "clock stretching" that would allow the slave to take more time than expected to respond, but at some point the master will decide to time out.
thetechnobear - if it has multiple i2c buses, can these be configured as master/slave independently.
From the little I could infer from the above, I think the master/slave behaviour could even be not only bus-specific but even address-specific. To be confirmed
Yes, like all its digital pins.
thetechnobear it would also be handy if Bela had another i2c bus, so I could run two independent i2c buses.
It has two: one is i2c1 (default for Trill), one is i2c2 (used for the Bela codec, but Trill could be moved to this because the addresses don't conflict and they both support 400kHz. Note: on non last-rev Bela/Mini boards you'll need pullup resistors on this bus).
thetechnobear bonus, is there any way I can get an i2c bus on Bela Salt...
I2C2 is broken out to one of the grove connectors on the BBG. If you need I2C1, that one is on a molex header on the Bela cape, and you could try to somehow stick a connector in there, but it'd need to be pretty short ... you can also solder to the pins at the back of the BBG.
thetechnobear I want to connect to another i2c master (which cannot be a slave, but potentially supports multi master) to Bela.
is there not a UART connection available? That would make things easier for the purpose of communicating to Bela without resorting to understanding I2C slave on Linux ...
thetechnobear this way, my Trill sensors could be potentially accessible by either i2c master, and also the two i2c masters could communicate....
Do you need the two masters to access the devices alternatively (e.g.: Bela reads, other device reads, Bela reads..) or do you need to be able to switch between them occasionally at some point (e.g.: one patch Bela reads, other patch other device reads)? I am wondering whether an I2c multiplexer could help with that ...
Here's some crazy talk, just for making things complicated: if you don'y really need to communicate between Bela and the other device and you want Bela to read from Trill at the same time as the other device, you could have a little PRU program that sniffs the I2C transaction between the other two devices. It would be super fun! Actually at that point you could even have the other device send dummy messages to Trill only for the purpose of sending them to Bela!
thetechnobear perhaps I could use something like a teensy which has two i2c buses (sdl0, sdl1) , if they were both setup as i2c slave. then it could 'simply' copy data between the two buses.
what's the connection diagram here?