PDA

View Full Version : Help Please - I2C Addressing



Drone
05-21-2008, 10:02 PM
Hello All...

I am trying to address a Silicon Labs (www.silabs.com (http://www.silabs.com)) Si570 LVDS clock generator (P/N 570CAC000141DG) via I2C. The part is on dedicated propeller pins with 10k pull-ups. I also have a 24LC256 EEPROM on the same bus.

The application is based on James Burrows's I2C demo object from ObEx, which uses a slightly modified version of Mike Green's Basic_I2C_Driver. The EEPROM's device address is 1010_0010, the Si570's address is 55h or 1010_101X per the I2C spec where the addresses are 7 digits left-justified and the LSB is the R/W bit. I used AAh or 1010_1010 for the I2C address in the propeller application.

I can write/read to/from the EEPROM just fine. At first I couldn't read the Si570 at the expected register locations of 7 through 12 decimal. So I did an I2C bus scan. I know what the startup values of registers 7 through 12 should look like. Voila, I found them via the bus scan. Here's what I found:




Reg, Addresses, Val
-------------------
R07, 600h-6FFh, E1h
R08, 700h-7FFh, C2h
R09, 800h-8FFh, 86h
R10, 900h-9FFh, 16h
R11, A00h-AFFh, A9h
R12, B00h-BFFh, 9Dh




Each register value appears for 256 bits of location range. Other users of this chip say this is wrong, I should read register 07 at location 07h, and register 12 at Ch. I've looked at the Si570's ANSI C reference software for 8051 from Silicon Labs, that code seems to confirm the register locations are one-to-one with the register number.

But with propeller, not only am I seeing the registers at much higher locations, even the "alignment" of the registers seems off by at least one in the MSBs! When I read and write to the EEPROM, the data and locations are as expected - unlike the Si570.

The Si570 data sheet says the register location addresses auto-increment. Maybe this is causing it? I'm using one readByte per register.

I haven't tried writing to the Si570 yet, I would like to get this read problem fixed first.

Has anyone seen this before? Any suggestions? This is the first time I've dealt with I2C. I have read the NXP I2C manual, but the act of reading doesn't always guarantee complete absorption!

Thanks & Best Regards,

David

Post Edited (Drone) : 5/21/2008 4:06:46 PM GMT

Mike Green
05-21-2008, 10:18 PM
Make sure you're using the proper I2C routines. The EEPROM routines use a two byte address (16 bits) while the Si570 requires a one byte address (8 bits).

Drone
05-21-2008, 11:59 PM
Doh! I forgot to upload the code, sorry... I added the project archive as an attachment to the first post in this thread.

Mike, I'm using ReadByte and WriteByte with the Si570. Hmmm...

The basic_I2C_driver seems to use 16 bit addresses as you mentioned, how to use 8 bit addresses (looking at the driver source more carefully now - should have done that in the first place).

Rgds, David

Post Edited (Drone) : 5/21/2008 4:11:42 PM GMT

hippy
05-22-2008, 12:42 AM
I don't know how it's done in the driver you're using but in the ones I've written I set flags to indicate if the I2C device I'm selecting expects a 7-bit or 10-bit device address and an 8-bit or 16-bit location address and then add a set of IF statements to generate the correct bit sequences after the start bit. I expect you're going to have to modify any basic driver to be a bit more than basic.

Drone
05-22-2008, 01:08 AM
I agree hippy, generality in device address size and location address size is what's needed. I would like to keep 7 or 10 bit dev addr and 9 or 16 bit loc addr when calling the I2C driver. This is important as eventually I plan to call a table of frequency settings from the upper 32k of main EEPROM and write them to the Si570 on the same I2C bus from an LCD/keypad UI. As it stands Mike's Basic_I2C_Driver may be just fine with this as long as we understand there is an 8 bit ($100) offset for 8 bit locations, but I'm not sure this is the case yet. If it is true, then the Basic_I2C_Driver may be fine for any device as long as we add the offset for parts like the Si570 vs. something like the 24LC256 EEPROM. I'm looking at the Basic_I2C_Driver source now, but it is getting late (I'm GMT+7).


hippy said...

I don't know how it's done in the driver you're using but in the ones I've written I set flags to indicate if the I2C device I'm selecting expects a 7-bit or 10-bit device address and an 8-bit or 16-bit location address and then add a set of IF statements to generate the correct bit sequences after the start bit. I expect you're going to have to modify any basic driver to be a bit more than basic.


Will you share these drivers with us? Are they already in ObEx?

Rgds, David

hippy
05-22-2008, 01:36 AM
These are the latest I2C master drivers which are part of the I2C Slave stuff I've been working on. The ProtoBoard version soft-drives the SCL line ( pull-up to 3V3 ), the DemoBoard version hard-drives SCL ( no pull-up ).

Drone
05-22-2008, 11:38 PM
Hi hippy,

It took very little time to get correct byte reads from the Si570 calling your i2c drivers; nice! I'll try writes tomorrow. Indeed the Si570's register locations match their names (at lest reg07 - reg12) using your driver. Very nice how you profile devices in Open vs. OpenRaw.

Many Thanks - David

hippy
05-23-2008, 10:23 AM
Glad it worked -- it would be even better if the PropTool supported conditional compilation and I could have one source to maintain. I do have a solution which doesn't slow everything down by having to use runtime IF statements but it then makes the code quite difficult to understand and I'm having trouble debugging it at present.

Drone
05-24-2008, 02:22 AM
Hi hippy,

Now Si570 reads and writes are working, as well as new frequency writes to the part using either OpenRaw and #0 CON enumeration with your driver. I'm using the Protoboard version driver with the pull-ups on dedicated pins for the Si570. This is probably a stupid question, but I'll throw it out anyway... If you have a driver that can handle I2C without pull-ups, why do you need to have a separate driver without pull-ups? In-practice, I've used Mike Green's driver which supports parts without pull-ups and it works if I have have pull-ups both with a 24LC256 and the Si570 (Si570 bus-scan only, and native offset 16 bit addressing with Mike's driver), using dedicated I2C pins separate from the main EEPROM.

Rgds, David

hippy
05-24-2008, 05:15 AM
The reasoning for having both is that the soft-drive for use with pull-ups is safer and supports slave device clock stretching and multi-master mode ( that's not supported in my driver ).

The hard-drive which works with or without SCL pull-up cannot support clock-stretching nor multi-master mode and is less safe for use.

This has always concerned me - Given that the Propeller hard-drives the SCL line during booting ( even with a pull-up ), if there's an I2C device on that bus which is in a fault mode it can be pulling a high SCL down and that would present a short to 0V on the SCL pin which could damage the Propeller.

It seems a strange design decision to have made despite the risk being low. The worst case is where a master driver of a user's application has set its SCL high and is waiting for the SCL line to go high with no timeout while another device is holding SCL low.