Propeller I2C Interface Questions (3.3V or 5V)
BuildAMachine
Posts: 7
Hello everyone,
I have recently got my propeller (and therefore a newbie), and plan to use it in an I2C motor controller project, specifically for an Arduino shield
I want to make the shield 3.3v or 5v compatible, and that got me wondering what to do for the I2C.
I have seen other posts relating to the Propeller's 5v tolerance, but I'm still not exactly sure what to do for an I2C interface- if I need to use bus buffers, what to do with the I2C pull-ups, components required, etc.
To cut to the chase, what would be the best method of implementing an I2C interface with the Propeller, in which the logic HIGHs could be either 3.3v or 5v (determined by the Arduino's IORef Pin)?
Thanks in Advance,
BuildAMachine
I have recently got my propeller (and therefore a newbie), and plan to use it in an I2C motor controller project, specifically for an Arduino shield
I want to make the shield 3.3v or 5v compatible, and that got me wondering what to do for the I2C.
I have seen other posts relating to the Propeller's 5v tolerance, but I'm still not exactly sure what to do for an I2C interface- if I need to use bus buffers, what to do with the I2C pull-ups, components required, etc.
To cut to the chase, what would be the best method of implementing an I2C interface with the Propeller, in which the logic HIGHs could be either 3.3v or 5v (determined by the Arduino's IORef Pin)?
Thanks in Advance,
BuildAMachine
Comments
Edit: This isn't correct. I don't know what I was thinking, sorry for any confusion.
The clever bit is you can supply chips on this bus with either 5V or 3V. Take a MCP23017 which gives you 16 inputs or outputs. Supply it with 5V and all those IO pins are 0V or 5V. Supply it with 3V3 and all the IO pins are 0V or 3V. You can even mix and match chips supplied with different voltages and put them all on the same I2C bus.
Such a high value would create a Voltage divider that would not go below 3.3V when pulled low
I think 1K would be good
Would you like to take an early peek at my I2C master code? It respects the open-drain design of I2C (it either pulls the line low or goes hi-z and lets the pull-up pull it high). You specify 100kHz or 400kHz operation. You can have sda and scl on any two unique pins. Finally, it honors I2C clock stretching which means the slave has a way to tell the master to slow down. In working with low speed ATtiny's running I2C implemented via USI, comm won't work reliably without clock stretching. Written in spin/pasm.
It would be nice to pick up some some of this code, and even a basic version of this would be would be sufficient as slave code
This seems like a very straightforward implementation, but I am wondering would the implementation of the circuit be any different for a 3.3v master?
(See image)
Would it be the same implementation if the Master is running at 3.3v core voltage?
Thanks in advance
Indeed. Technically, even the Propeller violates the I2C standard on boot-up by driving the SCL line high and low -- this is why you seem some Propeller designs with just one pull-up (on SDA).
I haven't needed high-speed I2C in any of my apps (yet) but my own Spin code is I2C compliant (active-low for 0, hi-z for 1). If you're really nervous there is a popular circuit that involves a couple pull-ups and a MOSFET. The circuit takes care of bi-directional level translation. I have used this circuit in my own projects.
-Phil
That seems like a really neat chip, and if I understood the datasheet correctly, it can both buffer as well as a level shift the I2C (if the Vcc pins are at different logic) - please correct me if I am mistaken
Is there anything special that I need to do with the "Rise time accelerator" pin - just tie it through a 10k resistor to 3.3v that the Propeller is running on?
Thanks for the suggestions (an to all previous contributors)
This has worked for me with any 5V I2C devices I've used.
Even if you pull it up to 5V you shouldn't need any other resistors as long as your pull-up resistor is 3.3K or more.
Edit: See post #15.
I don't understand why a MOSFET is needed at all? The 5V through a 10K resistor isn't going to hurt the Prop right?
I figure I must not understand something since you (Phil) and JonnyMac know a lot about this stuff than I do.
-Phil
Just another cheap aforementioned method, is it possible get away with simply pulling up the entire bus with 3.3v?
Thanks,
BuildAMachine
P.S. I looked at Adafruit's PWM servo shield, claiming that it can work with a 3.3v or 5v I2C bus, and it can, but you have to solder a jumper- a bit too cheap for me
Yes, buffers, level shifts, and makes it hot swappable...
I don't remember what I did with the rise time accelerator... I wasn't too worried about it since I was talking with Spin and not assembly speed...
But to follow the I2C spec as originated by Phillips the MOSFET circuit, also suggested by Phillips, will legitimately interface to 5V devices.
Apparently some parts really do require 5V levels and not work with just 3.3V levels.
Besides the MOSFET circuit is faster because they can accommodate lower valued pullups.
The PCA9512 is the best method as it also buffers the lines so is even faster.
BTW, the venerable 2N7000 or 2N7002 also work well in the circuit.
Duane J
Thank you both for clarifying this. MOSFETs good, got it (I think).
http://www.mouser.com/Search/Refine.aspx?Keyword=PCA9306&Ns=Pricing%7c0&FS=True
But if you really want to save space, a 0.5mm spacing with built-in 10k pull-up resistors.
http://www.mouser.com/ProductDetail/Fairchild-Semiconductor/FXMAR2102UMX/?qs=sGAEpiMZZMsty6Jaj0%252bBBpWyMwR3WqSjX0zrY8jBvBY%3d
It took me ages to work out the clever way the I2C hardware works. If it is done properly, there is no such thing as a "3.3V or 5V" bus, and then there is no need for series resistors, or more than one pullup resistor.
I'll try to explain my thinking in my muddleheaded sort of way
Most busses work on voltages. You might define a bus high as being 3V but will 5V zap the chip? Yes it may well if the chip is a SD card or another microprocessor. The I2C bus is different.
Devices on the I2C bus can only pull the voltage down to zero. They can't put any volts on the bus. This is why it does not matter what voltage any chip on the bus is supplied with. You could use a chip supplied with 12V and could put it on the bus and it would work fine - so long as it obeys the I2C rules. It is only allowed to pull the bus down to zero and never puts any volts on the line.
I like to think of the drivers for the I2C bus as being a NPN transistor. Maybe they are? Or the old school 7406 buffer with open collectors. The transistor is on or off, and if it is on then it pulls the line to zero and if it is off then the line goes to whatever the voltage is on the pullup resistor. The I2C bus allows multiple devices to pull the line down to zero and it won't do any harm if 20 chips are all pulling the line to zero at the same time.
The problems arise when the rules are bent. It is concerning to read post #5 that some obex code is putting volts on the I2C bus. Nothing should ever put volts on the bus.
For talking to another microprocessor eg the schematic in post #7 it would be very worthwhile to check the code and make sure that the disabled state is HiZ and not High.
The 'best' way is what jazzed says in post #6 - one pullup to 3V3 on each line. And you should not need any more resistors, or buffers or other pullups .
I should add that I have this working on one of my boards. An I2C bus with an eeprom running on 3V3 and two MCP23017 chips each running on 5V. It really does work just like the manual says!
re the attached image schematic post #7 where the box is labelled "Master Arduino" - is it possible to post the driver code for that? Just to make sure it is not putting any volts on the bus. If it is done right, you won't need the second 4k7 or the 1k series resistors.
I hope this all makes sense. It took me a while to figure it all out myself when I got into the I2C bus earlier this year
-Phil
(Note! The circuit should NOT connect the "source" side or gate to 5V as the gate may not reliably turn the MOSFET off when its supposed to.)
The "drain" side must operate at a voltage equal to or greater than the "source" side.
Of course, if both sides are the same voltage there is no point to using the circuit.
Actually yes.
If all the I2C devices on the bus specify they will work at 3.3V levels, even when running at higher voltages, everything should be fine. This may not always be true though, you must read the fine print in the specs.
Duane J
Using 3.3V has always worked for my needs but as Phil and Duane point on in posts #14 and 17, it can cause problems with some chips not seeing the 3.3V as a logic high.
Edit: I see both Phil and Duane had already replied.
The Arduino boards usually consist of AVR (or in the Due's case, and ARM) based microcontrollers, with "Two-wire interfaces" as they call it (use it to avoid paying royalties to use I2C) built into the hardware of the chips- the TWI is directly compatible with the I2C protocol, so I presume that they would be open-collector or open-drain outputs.
I will probably go with the PCA9512 or preferably MOSFET shifter,
It might be cutting it a bit close with the MOSFET shifter if the bus runs at 3.3V (e.g. if the Bus Master's Regulator is somehow running slightly lower than 3.3v, then I don't think that the shifter/buffer will behave as expected)
I guess from here is only testing,
The MOSFET shifter seems really elegant and cheap, but the PCA9512 seems like a safe bet
Whatever works...
Thanks for all of the input from everyone- really appreciate it
BuildAMachine
I just checked on the MCP23017 16-Bit I/O Expander.
The minimum HI input voltage to SCL and SDA:
Parameter D041 says .8 * VDD or 4V.
Yes, I know it can work but that is outside the spec.
What happens if the Prop VDD is a bit low, say 3V, and the MCP23017 is a bit high, say 5.5V.
Just saying!
Duane J
You are right, yikes!
How could one fix this? 10k pullups to 5V and assume the leakage current is low enough to be ok?
The MOSFET is turned on amply hard enough below 2.4V.
I don't have BSS123 MOSFETs to test so no data.
Duane J
One nice feature of that particular chip is that it has an output enable pin, and when that pin is low all of the signal pins become high impedance. That allows one to build a versatile bus multiplexer. Also it allows a measure of isolation, so that if the power on one I2C device is turned off either intentionally or by some accident, it is possible to isolate or failsafe that part of the I2C bus. Suppose you have several motor controllers on one I2C bus and one them happens to short circuit, or simply gets turned off. If you analyse the simple FET circuit, that one device, pulling low through its protection diodes and its pull-up resistor (now pulli-down) can lock up the entire bus and entail a number of gray hairs. Of course in core µP circuits, that is a rare occurance, but it is something to consider when dealing with an off-board bus.