OK, so back to deeper debugging. (I have already fixed a good deal of wrongly assigned pin numbers and loose or badly soldered wires in this wire-monster.)
The loop currently only contains the call to taskManager.runLoop(), nothing else. Listeners only send a quick message to USBSerial. Nothing more. If there is any mistake, it must be in the setup or wiring (if not HW or the library). The setup starts with:
multiIoAddExpander(multiIo, ioFrom23017(EXP1_ADDR, ACTIVE_LOW_OPEN, EXP1_INT), EXP_PIN_ALLOC);
multiIoAddExpander(multiIo, ioFrom23017(EXP2_ADDR, ACTIVE_LOW_OPEN, EXP2_INT), EXP_PIN_ALLOC);
multiIoAddExpander(multiIo, ioFrom23017(EXP3_ADDR, ACTIVE_LOW_OPEN, EXP3_INT), EXP_PIN_ALLOC);
multiIoAddExpander(multiIo, ioFrom23017(EXP4_ADDR, ACTIVE_LOW_OPEN, EXP4_INT), EXP_PIN_ALLOC);
multiIoAddExpander(multiIo, ioFrom23017(EXP5_ADDR, ACTIVE_LOW_OPEN, EXP5_INT), EXP_PIN_ALLOC);
switches.initialiseInterrupt(multiIo);
Then there is "switches.addSwitchListener(ENC01_S, &buttonListener, repeatInterval, true);" for each of the 12 encoder buttons and the other 24 buttons.
Then there is "switches.setEncoder(0, new HardwareRotaryEncoder(ENC01_A, ENC01_B, onEnc01Change, ENC_HW_ACCEL, ENC_TYPE));" for every encoder. 10 of them at the expander pins (>100), 2 of them on native SAMD21 pins (<100).
BTW, when I tried to allocate 100 pin numbers (here as EXP_PIN_ALLOC constant) for each expander, the sketch freezed and I was unable to even upload a new, fixed sketch. I had to try about 20 times before I somehow managed to start the upload just between the reboot and the freezing of the sketch. So, there is probably some limit on the amount of pin numbers on the multiIo, which bricks the whole controller? With EXP_PIN_ALLOC set to 20 it works.
Following is "switches.changeEncoderPrecision(0, maximumEncoderValue, 0, false, 1);" for each encoder.
(BTW, this was a cause of serious issues for some time: without the last two values (which should be defaults) it is actually the shorter/non-overloaded version of the method that gets called insted of the longer one and it has a completely different meaning - setting the default encoder (no. 0) to the first value as maxValue! This ambiguity is indeed very confusing!)
That is basically everything, except of initialization of all LEDs and OLED displays just for testing. (Also a strange issue, but not concerning IoAbstraction: the pin A4 does not work as CS output for the SPI displays, while A3, A5 and other pins seem to work. Maybe, there is some HW issue with the SAMD2 module itself?)
P.S.: And sorry for the confusion concerning PCF8575... I am still completely puzzled where did I get the idea that it can read analog input... and how did I manage not to notice it is a nonsense until now. Now I am looking for another solution.