November 07, 2024, 10:32:15 PM

I2C errors when using MOD-IO2 boards

Started by markus2330, June 26, 2022, 02:57:34 PM

Previous topic - Next topic

markus2330

When using two MOD-IO2 boards controlled from one Olimex A20 board, I get I2C errors.
It starts with an ENXIO error, and later ENODEV on I2C communication attempts after the first ENXIO. It also happens when reopening the file handle every time and can even be reproduced with modio2tool:

#!/bin/sh
set -ex

./modio2tool -A 0x20 -T 0xF
./modio2tool -A 0x20 --setpullups 0xF

./modio2tool -T 0xF
./modio2tool --setpullups 0xF

./modio2tool -A 0x20 -i 0
./modio2tool -A 0x20 -i 1

./modio2tool -i 0
./modio2tool -i 1

./modio2tool -p 41
./modio2tool -p 51
./modio2tool -p 61

./modio2tool -i 0
./modio2tool -i 1

./modio2tool -S 3
./modio2tool -A 0x20 -S 3

./modio2tool -i 0
./modio2tool -i 1

./modio2tool -S 0
./modio2tool -A 0x20 -S 0

./modio2tool -p 40
./modio2tool -p 50
./modio2tool -p 60

With following output:

+ ./modio2tool -A 0x20 -T 0xF
+ ./modio2tool -A 0x20 --setpullups 0xF
+ ./modio2tool -T 0xF
+ ./modio2tool --setpullups 0xF
+ ./modio2tool -A 0x20 -i 0
GPIO0: 1
+ ./modio2tool -A 0x20 -i 1
GPIO1: 1
+ ./modio2tool -i 0
GPIO0: 1
+ ./modio2tool -i 1
GPIO1: 1
+ ./modio2tool -p 41
done.
GPIO: 0x10
+ ./modio2tool -p 51
done.
GPIO: 0x30
+ ./modio2tool -p 61
done.
GPIO: 0x70
+ ./modio2tool -i 0
GPIO0: 1
+ ./modio2tool -i 1
GPIO1: 1
+ ./modio2tool -S 3
+ ./modio2tool -A 0x20 -S 3
+ ./modio2tool -i 0
GPIO0: 0
+ ./modio2tool -i 1
GPIO1: 0
+ ./modio2tool -S 0
error!
+ ./modio2tool -A 0x20 -S 0
+ ./modio2tool -p 40
error!
GPIO: 0x00
+ ./modio2tool -p 50
error!
GPIO: 0x00
+ ./modio2tool -p 60
error!
GPIO: 0x00

The errors do not always occur on the same spots but in some sequences an error happened in every try so far.

How can I avoid getting these I2C errors?

markus2330

I just found out that they can also occur when only using a single MOD-IO2 board. So maybe it is only some overload problem:

https://www.olimex.com/forum/index.php?topic=5178.msg21517#msg21517

In the kernel logs I found:
[  719.845050] i2c i2c-2: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x20, flags: 0x0

I don't know if it is related, though.

LubOlimex

How fast are the commands executed? Is there any delay in between?
Technical support and documentation manager at Olimex

markus2330

The delays depend on input, so there is no guarantee of any delay in between. Is there some requirement of a minimum delay? Shouldn't the kernel driver take care of this?

LubOlimex

I am not even sure if modio2tool works fine with latest MOD-IO2 firmware. The tool was published 7 years ago, the latest update to the firmware 3 years ago. Might be that the issue is in the modio2tool.
Technical support and documentation manager at Olimex

markus2330

Errors now occur much less (about 2-3 errors a day when doing two request every 10ms). Relays now work reliable. There was a combination of problems, following guidelines helped me to avoid them:

- larger AC loads (>>10W) might need Snubber circuits
- larger DC loads might need a diode
- avoid switching relays faster than every ~200ms
- avoid Snubber parallel to switch on smaller loads
- avoid multiple appliances that might create interferences on the same board (i.e. connect larger loads to different mod-io2)
- Snubbers as near to load as possible

No guarantee on correctness. The later the guideline the more doubtful you should be ;)

I didn't find any difference in robustness between Mod-IO and Mod-IO2. With Mod-IO2, however, it is a bit easier to separate higher loads to different boards. Even if separated, the ~200ms rule was needed, though.

best regards,
Markus

markus2330

#6
I could improve the i2c problems by reducing the i2c bus speed. The overlay is part of https://opensesame.libelektra.org/ (files/i2c_2_clock_freq_overlay.dtbo see also doc/I2C.md).

ilario

Hi!
I observed ENXIO (errno 6) when I was having more than one communications going on at the same time on the same I2C bus.
So in my case it was a matter of conflicts of a communication overlapping with the other.
I solved using semaphores (I used system-wide ones: https://semanchuk.com/philip/sysv_ipc/ available for Python and packaged in Debian), for making sure that one thread waits until the other thread finished communicating.

Useful for understanding I2C error codes (errno 6 for I2C does not mean "No such device or address."):
https://docs.kernel.org/i2c/fault-codes.html
and the errno-fault name correspondence can be found with:
cat /usr/include/asm-generic/errno*.h


I never saw ENODEV (errno 19).

I saw EIO (errno 5, "I/O error") and when this happened I saw an error in dmesg (kernel logs):
i2c i2c-0: mv64xxx_i2c_fsm: Ctlr Error -- state: 0x2, status: 0x0, addr: 0x70, flags: 0x0this I have no idea why it happens.


LubOlimex

Can be shaky wiring or improper I2C levels. Can happen with longer or thin wires too.
Technical support and documentation manager at Olimex

ilario

Ok, surely I have non-short cables (up to maybe 15 cm).

Using the device tree overlay linked by markus2330, can I set any arbitrary speed or is there a list of valid values? I am on an A64-OLinuXino-2Ge8G-IND.

Copying and pasting here the device tree overlay source for convenience (written for A20-OLinuXino, taken from the link in latest markus2330 post):

/dts-v1/;

/ {
        compatible = "allwinner,sun7i-a20";
        description = "Change I2C2 clock-frequency to 6000";

        fragment@0 {
                target-path = "/soc/i2c@1c2b400";

                __overlay__ {
                        clock-frequency = <0x1770>;
                };
        };
};

LubOlimex

I have no idea but slow I2C speed can also cause the error you get. Try different speeds empirically, probably try higher speed.
Technical support and documentation manager at Olimex