There are two solution for running I2C devices that require clock stretching at the bottom of this thread A Summary with downloads is here

I am trying to use a BV4205 (I2C ADC converter) from a Raspberry PI - but I am unable to "see" this device on the I2C bus.

On my prototyping board I have added pullup resistors to the SDA / SCK lines and have other I2C devices connected: 2 * MCP23017 (port expander), BV4213 (motor controller). I can detect these readily on the I2C bus:

Without i2cdetect I can't be sure what address to use.
Assuming 7-bit addressing (as seems to be the case from the BV4213) I have attempted to send commands to address 0x22 (7-bit equivalent of default address: 0x62). However, this results in an i/o error:

The address is 0x31 This is on the datasheet at 0x62 which is the 8 bit address so device by 2 to get 0x31. Also if you get the chance try some of the command line options that are available for i2cdectect:
[man.cx]

I am going on holiday now for a few days. When I return I intend to try a different python library to control the I2C bus (quickwire rather than SMBus) - I will let you know if I have any success when I return.

I have been experimenting with the Quick2Wire python API for the Raspberry Pi (see: Quick2Wire). This provides much better transactional control over reads / writes than the SMBus API. Using this I have been able to successfully use the BV4213 to control a stepper motor.

There is quite clearly something the 4205 does not like about the way i2c-tools works but unfortunately I don't have a Linux box with GPIO at the moment so can't analyse the problem. I think the RPi's are about 3 weeks off so I am not able to do anything until then -- unless I can get the old NSLU2 going.

I have looked at the Clk and Data lines with a multimeter and after running i2cdetect the BV4205 jams them in the low state. Hence you can't see any other devices on subsequent runs of i2cdetect after running i2cdetect the first time. Cycling the power to the BV4205 chip then releases the bus.

Using an oscillosope on the lines shows activity just before the bus hangs.

I haven't tried the -q option to i2cdetect but it sounds like it hangs the bus anyway from what Ken has said.

I've tried avoiding using i2cdetect at all so the bus doesn't hang. I've written a C test program to do read/writes to it with ioctl() Linux call. If I just write select channel 0 (command 1), then I don't get an I/O error. If I try to write a do conversion (command 2) or do a write command 3 and read back conversion status then I get an I/O error.

I thought there might be something wrong with the i2c bus on my RPI, but connecting the ByVAC RTC module on it's own works fine with the RPI. Also checked BV4205 chip still working with my PIC32 board and it works fine. So definitely specific to the BV4205 and the RPI.

It is strange as the 4205 woks okay with other hardware so there is some subtle difference when using lm-devices.

I havn't looked but is is possible that the clock is running at > 100k? I think that bit banning is used rather than hardware and so ther must be some delay incorporated. Can the speed of the clock be controlled as the PI runs faster than most embedded linux boxes, could this be the problem? If you have a scope then you may be able to work out the clock speed.

I will look into this and update the firmware on the BV4205 if required as soon as I have a working linux box with a GPIO.

I have a solution, I think, but the problem is probably with the actual driver and so it won't matter if C, Python or any other language is used as they all open 'i2c-n'. I have got the BV4502 working using the BV4205 test command '0x55' but this is by introducing a delay between the write and read. I will check it and write it up tomorrow.

I suspect that the actual problem is with the clock stretch timeout which is a register setting on the Broadcom IC. This is set to a very short period. It really should be an option of the driver as should the speed of the bus, which incidentally is 100KHz.

I would be happy to change the settings of the bus in order to make it work, after all, it is something I am trying to do anyway as I would like to allow for slightly longer cables and that would require lower frequency. Even minimum actually works for me!

jimeer Wrote:
-------------------------------------------------------
> I suspect that the actual problem is with the
> clock stretch timeout which is a register setting
> on the Broadcom IC. This is set to a very short
> period. It really should be an option of the
> driver as should the speed of the bus, which
> incidentally is 100KHz.

The problem is turning out to quite difficult to track down. I am now just at the stage (almost) where I can talk directly to the Broadcom chip - This, for me, was incredibly difficult sifting through the Linux noise (all of the online information that looks promising but turns out to be only partly relevant.) to be able to compile a device driver. The image is 3.1.9+ but the online headers requires are 3.2.23, also when making the headers the file Module.symvers is not created which is a crucial part of being able to compile a device driver -- and so on.

At some point it would be nice to have a cross compiler environment so that I can compile the kernel and so have all of the necessary header and object files that are needed.

There are three main problems:
1) The current driver bcm2708 does not allow any changes to the Broadcom I2C hardware registers, it would have been so easy to provide this through ioctl.
2) The actual hardware I2C provided by the IC looks to be a bit too simplistic for driving the more complex I2C devices. I may be wrong as I have not looked at this properly yet but I don't think there is any control over start/stop etc. unlike that provided by other chip manufacturers. It may be necessary to resort to a bit banging method.
3) These is a clash between the way my I2C salve works and the way the linux master works, this I want to get to the bottom of this coming week hopefully

Thank you for all your effort, I am indeed looking forward to have the relay working!

Regarding the register access - I believe I was able to write to them using the memory-mapping, an example of my code is here. I am not sure if it all has any relevance to what you are doing but I believe that using the same principle I should be also able to write into the i2c registers for sending information (I just did not have that interest).

Thanks for all your effort to try and diagnose the issue. I have only a little experience with I2C and even less writing linux kernel drivers. I can't find anything directly useful on the Raspberry PI forums other than the article you have already identified (I initially suspected it was a clock stretching issue but I was not able to confirm this). There are some posts requesting the ability to change / set the clock frequency but without resolution. Perhaps a more focused post on the PI forums may provide some useful information ?

Well I finally managed to find out the cause of the problem. It would have taken a lot longer without the code that petr supplied. This code enables access to the registers without the need to go into kernel space although it does need to be run with sudo (there are probably ways round this).

