Faster IIC
Rick Murray (539) 13840 posts |
May I propose that the default IIC speed on the RaspberryPi (and possibly the newer SoCs in general) be increased to 400kHz instead of 100kHz? The faster speed was introduced in 1992, so it seems reasonable to assume that most devices will be compatible, twenty two years later and anyway Fast Mode predates more recent changes such as the use of 3.3V or even 1.8V as IIC signal levels. I have hacked my Pi’s IIC driver to run at about 400kHz (binary hack, as described in the OLED docs) because the slower way was too slow and unable to send a frame within the OLED’s native refresh rate. I would propose trying this in a nightly build to see “what breaks”. The CJE hardware on a 256MB issue 2 Model B Pi works, but that is all that I am able to test. If no reports of IIC problems arise, it should pave to way for running IIC faster “as standard” on modern devices. |
Jon Abbott (1421) 2651 posts |
Is there a legal way to set the I2C bus speed other that hack the IIC driver? All Pi’s suffer from a hardware bug in the Broadcom SoC that causes issues with I2C devices that use clock stretching. One workaround is to use the i2c-gpio overlay which bitbangs I2C, the other is to slow the I2C bus down. |
Jeffrey Lee (213) 6048 posts |
No.
Possibly that’s the bug that we’ve worked around by having the Pi IIC driver run in a completely blocking manner, with interrupts disabled? (Dave Higton should be able to confirm)
Yeah, I did realise a couple of weeks ago that we could probably just switch to using bit-banged IIC in order to avoid needing to perform transfers with interrupts disabled (the kernel does all the hard work, the HAL just needs a couple of calls to read & write the control lines). And if this is a different bug, it’s all the more reason to switch. |
Dave Higton (1515) 3526 posts |
I’m not aware of any bug. I wrote the IIC driver like that because I discovered that it would generate the repeated start condition under those circumstances – IIRC (it’s a long time ago that I wrote the driver!) the transfer for the data part had to be initiated before the peripheral had a chance to issue the stop condition. The repeated start condition seems to be not well understood. It is part of the standard, but many people seem to just generate a stop followed by a start. My understanding is that the Acorn drivers used to do it. Once you do that instead of repeated start, you’re working outside the IIC specification. It only occurred to me long afterwards that it might be possible to re-enable interrupts after the repeated start has been generated, but I never went back to try.
I had a look at the PCF8583 recently; it’s still in production, and the data sheet still shows it as a 100kHz device. This was the RTC/CMOS in lots of Acorn computers. I would recommend that a call be added to change the IIC bus speed. I think it would probably have to call into the HAL, as I don’t think you can do it in a hardware-independent way. I also don’t know what happens if the CPU clock is changed – does the IIC peripheral come off a constant or variable clock? Dunno. |
Jon Abbott (1421) 2651 posts |
I presume you’ve now read the bug report I linked too and understand the issue. The only real workaround is the bitbang approach, which looks like the route Linux probably took.
From what I understand the I2C clock is derived from the CPU clock, so will possibly change as the CPU clock changes. ie. it’s only running at the set clock speed when the CPU is at its full set clock speed. See this post from one of the Pi engineers that explains things. As the firmware blob also alters the CPU speed when undervolt and thermal limit are detected, you probably don’t get much say it what speed it’s actually running at, only the max speed it can run at. |