Hi,

Is that what you are seeing?

It has nothing to do with this, I'm not even close to the page
boundaries. I'm trying to write and read the first ~4 bytes. I've
tried a million things now without much success. One thing I do which
I know I shouldn't is using RF_CALL_BLOCKING everywhere. Could this be
the cause?

No, I don't think so.
The failure that you describe is so specific, I don't think the RF_CALL_BLOCKING mechanism, which is extremely generic, could have any effect on this.
If there were something wrong with that macro, I would expect the entire transfer to fail, not just one byte.

RF_CALL_BLOCKING is a while(1) loop that polls the resumable function _in place_. So no other task will run during that call (except interrupts of course):
https://github.com/roboterclubaachen/xpcc/blob/develop/src/xpcc/processing/resumable/macros.hpp#L146-L152

Note that hardware I2C is interrupt driven, so it will definitely execute during that macro.
SoftwareI2cMaster executes completely within the `start` method of I2cMaster, which is called inside the macro (somewhere in the driver) and therefore also executes during that macro.

Using RF_CALL_BLOCKING is fine _both_ inside and outside of a Protothread.
But particularly for I2C, which is quite slow compared to the CPU speed, you can use time during the transfer to switch to other protothreads and do other things.
Hence the recommendation to call your resumable functions using PT_CALL from inside a Protothread, because it makes it a lot easier to add more tasks in the future and make them execute in parallel.

Cheers,
Niklas