View Full Version : How dose I2c work?
07-09-2009, 09:50 AM
OK so I have been learning about I2c communication and there are a few things I am unsure about how this works with the propeller. I understand the timing aspects of it, how you have a clock and a data line and by raising and lowering the line voltage you can send a start command, an address that includes a read or write bit, and then the stop condition. What I am unsure of is do I need a pull-up resistor? I think I might prefer this because it is standard. Also the start command says to bring SDA high while SCL is set low, but the biggest thing I am unsure about is how do you set the line high and low if you are using a pull-up resistor? Would I set the direction register in or out and then would I set it to one or zero? It is the simple things that I am getting stuck on, but any help would be appreciated. I have looked at the I2c driver but I am unsure if it is written to be used with a pull up resistor or not. Also I would prefer not to use the existing i2c driver because I want to write a version of my own for a specific application. And thanks for the patience with my basic questions.
07-09-2009, 10:00 AM
Honestly, I don't get it either... I just look at a schematic and make it happen...
What sort of specific application do you have in mind?
Quit buying all those fixed voltage regulators, and·get an Adjustable Power Supply (http://www.gadgetgangster.com/130)·for your projects!· Includes an LED testing terminal!
07-09-2009, 10:06 AM
if its written assuming a pull-up resistor for sda then it sets outa[sda] := 0 and dira[sda] := 1 for sda low and dira[sda] := 0 for sda high, similar for scl.
If it doesn't assume a pull-up then outa[sda] :=0, dira[sda]:=1 for low and outa[sda]:=1,dira[sda]:=1 for high.
07-09-2009, 10:07 AM
If there is only one bus master (like the Propeller), you can get away with only a pull up on SDA because only the master produces a clock and the Propeller can drive the clock both high and low.
If you look at any of the existing I2C drivers, you'll see that the SDA pin output register bit is set to 0 (low) and the direction register bit is switched from 0 (input mode) to allow the pull up to produce a high (1) to 1 (output mode) to allow the output driver to pull the line down (low).
The Basic_I2C_Driver in the Object Exchange is really simple and should serve as an example of how to do I2C using Spin.
07-09-2009, 10:09 AM
and the slave doesn't do clock stretching, if the slave does then it also drives the scl line and you need a pull-up
07-09-2009, 10:27 AM
Yes, the propeller will be the only master, and for now it is likely that the slave chip will be the only one on the line. The application is for a startup procedure for an STA013 MP# decoder chip. It’s a nice little chip that will decode mp3 data and output it to an ADC to produce sound. I have an SD memory card that scans all files and gets all of the .MP3 files and will list them on a screen, and then you can select up and down to select an mp3 file. When you hit play, it is going to start sending data to the mp3 chip. The problem is that I have no experience in I2C (yet), and you need to load in startup parameters before the chip will function, and you have to do it through I2C. After that you can send the data in as serial through other lines, but the I2c can be used to make audio adjustments while the serial lines are busy receiving data to be decoded, you don’t want to hold that up so the SCL and SDA lines can be used to access registers and settings for volume, treble, balance and other settings on the fly. And Thank you Mike Green for the suggestions on driving the SCL line without the pull-up, I might give that a try to simplify that part of it. And I will make sure to use the pull-up on SDA. I don’t believe the MP3 chip will do clock stretching, but to keep things as close to the standard specifications, I will use a pull-up on the data line. I will need to look closer at what is happening here. The whole thing can be a little confusing when you are unsure if your hardware is setup right. I think now there is going to be a lot I need to change in my program. I was originally trying to drive both lines with the prop without a pull up resistor. I don’t think that was working out so well.
07-09-2009, 10:36 AM
The Propeller Protoboard has pullups on both pins and I suggest you build that into your device as well. Parallax's choice to leave out the clock pullup is partly to save power and partly to save cost and board space. NXP (who used to be Philips - the inventor of I2C) has all kinds of application notes on how to choose pullups for I2C and they say that you have to have both.
I can't recommend strongly enough that you use a working I2C driver as your model. There are several in the Object Exchange. Unless you are quite expert, it will save you much grief. Once you get your system basically working, you can always rewrite it from scratch with your own driver to do exactly what you want.
07-09-2009, 08:46 PM
Mike, I understand what you are saying, dont jump into a task like that until·I can proof out my part of the program, and get the process down. I agree that if·I can not get the I2C·driver from parallax running then I really shouldnt jump into making my own. The part that I am having trouble with is knowing how to setup the driver to run with my specific device. It is a standard, so it should work fine, but I could not seem to get the device to respond properly. The best example·I have of how to get the I2C driver running is the basic I2C module that has demo applications on how to read and write to an EEPROM. It seems to be specifically made for that type of device and I couldn't determine if the driver assumed a pullup resistor was present on the lines or not. The standard I2C driver looks a lot closer to what I need but i still can not find a good example on how to implement it. I tried to get it running by using the Init and start, but can not seem to get it to recieve ACK for bytes sent. I will really rip into it more today to try to get it going. I think part of the problem is with how·I had the SCL and SDA lines setup on Tuesday.
07-09-2009, 08:53 PM
Have a look at "i2cObjectv2" from the Object Exchange. It's based on "Basic_I2C_Driver", but there are specific drivers for a variety of I2C devices, not just EEPROMs. One of these may be similar to what you're trying to use.
If you read the comments in "Basic_I2C_Driver", you'll see that it's intended to work whether or not the pullup is present on SCL.
07-09-2009, 09:41 PM
The thing with "true" I2C is that anything that hooks-up to SDA or SCL are open-drain devices and thus cannot drive the line high. If the line is not being driven low then it will be pulled-up via the resistor. For all practical purposes you can treat the I2C bus as a single clock from the master plus a bi-directional data line which ideally should never be driven high but often is. Follow Mike's suggestions though and use 2 resistors if you can spare a cent. Some people use series current limit resistors (don't worry about this for now) which is ok too I guess but I have never seen any I2C bus damaged from a malfunctioning I2C driver.
Remember though that I2C only transports your data to and from the I2C chip, it's up to you to read the chip's datasheet properly to determine what you need to read/write and how. It's not black magic so just be methodical about it and first determine that the chip is responding and build it up from there.