// skip this bit if you know what clock stretching is //
Just in case you don’t know, clock stretching is a method of slowing down the I2C bus for slower slave devices. It is the equivalent of hardware handshaking (RTS/CTS) on a serial bus. The slave at any point in time (see later) can hold the clock line low, the master should check for this and wait until the slave releases it. In this way the slave can have time to do what it needs to do without missing any clock pulses. The master of course will not wait forever and so will time out if the slave holds the line too long although once this happens the bus is dead anyway if the slave will not relinquish control.
// end of clock stretch explanation //

The problem is with clock stretching, it took so long because I needed to be certain of the exact nature of the problem. It was confusing because the BCM, I2C hardware does indeed have a register dedicated to the clock stretch time out. This is either not working or the stretch is only handled at byte level. In other words a check for the slave holding the clock low is only carried out at certain times (or not at all) see later.

The solution.
There are two solutions, one involves changing the firmware on the BV devices and the other is to use a bit banged I2C interface:

Bit Banged interface (zip file here)
I have written an interface that can be compiled as follows:
gcc –o i2cbb bcm2835_i2cbb.c bcm2835.c
and can be run: sudo ./i2cbb

The link to the GPIO is done by the code in bcm2853.c (//www.open.com.au/mikem/bcm2835/) The file could be made smaller by just extracting the bits needed from this or to compile to object and use the .o file. I did try to install it but it didn’t seam top make any difference. I started out with the code provided by petr (http://pastebin.com/uRAPjcN0) given in the post above.

The bcm2835_i2cbb.c file contains a main() and examples within that for running. One advantage is that any GPIO pins and even more than one set of pins can be used for the interface. The pins I used are GPIO 17 and 21 (sda,scl). These correspond to physical pins 11 and 13, see [elinux.org].

There is an example for i2cdetect, the same as i2c-tools but because there is access to start and stop conditions, this is safe to run no matter what is connected to the bus. The code is set to run at 100k (clock delay 300) however the delay is simply a counter and so there will be problems if the hardware changes.

To test the program un-comment the lines as required from main(). I suppose this could also be compiled as a .o file and used as a library. It would be nice to have something like this as a proper device driver being an alternative to the I2C driver provided.

Firmware Change
The BV devices are more complex than the usual RTC and EEPROMS and so need a bit of time to process the information, hence clock stretching. Some earlier firmware I have eliminates the need for clock stretching as it buffers the data. However it is possible for the buffer to become full of course and without clock stretching how is this controlled other than the user being aware and not sending too much data at once. A backwards step I think.

I will wait until the BCM chip is fixed, thanks to petr for the link about clock stretching not working on the BCM.

A big thank you to all who have contributed to this. I can now say I know much more about Linux than I did two weeks ago, I also don’t need to spit on the ground every time Raspberry Pi is mentioned anymore.

Another Solution
I have been dabbling with the RPi some more and was even contemplating changing the firmware on the premise that if you can’t bet them join them; even if it is a backwards step. To cut short a long story I found that by adjusting the DEL register this effectively alters the clock frequency just enough for the BV42nn devices** to work. This zip file contains a program that needs to be run just once in order to change the DEL values. From then on all of the above examples will work, e.g.
i2cget -y 0 0x31 0xA0 w // will return the firmware version
i2cdetect –y 0 // also works
and the Python (quick2wire) examples work.

** I have only tested the BV4205, however all of the BV42nn (except BV4213) share the same I2C firmware.

I have tried this alternative solution - this fixes the issue. I am able to successfully configure the BV4205 and read back ADC data (single values or multiple values with auto scan). Note, I did need to use the -q option for i2cdetect to identify the BV4205: i2cdetect -q -y 0.

I have tried this with a number of other I2C devices (port expanders, LCD backpack) and these seem to be unaffected by this change.

I'm trying to use the BV4205 with a raspberry pi Model B revision 2.0 and so far I have managed to detect the device only one time. (and by using the ./i2c_slow version of the bcmdel fix)

I don't know if revision 2.0 is the cause of the problem. The main difference with revision 1.0 regarding i2c bus is the change of the pins of i2c-0 with those of i2c-1. So, I'm still using pins 3 and 5 but with i2c-1 and not with i2c-0.

Question:

Could be something wrong with the connection of the BV4205 to the circuit? Actually while I was writing this message i realized that the FR pin (on the drawing on the chip) is not pin number 4 (factory / ground).. so that could be the issue? Please check this image:
[i149.photobucket.com]

Thank you
Nick

P.S. of course i will try this when I'll be back at home tonight and give you an update

UPDATE: still not working.... any other ideas? :-| What else could be wrong...? In the code of bcm_del.c could BCM2835_I2C0_BASE be wrong since I'm using i2c-1 and not i2c-0.

UPDATE2: Yes it seems that the address of BCM2835_I2C0_BASE is 0x205000 while the address of BCM2835_I2C1_BASE is 0x804000. However... guess what.... still not detected.. :-/

UPDATE3: Yes, it works!! You have to replace 0x205000 with 0x804000 in order to work with raspberry pi model B revision 2.0. Also, if you use i2cdetect -y 1 before sending any other command to the BV4025 the chip crashes (SDA and SCL at zero voltage all the time).. otherwise it works as expected and it's awesome!

The BV4627 uses a different technology from the BV4502 and so there are no problems interfacing this device as there are with the BV4502 - so no need for the delays or any modification of the drivers.

HOWEVER: There is a bug on firmware version 1.1 which causes i2c not to work with the RPi, all other I2C master I2C devices work, Arduino etc. If you can't see it using i2cdetect then it is likely that you have firmware 1.1. Contact me at this email address to sort out an upgrade.