Welcome! Log In Create A New Profile

Advanced

BV4205 with a Raspberry PI

Posted by Ken 
Ken
BV4205 with a Raspberry PI
August 09, 2012 11:16AM
NOTE The BV4205 has now been replaced with the P011/2 see [www.pichips.co.uk]


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:

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

BV4213 - address 0x21
MCP23017 - address 0x22, 0x23

My test application can interact with the MCP23017 port expanders and I can interrogate the BV4213 (from the command line as I have not started application development yet):

pi@raspberrypi ~ $ i2cget -y 0 0x21 0xA0 c
0x02
pi@raspberrypi ~ $ i2cget -y 0 0x21 0xA1 c
0x61


However, when I connect the BV4205 to the I2C bus it is not visible and I am no longer able to detect the other devices on the bus:

pi@raspberrypi ~ $ 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: -- -- -- -- -- -- -- --

In addition, my test application is no longer able to interact the the MCP23017 port expanders and I can no longer access the BV4213.

Do you have any suggestions on what may be causing this problem and how I can fix it ?



Edited 3 time(s). Last edit at 12/17/2013 09:39AM by jimeer.
Re: BV4205 with a Raspberry PI
August 09, 2012 12:02PM
What happens if you don't try to i2cdetect?. I suspect that the I2Cdetect causes the BV4205 to keep the clock or data low for some reason.
Ken
Re: BV4205 with a Raspberry PI
August 09, 2012 12:53PM
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:


Python 2.7.3rc2 (default, May  6 2012, 20:02:25)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from smbus import SMBus
>>> b=SMBus(0)
>>> b.write_byte_data(0x22, 0x06, 0x01)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 5] Input/output error
>>> b.write_byte_data(0x22, 0x95, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 5] Input/output error
Using this approach I am able to communicate with the BV4213, example - this will reset:
>>> b.write_byte_data(0x21, 0x95, 0)
>>>
Re: BV4205 with a Raspberry PI
August 09, 2012 01:29PM
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]
Ken
Re: BV4205 with a Raspberry PI
August 09, 2012 02:49PM
Limited success with i2cdump -q option:

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

The BV4205 shows up on address 31 - but only the first i2cdetect, subsequent calls do not show this device

Using this address I am still unable to access the BV4205.
Re: BV4205 with a Raspberry PI
August 09, 2012 03:37PM
What are you sending to the BV4205?
Ken
Re: BV4205 with a Raspberry PI
August 09, 2012 05:49PM
For example, the following will reset the BV4213:

Python 2.7.3rc2 (default, May  6 2012, 20:02:25)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from smbus import SMBus
>>> b=SMBus(0)
>>> b.write_byte_data(0x21, 0x95, 0)
>>>

If I try the same reset command with the BV4205:
>>> b.write_byte_data(0x31, 0x95, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 5] Input/output error
>>>

If I try any of the other commands, I get a similar I/O error.

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.
Ken
Re: BV4205 with a Raspberry PI
August 17, 2012 02:09PM
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.

However, when I try and apply this to the BV4205 I run into problems.

I have verified the address of the BV4205 (0x31):

pi@raspberrypi ~/dev/test $ i2cdetect -y -q 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- 21 22 23 -- -- -- -- -- -- -- -- -- -- -- --
30: -- 31 -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

If I try and issue any commands to the BV4205 I get an IO error. For example, if I try and interrogate the firmware version:

pi@raspberrypi ~/dev/test $ python3 test.py
Checking BV4213...
BV4213 Firmware version:  2 97
Checking BV4205...
Traceback (most recent call last):
  File "test.py", line 275, in <module>
    main()
  File "test.py", line 270, in main
    test();
  File "test.py", line 262, in test
    i2c.reading(0x31, 2))[0]
  File "/home/pi/dev/test/quick2wire/i2c.py", line 72, in transaction
    ioctl(self.fd, I2C_RDWR, addressof(ioctl_arg))
IOError: [Errno 5] Input/output error

The following python3 function is used to derive the above:

