"Chained" uControllers to configure an I2C device - Page 1
Forum section: electronics / beginners

author: jmf11
author_rank: Contributor
timestamp: November 18, 2019, 09:20:40 pm
content: Hello,I'm looking for the adequate way to sort out the below use case.I'm working a TAS3251 board (class D audio amplifier chip with included DSP). The DSP is to be configured/controlled by I2C (slave only). Then, you can configure other things during the operation like the volume. The idea would be to have a small micro-controller on the amplifier board to manage power ON, power OFF, first DSP configuration. But for more powerfull functions the idea would be to use a Raspberry Pi (RPi). But the Rpi does not manages multi-master I2C.Would there be "proven" strategies to have an I2C slave device controlled by a small board uC and a RPi masters (but not multi-master) ?I know that this design may not be so good, but from usage perspective, it would make some sense...JMF

author: rstofer
author_rank: Super Contributor
timestamp: November 19, 2019, 12:53:25 am
content: As long as everybody plays by the rules in terms of addressing, I don't see why one end of the bus couldn't be a Pi and the other end of the bus be a uC with the audio gadget in the middle. This is more conceptual because the physical orientation doesn't matter.At power on, the uC will be done doing it's thing long before the Pi boots.Both masters should be able to detect collisions on the bus but it seems to me this just won't happen.Try it! I would use pull-up resistors around 2.2k Ohms.

author: jmf11
author_rank: Contributor
timestamp: November 19, 2019, 08:07:23 am
content: Hi,It is not a question of orientation. It is more the fact of having 2 masters, with different functional roles. This is an option included in the I2C protocol with the "multi master" concept. But this is not managed by the RPi unfortunatly.In my current set-up (with different off the shelf amps), the RPi is always powered on and I switch ON and OFF the amp when needed. In that type od scenario, the Rpi will be booted before the uC is powered. So there are some risks of master fighting.JMF

author: jhpadjustable
author_rank: Frequent Contributor
timestamp: November 19, 2019, 05:48:49 pm
content: Nothing "proven" but let me throw some things out there.Since clock stretching does appear to work on Pi at the ACK bit, you could use a micro with at least one hardware I2C controller set to respond to the amplifier's address, and mimic every bus byte or condition on the other side as required, by bit-banging or a second I2C controller as available. Use clock stretching to hold off each side between bytes. This is straightorward and easy to work with, but slow. You can speed it up (and complicate it) if you cared to parse the read/write protocol of the amplifier chip, for example, to handle book/page changes asynchronously, or read-ahead from the amplifier when safe to do so, or cache written values...If the Pi won't accept another master on the bus, and hold itself off during a transaction, you'll have to hold it off. You can do this from inside by giving the on/off/startup micro an output that tells the Pi to not initiate transactions. Even if the Pi is in master mode, its bus outputs in the idle state "should" be in undriven open-drain mode and shouldn't disturb whatever else might be happening on the bus. You'll need to handle the hold-off signal in the application or, if kernel drivers are issuing the commands, hack the i2c or ALSA(?) device driver.Or, if your Pi side can handle retries when the amplifier disappears and reappears from the bus, use any I2C hot-plug transceiver to simply detach the Pi whenever the on/off/startup micro does its business. For best results you would need the micro to detect when the bus is in use by the Pi and only detach or attach when idle.

author: jmf11
author_rank: Contributor
timestamp: November 20, 2019, 02:51:45 pm
content: Quote from: jhpadjustable on November 19, 2019, 05:48:49 pmThanks for all proposals,The one I have quoted above, seems to me the easiest and more robust to implement, in absence of a "multi-master" implementation by the RPi and the board uC.I had arrived in parallel to a similar idea. Your proposal confirms me in this direction.Thanks for the help.JMF

author: rstofer
author_rank: Super Contributor
timestamp: November 20, 2019, 11:12:12 pm
content: You should probably have two signals: Bus Request and Bus Grant.The uC sets Bus RequestThe Pi sees Bus Request then completes and ultimately blocks I2C operations. Then it issues Bus GrantThe uC sees Bus Grant, does whatever and then drops Bus RequestThe Pi sees Bus Request dropped, drops Bus Grant and enables I2C operationsThis type of Request/Grant bus management has been used for decades.

author: jhpadjustable
author_rank: Frequent Contributor
timestamp: November 21, 2019, 04:59:32 pm
content: Quote from: rstofer on November 20, 2019, 11:12:12 pmMy understanding is that OP wants to set up the amplifier before the Pi is booted, and shut it down/start it up in an orderly fashion on demand from. What if one peer isn't up when the uC has to work? For that reason, I didn't suggest an interlocked handshake to arbitrate bus ownership, and do recommend that the uC has priority. If confirmation from the Pi is required, and it's not 100% clear that it is, maybe bus-idle detection is enough to serve the purpose.

author: rstofer
author_rank: Super Contributor
timestamp: November 21, 2019, 06:30:35 pm
content: The sequence of events is not at all clear to me. The fact that the Linux drivers don't support multi-master mode is a real shortcoming. The uC will detect a collision, the Pi probably won't. The entire reason for I2C is to allow for multi-master.Assuming the uC and Pi come up in some bizarre sequence, there needs to be a defined way for one device or the other to own the bus for some period of time.Given the existence of the Pi, I'm not ever sure what the uC brings to the dance. Or, another way of looking at it: Why can't the Pi send something over serial to the uC and let the uC handle all I2C traffic?There are many ways to architect these things.

author: mikerj
author_rank: Super Contributor
timestamp: November 21, 2019, 06:46:02 pm
content: You could add an I2C mux to ensure the Rpi is not connected to the slave device whilst the micro is doing it's thing. The Rpi would then get a NACK if it tried to write/read from the slave device whilst the micro had control, which would need to be handled.

author: jmf11
author_rank: Contributor
timestamp: November 22, 2019, 08:27:38 pm
content: Thanks for all your relevant proposals.I know that the use case is not so clear :-) It is mainly as chosing is difficult. I would like a (too) versatile amplifier board to be connected to all sort of I2S source. So I try to open to maximum cases:- basic autonomous board, with the board uC configuring the DSP, power ON and OFF,- connected to a powerfull controller, that could manage different DSP configurations, at higher programing level like a RPi- one controller contrlling several amplifier boards...Too many options <= posibility of a bad design... I know.JMF

author: jhpadjustable
author_rank: Frequent Contributor
timestamp: November 23, 2019, 02:38:45 am
content: Oh, if it's supposed to be open-ended, the proxy uC is the way to go. Then you can load firmware to emulate any gain/frequency control block you like (TDA7439 etc.). You might even add a couple of volume up/down buttons to the uC to make the board that much more useful in the I2S-only case.

author: jmf11
author_rank: Contributor
timestamp: November 23, 2019, 07:50:18 am
content: Quote from: jhpadjustable on November 23, 2019, 02:38:45 amWhat do you mean by proxy uC ? Is it the RPi (for example) talking to the board uC, then the board uC talking the TAS3251 ?Having come pins to connect Volume and buttons to the board uC is the ideaJMF

author: jhpadjustable
author_rank: Frequent Contributor
timestamp: November 23, 2019, 08:35:51 am
content: Quote from: jmf11 on November 23, 2019, 07:50:18 amExactly. You use the hardware I2C interface on the uC to receive commands from the Pi (or other controller) and buttons, and translate/replay them out another interface, bit-banged or hardware, depending on what uCs will fit your design.