raspberrypi / firmware

This repository contains pre-compiled binaries of the current Raspberry Pi kernel and modules, userspace libraries, and bootloader/GPU firmware.
5.14k stars 1.68k forks source link

i2c-0 broken #382

Closed richard-tx closed 9 years ago

richard-tx commented 9 years ago

I2c bus 0 appears broken as verified by Joan. It appears that bit 9 of the i2c packet is being held low. See discussion at http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=102130

6by9 commented 9 years ago

I could be wrong, but I believe that is correct. http://en.wikipedia.org/wiki/I%C2%B2C

After every 8 data bits in one direction, an "acknowledge" bit is transmitted in the other direction. The transmitter and receiver switch roles for one bit and the erstwhile receiver transmits a single 0 bit (ACK) back. If the transmitter sees a 1 bit (NACK) instead, it learns that:

(If master transmitting to slave) The slave is unable to accept the data. No such slave, command not understood, or unable to accept any more data. (If slave transmitting to master) The master wishes the transfer to stop after this data byte.

So you are seeing the receiver acknowledging the packet correctly. The next device doesn't exist so doesn't ACK the message. That's how I2C works.

richard-tx commented 9 years ago

I2cdetect does not detect a device that is connect to bus 0. It does detect a device that is plugged into bus 1.

Two people have seen this.

6by9 commented 9 years ago

I was referencing your apparent diagnosis that bit 9 being held low by the device as being the breakage. That is not broken, it is the correct behaviour of I2C.

Why the Pi is not seeing that ACK bit is the bigger question.

You appear to hacking the pin config by hand. I believe that has changed for Pi2. It'd be worth downloading wiringPi (http://wiringpi.com/download-and-install/) and using "gpio readall" to dump out the gpio config before and after your shell script. You don't actually state which GPIOs you're trying to use (i2c-0 normally being reserved for use by the GPU), and both 0/1 and 28/29 are referenced in your script. Have you arranged appropriate pull-ups for the I2C lines?

richard-tx commented 9 years ago

Whether of not I run my script doesn't seem to matter. the report from a gpio readall does not change and according to what I am seeing, it doesn't need to.

Appropriate pullups are used.

When the B+ model came out, I had some issues getting i2c-0 functional running Jessie.. Joan helped figure that one out. Things have changed again with the pi2 and the current release.

I have posted the output of a gpio readall on the forum. Posting something like that here is pointless due to formatting issues. The summary is that both is2-0 and i2c-1 look the same. ALT0 and V=1

I could run jessie, but that would be outside of the mainstream. I am not opposed to that, but I would prefer to stay with a supported OS as this whole exercise is for a free-ware hardware/software project.

The GPIOs that are supposed to be used are header pins 3 and 5 (i2c1) as well as Header pins 27 and 28 (i2c-0 or IDSC and IDSD)

My script does not detect that anything is wrong with the default configuration so it makes no changes.

6by9 commented 9 years ago

I'll give you that something funny is going on. I've got a camera module attached to i2c-0 that the GPU sees perfectly under normal conditions. Reconfigure the kernel to add i2c-0 and neither processor can then see the camera. I wouldn't have expected to see any change there.

The firmware actually dynamically reconfigures the ALT function selection of GPIOs 0/1 or 28/29 as the Compute Module shares the one i2c controller between the two sensors. Hacking the firmware to not switch back again (so GPIOs 0/1 should remain at ALT0 instead of INPUT), and gpio readall doesn't see a difference - it was read as INPUT initially, and remains at INPUT. That half says to me that there's some caching going of peripheral registers, and that can't be a good thing. Or wiringPi isn't doing what I expect. Need the experts in on this one.

pelwell commented 9 years ago

It's on my list for tomorrow.

richard-tx commented 9 years ago

I would expect the camera to stop working if i2c-0 is enabled. Since my application has nothing to do with the camera, that is OK. In my application, I-O capacity is what is supremely important.

6by9 commented 9 years ago

Well what would I know - I only worked at Broadcom for 7 years working on this and previous chips. I would expect badness if both processors try accessing the same I2C peripheral at the same time, but one at a a time they should be fine. It's just an I2C device that should respond on i2c-0.

Bye bye. I'll remember to ignore your posts in the future as you clearly don't actually want help or input from others. @pelwell Good luck.

pelwell commented 9 years ago

Thanks for your help, @6by9. Have a good one.

pelwell commented 9 years ago

The fact that i2cdetect is prepared to look at bus 0 shows that the platform device has been created correctly. The i2c driver takes care of changing the pin mode, so you shouldn't need your Python script (which won't work on a Pi2 anyway because the I/O peripherals are mapped at 0x3f000000).

The first thing to report is that i2c0 access from the ARM works on my Pi2, at least well enough to detect and read a HAT EEPROM:

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

I know that doesn't help you, but it's an interesting data point, and it makes the problem harder to investigate.

Thinking that my testing hadn't been thorough enough, I located an external I2C device (a BMP180 temperature sensor), hooked it up to pins 27 and 28, and got this:

pi@raspberrypi:~$ sudo i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77

Digging deeper, I kept running into the lack of interlocking between the two sides when it comes to i2c_vc - the both sides think they own it, and are not averse to resetting the device while the other side is using it. On a Pi 2, depending on the board revision, that i2c0 may be used to talk to the ambient light sensorvoltage regulator, but I see from the forum post that you have a rev 1 Pi 2 so that shouldn't affect you.

I'm in the middle of adding some extra interlocking on i2c0 (with a way of defeating it), and I'll be curious to see if it makes a difference for you, but if throughput is your priority then it may slow things down sufficiently between transfers as to be unusable.

pelwell commented 9 years ago

Hmm. After swapping for a Rev 1.1 Pi2 I'm no longer seeing anything using those pins. Watch this space.

pelwell commented 9 years ago

Rev 1.1 Pi2's use I2C slightly differently than the earlier 1.0 variants. This resulted in the BSC0 (I2C0) function being mapped onto two sets of pins simultaneously, which stops it working, but it wasn't obvious because HAT EEPROM is read successfully.

I have a fix for the next firmware release that removes the bogus mapping, but in the meantime there is a workaround:

echo 28 | sudo tee /sys/class/gpio/export
echo 29 | sudo tee /sys/class/gpio/export
echo in | sudo tee /sys/class/gpio/gpio28/direction
echo in | sudo tee /sys/class/gpio/gpio29/direction

This removes the ALT0 (BSC0) function on GPIOs 28 and 29, allowing it to work on GPIOs 0 and 1.

superderp commented 9 years ago

This worked perfectly, small oled-screen showed up out of nowhere when performing i2cdetect -y 0. One note, the paths where sudo tee /sys/class/gpio/gpio28/direction.

Thanks a lot for fixing this, it really helped. :-) :+1:

richard-tx commented 9 years ago

Yes the paths were wrong but I posted the corrected commands on the forum.

i2cdetect 0 does indeed work now, Thanks bunches Phil.

richard

pelwell commented 9 years ago

Are you confirming that the proper fix works (it is now in rpi-update and the kernel source), or just the workaround?

Thanks - I knew I should double check the paths - I've fixed them now.

pelwell commented 9 years ago

I'll take that as a "Both". 8-)

richard-tx commented 9 years ago

I am closing this issue as we now have a work around. I presume that the base code will be fixed in the next release.

Thanks to Everyone

richard-tx commented 9 years ago

Phil, I will attempt a firmware upgrade later. If that proves successful, I will close this issue.

richard

richard-tx commented 9 years ago

I did a rpi-update and all is well. Thanks very much everyone. I am closing this issue.

richard