I2C bus - Multiple identical write-only slave devices (MCP23017)? - Page 1
Forum section: electronics / general

author: jeremy0
author_rank: Contributor
timestamp: April 08, 2021, 05:46:58 pm
content: I have a number of identical hardware modules connected to a shared I2C bus. The module design includes anMCP23017 I2C IO expander, controlling 16 digital control signals within the module. The MCP23017's address pins can be manually configured, so that each module's IO expander can be individually addressed and controlled. The IO expander's GPIOs are only used as outputs, and the device is only ever written to, never read from.Now, it turns out that these digital control signals need to be set identically for each module. (Any per-module control is handled by other means.)So, my question is: What would happen if I configured all the the modules with the same address, and wrote to them all in a single transaction to their single, shared address?Since we're operating write-only, the devices would only respond with ACKs, and all at the same time - exactly as in a General Call transaction, correct?[EDIT: I realise the MCP23017 doesn't support General Call - what I mean is that the bus operation would be identical except for the specific data bits, right?]Does this mode of operation violate the bus protocol in any meaningful way?Is there any reason to expect the MCP23017s to *not* behave as I want them to?

author: Microdoser
author_rank: Frequent Contributor
timestamp: April 08, 2021, 06:00:08 pm
content: Posted without reading your post properly. Checking datasheet

author: phil from seattle
author_rank: Super Contributor
timestamp: April 08, 2021, 06:38:37 pm
content: The theory that the WOM I2C devices ACK at the same time needs to be tested. The consequences of some driving the bus at different times may not be desirableIf nothing else, you are operating outside the design parameters. WOM Async and SPI devices are easy to drive in parallel, FWIW.

author: Microdoser
author_rank: Frequent Contributor
timestamp: April 08, 2021, 06:47:51 pm
content: Personally, I would activate each channel individually, send the command, then turn that channel off and switch to the next one. You could even wait for the ACK for robustness. Then you know you won't get a conflict from multiple devices all pulling a line LOW at the same time. It will slow down your communications slightly but unless your bus is nearly saturated it shouldn't make much difference.I had a very similar problem where I wanted to use 8 of the same device straight out of the box, so naturally they had the same address.I ended up using a TCA9548APWR which is an 8 channel switch that you just send 0-255 to choose which combination of the 8 channels you want connected.EDIT: I would have replied earlier, but the site went 502 Bad Gateway again

author: jeremy0
author_rank: Contributor
timestamp: April 08, 2021, 07:57:17 pm
content: Quote from: phil from seattle on April 08, 2021, 06:38:37 pmSurely they are required to (within SCK/SDA timing margins) to conform with the spec.QuoteIf the device meets the spec, doing so should have no consequences.Open-drain SDA is expressly designed to allow this electrically - indeed, this is exactly what happens in a General Call transaction.SDA will be pulled low by the fastest-reacting device, and it will remain low until released by the slowest-reacting device - but this will be indistinguishable from a single device that pulls low at the earliest time and releases at the latest, and entirely within spec if the individual devices are.QuoteHow, exactly?Interestingly, section 3.1.10 of the spec anticipates this mode, in Note 6:QuoteOf course, whether the specific device has been designed in such a way as to not work this way is a valid question, but it seems to me that the designers would have to go out of their way to achieve this.QuoteSure. I ask the question mostly out of curiosity.

author: nctnico
author_rank: Super Contributor
timestamp: April 09, 2021, 12:39:34 pm
content: You can parallel the devices without any problems.However you need to have some way to correct transmission errors. You can do this by reading back the state of the output pins and re-send if there is an error OR update the outputs frequently enough so a transmission error does not cause any damage.

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 09, 2021, 02:48:41 pm
content: I2C is open drain, so to send "1" the device does nothing, to say "0" it pulls the line down.You could connect 2,4,8 devices, but if at least one device got the message, you will read ACK (OK), but you won't know if all received it correctly.

author: jeremy0
author_rank: Contributor
timestamp: April 09, 2021, 05:09:34 pm
content: Quote from: DavidAlfa on April 09, 2021, 02:48:41 pmOf course. (This is recognised in both the General Call section (3.1.13) of the standard, and in Note 6 to section 3.1.10.)But the I2C ACK/NAK mechanism isn't really intended to deal with transmission errors - it has more to do with bus access.Even with distinctly addressed devices, as long as a device thinks it has recognised its address it will ACK successive bytes regardless of transmission errors.Devices have no way of detecting transmission errors anyway, unless they implement error detection at a protocol layer above the physical bus.

author: jeremy0
author_rank: Contributor
timestamp: April 09, 2021, 05:17:14 pm
content: Quote from: nctnico on April 09, 2021, 12:39:34 pmUnless the probability of transmission errors is increased by the shared-address scenario, the same concern applies to distinctly-addressed devices, or even a single device.

author: nctnico
author_rank: Super Contributor
timestamp: April 09, 2021, 05:31:34 pm
content: Quote from: jeremy0 on April 09, 2021, 05:17:14 pmYes indeed. I should have been clearer about that.

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 09, 2021, 07:37:29 pm
content: The ACK at least lets you know that someone received the message. Data might be correct or wrong, but at least it was received.However if any of the devices loses a clock, gets noise or whatever, it will not send ACK. So how do you know?I guess that checking the waveforms to ensure there're clean and got nice rising/falling edges, would be ok.

author: Siwastaja
author_rank: Super Contributor
timestamp: April 10, 2021, 08:36:40 am
content: Quote from: DavidAlfa on April 09, 2021, 07:37:29 pmYou usually don't. That's one of the basic assumption in designing digital systems, really.Our complete electronic ecosystem is based on assumptions that signal integrity issues are sorted out during design, then we assume communication does not fail.Notdoing this assumption makes the design much more complex, time-consuming, and expensive than most (including nctnico) ever guess. Your $200 smartphone becomes a $200 million space device.For example, DRAM is parity checked in mission critical information technology (like servers) not because of designers not trusting the RAM interface, but because DRAM itself has a certain bit corruption rate.CPUs internally do not checksum any internal bus. External buses are rarely checksummed either. Discrete logic is almost never designed to be safe against signal corruption.Yet electronics can be very robust, despite the assumption that communication does not fail. Why? Because ofsignal integrityand strict EMC compliance requirements. The world operates fine regardless of nctnico failing to understand how it works. The world is practical; if there is a problem, it is solved. If some interface requires extra robustness, it is added. Extreme principles are avoided because they become expensive.nctnico's claim is that SPI and I2C somehow are different and require checksumming. This is usually a total fallacy. Normal SI applies to these single ended signals, like any other on-board logic signal. Besides, the idea of adding checksumming remains mostly theoretical; people typically use existing I2C or SPI slave ICs, which almost never implement any way of checksumming. Some do, but most do not.I'm not saying adding a checksum is a bad idea; some tiny part of SPI/I2C devices do this. And if you roll your own both sides, then you obviously can do it.And if you abuse the buses outside of the intended usage and your SI sucks as a result, one way to try to deal with it is adding checksumming.It's just that if youeversee the error trigger, that means, you have seriously f*cked up your SI, or are operating in an environment with devicesseriouslycompromising their EMC requirement. Or you are operating in space. The question is, what is the likelihood that the same "noise" that corrupted your I2C or SPI won't corrupt something else on-board that you failed to safeguard? That's right, in such special conditions, you need completely different mindset.

author: voltsandjolts
author_rank: Unknown
timestamp: April 10, 2021, 09:19:08 am
content: Depends what your application is and what the safety requirements are.An fmea process might point out some things, e.g. maybe a power line fail in one module would pull down the i2c bus and therefore stop all modules operating.

author: nctnico
author_rank: Super Contributor
timestamp: April 10, 2021, 10:55:44 am
content: Quote from: Siwastaja on April 10, 2021, 08:36:40 amActually, it is the other way around. You seem to have an extremely naive and optimistic view of the world. As if EMC compliance and getting signal integrity right is the golden solution to everything. It isn't!Some of my designs are being produced in huge numbers (which are fully tested for CE compliance by a third party) and get installed in all kinds of places. Something simple like a garage door opener driven by a motor with bad brushes can mess things up. The end user just says to my customer: your device doesn't work so it sucks. The end customer doesn't care they bought a crappy garage door opener that isn't CE compliant.After several decades of engineering I learned that the world isn't optimal and passing CE testing doesn't mean your product will always function right. However, along the way I have picked up a lot of simple tricks which improve reliability enormously. For example: Updating outputs continuously instead of when they need to change for example; it doesn't add any cost (contrary to your statement) but it improves the perceived reliability to the end user hugely AND reduces costs for support.And that is what my statement is about: implementing hardware & software in a way so it automatically recovers from a failure. In many cases this can be achieved by really simple methods which don't add costs. In the end this saves a lot of time & money.The case of the garage door opener took a few visits from service people to figure out why the device was failing. IIRC this was fixed in software (not written by me BTW).

author: Siwastaja
author_rank: Super Contributor
timestamp: April 10, 2021, 01:45:48 pm
content: Now that you elaborated a bit on your viewpoint I have nothing to disagree with, I also follow the same practices pretty much, at least when we have time and budget available...It's just that usually you come with the simplified version saying that SPI (or I2C) absolutelyrequireschecksumming to work reliably, as if the problem is about SPI (or I2C) and not more general. Yet, if you have a SPI or I2C slave one inch from an MCU with proper grounding and power bypassing, it's extremely extremely unlikely that communication will ever corrupt. Gazillion of other problems do arise, though, exactly because we live in thereal world.You need to get people understand that hardening SPI or I2C solves only so much. In order to be effective, hardening must be a pattern followed everywhere. With limited resources, the weight should be on,* Very probable problems (even if the fix is costly)* Easy-to-implement solutions (even if the problem isn't probable)Obviously I do agree that you should be using hardened practices whenever they are easy to implement and come without cost; the typical example being updating the outputs regularly even when there is no state change. Although, this only works in cases where short glitches are harmless. Sometimes you can't accept such glitches, then you are back to the assumption miscommunication does not happen, or need to design in significantly more complexity.You probably realize but others may not, that in your garage door opener what you did by software update was to hack a non-functional (due to unexpected environmental problem) device to barely functional (still in that same environment). You patched it enough to solve the crisis. I would have done the same, but it did not become robust as a result.Regarding error recovery, this is very relevant in case of I2C. I have found I2C slaves to be exceedingly finicky in high-reliability applications, and no, the problem is not poor signal integrity messing up the comms, the problem are buggy or poorly specified I2C slave devices and MCU peripheral implementationsthat crash like Windows 95 beta versionfor no reason whatsoever. A good mitigation strategy is to add a high-side power switch to each I2C slave so you can at least run hot reboot of the slaves when your error detection and recovery logic detects a problem that doesn't go away with just recommunicating. Of course, if this is a life support device, you won't be using any I2C part for anything critical.So yeah, paying attention to all possible sources of errors is good use of time, but you can't boil it down to saying it's the communication that fails, and just checksum it. If you just do that, you have caught one rarely appearing risk but let 99 other more typical points of failure pass through.

author: spostma
author_rank: Regular Contributor
timestamp: April 10, 2021, 04:10:39 pm
content: Before sending an I2C START, check that the bus is idle (SDA high)If not, do a I2C Bus Error Recovery by sending 9 clocks followed by a Stopto clear a slave that may be stuck in the middle of a byte.Dallas/Maxim Application note 476 "Comparing the I2C Bus to the SMBus" says:In the I2C bus, if the slave locks up and holds either Clock or Data low, error recovery is impossible.Very few slave devices actually have the ability to hold Clock. As a result, the most commonbus error is slave devices that have ended up in a state where Data (the data line) is low.In the I2C bus, a master accomplishes error recovery by clocking Clock until Data is highand then issuing a Start followed by a Stop.-----I2C Bus recovery (from DesignCon 2003 TecForum I2C Bus Overview)Typical case is when masters fails when doing a read operation in a slaveSDA line is then non usable anymore because of the “Slave-Transmitter” mode.Methods to recover the SDA line are:– Reset the slave device (assuming the device has a Reset pin)– Use a bus recovery sequence to leave the “Slave-Transmitter” modeBus recovery sequence is done as following:1 - Send 9 clock pulses on SCL line2 - Ask the master to keep SDA High until the “Slave-Transmitter” releases the SDA line to perform the ACK operation3 - Keeping SDA High during the ACK means that the “Master-Receiver” does not acknowledge the previous byte receive4 - The “Slave-Transmitter” then goes in an idle state5 - The master then sends a STOP command initializing completely the bus.----This should unlock a stuck I2C bus always without need of power cycling of slave devices as far as I know...

author: bson
author_rank: Unknown
timestamp: April 10, 2021, 11:20:35 pm
content: Are you sure it doesn't support GC? It should be easy to verify and might be worth checking...

author: NorthGuy
author_rank: Super Contributor
timestamp: April 11, 2021, 02:08:25 pm
content: If one of the slaves pulls down the SDA line and locks the bus, it doesn't really matter if you were sending data to all slaves or just to one. Consecutive communication may have some diagnostic value, but even if you talk to one device at a tine, there's no guarantee that the device which locked the bus is the same that you wanted to talk to.The question is, why do you need multiple output-only IO extenders all driven the same while you can achieve the same effect with a single IO extender?

author: jeremy0
author_rank: Contributor
timestamp: April 13, 2021, 03:58:07 pm
content: Quote from: NorthGuy on April 11, 2021, 02:08:25 pmWith a single IO extender the 16 control signals need to be distributed to each module.With an IO extender per module (whether using individual or shared addresses) only the two I2C signals need to be distributed.

author: jeremy0
author_rank: Contributor
timestamp: April 13, 2021, 04:02:25 pm
content: Quote from: bson on April 10, 2021, 11:20:35 pmIt's not mentioned in the data sheet.In any case, what use could be made of it?

author: gnuarm
author_rank: Super Contributor
timestamp: April 13, 2021, 05:43:53 pm
content: Just a comment, SPI devices would be very easy to wire in parallel knowing it will work. You don't even need special IO expanders. Any double buffered shift register would work such as 74HC595. Two devices in series give 16 bits and cost less than a quarter US together. It does use 3 pins, clock, data and latch controls. You can add a simple RC timing circuit to the clock to generate the output register clock if you want to keep the interface as two lines. Heck, you can also use an RC on the clock to capture the data using PWM.Line is high by default. Short low time shifts in a '1'. Longer low time shifts in a '0'. Much longer low time loads the output register.

author: bson
author_rank: Unknown
timestamp: April 15, 2021, 07:25:29 pm
content: Quote from: jeremy0 on April 13, 2021, 04:02:25 pmIt would allow you to broadcast to all devices on the bus simultaneously.

author: Microdoser
author_rank: Frequent Contributor
timestamp: April 15, 2021, 08:11:27 pm
content: Quote from: bson on April 15, 2021, 07:25:29 pmI2C allows you to do that anyway There is usually only one master and that is able to transmit to dozens of devices. It is able to transmit to all devices on the bus simultaneously without any extra hardware. Even if they have the same address.You only need hardware if you want to communicate with one device but not any others that have the same address.In the case proposed here, that is where you want all devices with the same address to always receive the same commands, you can just connect them to the bus and that will be the case. There may be issues with data sent from the slaves, but that is not a requirement in this case.