def test():
    
    with i2c.I2CMaster() as bus:
 
        print("Checking BV4213..." )
 
        bv4213_firmware_version = bus.transaction(
            i2c.writing_bytes(0x21, 0xA0),
            i2c.reading(0x21, 2))[0]
            
        print("BV4213 Firmware version: ", bv4213_firmware_version[0], bv4213_firmware_version[1])

        print("Checking BV4205..." )

        bv4205_firmware_version = bus.transaction(
            i2c.writing_bytes(0x31, 0xA0),
            i2c.reading(0x31, 2))[0]
           
        print("BV4205 Firmware version: ", bv4205_firmware_version[0], bv4205_firmware_version[1])

I get similar I/O errors if I try other commands, eg: enable autoscan: 0x06 = 1

def enableAutoscan():
    
    with i2c.I2CMaster() as bus:
 
        print("Enable autoscan --> 0x06 = 1" )
 
        bus.transaction(
            i2c.writing_bytes(0x31, 0x06, 1))



pi@raspberrypi ~/dev/test $ python3 test.py
Enable autoscan --> 0x06 = 1
Traceback (most recent call last):
  File "test.py", line 298, in <module>
    main()
  File "test.py", line 293, in main
    enableAutoscan()
  File "test.py", line 273, in enableAutoscan
    i2c.writing_bytes(0x31, 0x06, 1))
  File "/home/pi/dev/test/quick2wire/i2c.py", line 72, in transaction
    ioctl(self.fd, I2C_RDWR, addressof(ioctl_arg))
IOError: [Errno 5] Input/output error
Re: BV4205 with a Raspberry PI
August 17, 2012 06:39PM
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.
Re: BV4205 with a Raspberry PI
August 19, 2012 11:02AM
I get exactly the same issue with my RPI and BV4205.

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.
Re: BV4205 with a Raspberry PI
August 19, 2012 01:04PM
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.

Found this link [lists.lm-sensors.org]

Assuming that udelay is working okay (some reports that is does'nt) then 1/2 of 100KHz is 5uS, however the SMBUS uses 50 - is that why the -q option works?



Edited 1 time(s). Last edit at 08/19/2012 01:27PM by jimeer.
Re: BV4205 with a Raspberry PI
August 28, 2012 08:08PM
Well that’s a week out of my life I will never get back.

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.
Re: BV4205 with a Raspberry PI
September 02, 2012 12:38PM
Great to hear that there was some progress!

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!
Re: BV4205 with a Raspberry PI
September 02, 2012 05:40PM
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.

Myabe this is relevant? I2C clock stretching



Edited 1 time(s). Last edit at 09/02/2012 05:41PM by petr.
Re: BV4205 with a Raspberry PI
September 02, 2012 07:57PM
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
Re: BV4205 with a Raspberry PI
September 03, 2012 10:40AM
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).

Keep up the great work!
Re: BV4205 with a Raspberry PI
September 03, 2012 05:05PM
Thanks,
I was told that it was not possible to write to the CPU registers from user space hence all of the work with device drivers. I will look at the code with interest, tomorrow hopefully.
Jim
Ken
Re: BV4205 with a Raspberry PI
September 03, 2012 07:10PM
Hi Jimeer

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 ?

Once again, thanks for all your effort.
Ken
Re: BV4205 with a Raspberry PI
September 05, 2012 07:27PM
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.
Re: BV4205 with a Raspberry PI
September 19, 2012 07:20PM
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.
Ken
Re: BV4205 with a Raspberry PI
September 23, 2012 04:57PM
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.
Re: BV4205 with a Raspberry PI
November 01, 2012 09:45AM
Hi,

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!



Edited 7 time(s). Last edit at 11/03/2012 12:51AM by nicktgr15.
Re: BV4205 with a Raspberry PI
April 06, 2013 05:43PM
Hi all,
I have the same problem ...

And this is really frustating ...

I'm trying to see the "BV4627-B" the 8 way relay ... connected to the RPI ...

Any idea ? even with the bcmdel program .. it doesn't works ...

Regards,

Didier
Re: BV4205 with a Raspberry PI
April 07, 2013 10:08AM
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.
Sorry, only registered users may post in this forum.

Click here to login