I2C on Raspberry Pi 4B has wrong clock rate?

From: Daniel O'Connor <darius_at_dons.net.au>
Date: Wed, 13 Nov 2024 03:57:34 UTC
Hi,
I have an RPi4B with (currently) FreeBSD 13.1 on it which has a PiJuice (https://github.com/PiSupply/PiJuice/tree/master) hat on it as a mini UPS.

This has an I2C interface which emulates an RTC at 0x68 as well as has its own control/status at 0x14.

If I boot up Linux this is detected fine, eg
doconnor@rpitest:~ $ i2cdetect -l
i2c-0	i2c       	i2c-22-mux (chan_id 0)          	I2C adapter
i2c-1	i2c       	bcm2835 (i2c@7e804000)          	I2C adapter
i2c-10	i2c       	i2c-22-mux (chan_id 1)          	I2C adapter
i2c-20	i2c       	fef04500.i2c                    	I2C adapter
i2c-21	i2c       	fef09500.i2c                    	I2C adapter
i2c-22	i2c       	bcm2835 (i2c@7e205000)          	I2C adapter

doconnor@rpitest:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- 14 -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

doconnor@rpitest:~ $ i2ctransfer -y 1 w1@0x14 0x40 r1
0x34

And the logic analyser I have sniffing the bus shows what I expect:
i2c-1: Address write: 14
i2c-1: ACK
i2c-1: Data write: 40
i2c-1: ACK
i2c-1: Start repeat
i2c-1: Read
i2c-1: Address read: 14
i2c-1: ACK
i2c-1: Data read: 34
i2c-1: NACK
i2c-1: Stop

I checked using a 'scope and the bus appears to be running at about 40kHz (bit weird, but OK..)

However on FreeBSD it looks like the I2C bus is not working correctly, I have modified config.txt as per https://lists.freebsd.org/pipermail/freebsd-arm/2021-May/023713.html (otherwise the bus hangs).

Most of the time scanning fails, if I spam it I get:
[rpi13 3:41] ~ >while [ 1 ]; do
sudo i2c -m tr -s 2>/dev/null | grep -v none
done
Scanning I2C devices on /dev/iic0: 68
Scanning I2C devices on /dev/iic0: 68
Scanning I2C devices on /dev/iic0: 68
Scanning I2C devices on /dev/iic0: 14
Scanning I2C devices on /dev/iic0: 15
Scanning I2C devices on /dev/iic0: 68
Scanning I2C devices on /dev/iic0: 14 68
..

ie 15 is definitely wrong, "14 68" is what I would expect.

If I try and read the pijuice firmware version:
[rpi13 3:45] ~ >while ! sudo i2c -m tr -a 0x14 -d r -c 1 -o 0xfd; do
done
i2c: ioctl(I2CRDWR) failed: Input/output error
i2c: ioctl(I2CRDWR) failed: Input/output error
i2c: ioctl(I2CRDWR) failed: Input/output error
i2c: ioctl(I2CRDWR) failed: Input/output error
i2c: ioctl(I2CRDWR) failed: Input/output error
i2c: ioctl(I2CRDWR) failed: Input/output error
i2c: ioctl(I2CRDWR) failed: Input/output error
i2c: ioctl(I2CRDWR) failed: Input/output error
17

ie it fails often and also usually gets the wrong answer (should be 1.6)

Checking with the 'scope shows the bus running at about 200kHz however sysctl says it should be 100kHz:
[rpi13 3:54] ~ >sysctl dev.iichb
dev.iichb.0.debug: 0
dev.iichb.0.rise_edge_delay: 48
dev.iichb.0.fall_edge_delay: 48
dev.iichb.0.clock_stretch: 64
dev.iichb.0.frequency: 100000
dev.iichb.0.%parent: simplebus0
dev.iichb.0.%pnpinfo: name=i2c@7e804000 compat=brcm,bcm2711-i2c
dev.iichb.0.%location:
dev.iichb.0.%driver: iichb
dev.iichb.0.%desc: BCM2708/2835 BSC controller
dev.iichb.%parent: twsi

I tried setting the frequency but it does not 'stick':
[rpi13 3:56] ~ >sudo sysctl dev.iichb.0.frequency=10000
dev.iichb.0.frequency: 100000 -> 100000

Does anyone have suggestions for what I can try?
Thanks.

--
Daniel O'Connor
"The nice thing about standards is that there
are so many of them to choose from."
-- Andrew Tanenbaum