C001 i2c issues (but imp004m works)

I have the c001 dev board using 2 i2c busses. One is the bus that is tied to the ICs included on the dev board and another is to a chain of I/O for my project. When I run a bus scanner (like the one provided in the utilities package), I can sometimes see 1 or 2 of the 4 devices but after a reset and re-scan I see nothing. If I disconnect those i2c wires from the c001 and connect them to an imp004m dev board on my desk, every chip appears every time without fail (with exactly the same code, except for the name of the i2c bus).

Are there issues with i2c on the imp c001? I’ve tried i2cXBA and ic2JH. Both perform the same.

No known issues, no. What OS version are you on? What value pull-ups are you using? How long are the wires?

Scanning a bus isn’t really a supported i2c operation; you’re relying on the devices not being upset by the zero byte write.

Sure, I get that there’s no true “i2c scan” but like I said, I’m using the function from your utilities package that scans and lists out (most) connected devices:

    for (local i = 2 ; i < 256 ; i += 2) {
        if (i2c.read(i, "", 1) != null) server.log(format("Device at 8-bit address: 0x%02X (7-bit address: 0x%02X)", i, (i >> 1)));
    }

My entire point is that all of my code works just fine with the i2c lines connected to a port on a imp004m dev board but when connected to the c001, I can only get a read from 0-1 of the connected ICs.

My pull ups in both cases are 2.2k and the total length is about 4 inches. What I’m essentially asking, is why would it work so well on the 004m but not work at all on the c001 (dev board with headers soldered on)?

Honestly, it’s hard to tell. There are different CPUs involved and different wiring, but I2C is slow and generally not super fussy. It’s possible there are bugs with the I2C driver on the STM32H7 CPU - eg the very fact you’re trying to talk to devices that don’t respond could be causing the bus to not reset its state correctly or something similar.

If you don’t scan, and instead just actually try to talk to each device that you expect to be there - with a valid request - does it work fine? That would confirm the above hypothesis.

We should remove that bus scan from the “utilities” package, as it’s not good practice in general. Not all I2C devices will respond to a read transaction, there are such things as write-only I2C devices. for example.

If I slow the speed all the way down to 10kHz I can at least consistently get a read from all the ICs (though the imp004m performs just fine at 400kHz).

I spent the morning developing some libraries using the imp004m with all the devices connected and I didn’t have any bus-related errors. This afternoon I copied everything over to the c001 and took the bus speed down to 10kHz and I would say that every 3rd i2c.read gives me back
TRANSMIT_SELECT_ERROR or MASTER_RECEIVE_SELECT_ERROR

I think you’ve grabbed onto the scan issue a little tightly. Obviously that part is not ending up in my final code and the fact is that all my my ICs do respond to that function on the imp004m. We can debate the merits of such a function another time (though if you don’t write it, you force me to write it each time).

The question was “if you talk to the ICs directly (no scanning), on impC001, do all of them respond”? Not sure if that’s what you were answering above - it sounds like you’re saying that they don’t all respond even at 10kHz?

If so, that sounds a little like a clock stretching issue. Can you give part numbers of the devices in question? If a slow clock works but a fast one does not then it’s usually because the device is trying to stretch the clock (the slave holds SCL low to slow down the master). That should be supported by the I2C peripheral in the STM32H7, but it’s one of the most buggy areas of I2C hardware in my experience.

My comment on “scanning” is that there’s no such thing on i2c. You can try to address each device in turn and see if you get an ACK on the address byte, but aborting the transaction at that point is not something that’s documented for most parts and so I2C peripheral blocks (master or slave) may do undefined things.

If I talk directly with no “scanning” there is no change. All of the ICs do have an actual read operation on the 0 register so the scan would have no ill side effects in this case.

All of the slaves are other microprocessors. I can’t share much information except that they are all AVRs of one sort or another and that one of them specifically does not implement stretching. I’ve sent requests asking about the other two. I have experienced read/write issues on all of them including the one that states that it will not mess with scl.

Any chance you can get a logic analyzer trace - or if not, a scope shot - of a failure? There does appear to be something strange going on (like, I can see a stretch of >40ms would fail, but that seems a pretty huge stretch).

I2C is tested automatically by our system tests, but obviously we only test against a limited number of targets; in general, everyone using an impC001 devkit uses I2C (as the PMU, accelerometer, temp/humid sensor and gas gauge are all on I2C). These all work fine at 400kHz, but they are all hardware I2C devices.

Usually MCUs will be much slower to respond as they are firing interrupts off and (usually) stretching SCL until code runs to form a response or remove a byte from a holding register.

If you can share details privately on a support ticket then that would also be helpful.

Someone is borrowing my scope right now but I’ll take some traces when I get it back. When I sat down this morning to test it connected to the c001, everything worked just fine for about 5 minutes and then I started seeing errors at a similar rate to the last few days. Not sure what that means.

Hmm. Have you got a good ground connection between the boards?