i2c signalling?

New to XMOS and XCore? Get started here.
aubreyrjones
New User
Posts: 3
Joined: Mon Jan 07, 2013 9:05 pm

i2c signalling?

Post by aubreyrjones »

I'm a software guy, and I'm sure that this is EE 101 stuff...

I'm reading the i2c signalling description, and it specifies open collector pins for SCL and SDA. What electrical support is required to wire up an XMOS I/O pin as open collector? Just pull-up resistors? Or, do I need to build the open drain circuit with a transistor?

It also appears that there're a couple points in the protocol where a pin needs to be undriven so that it can detect slave clock stretching or whatever.

How can I 'unassert' or 'undrive' a pin in XC? The spec says that the pin is driven with the last output until a new output is given. Does it float if I tell it to input, like "i2c.scl :> void"? Reading the i2c softIP module, it looks like it does. I'm just confirming that.


User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

aubreyrjones wrote:I'm reading the i2c signalling description, and it specifies open collector pins for SCL and SDA. What electrical support is required to wire up an XMOS I/O pin as open collector? Just pull-up resistors?
Just never drive the output high, let the resistor pullup handle that. This is
important if something else on the bus drives low at the same time.
It also appears that there're a couple points in the protocol where a pin needs to be undriven so that it can detect slave clock stretching or whatever.
Also whenever the slave is talking to you (including the ACK when you are
writing), and for all logically high bits (as above).
How can I 'unassert' or 'undrive' a pin in XC? The spec says that the pin is driven with the last output until a new output is given. Does it float if I tell it to input, like "i2c.scl :> void"?
Yes, that is the simplest way to make it float.

Good luck, have fun, and I hope for you you don't really have to do
clock stretching :-)
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

Post by babazaroni »

The above discussion is about SDA and SCL being on single bit ports.

What happens when they are on the same port, like a 4bit port, on a U series part?

Can one bit be driving while the other bit is not driving and in open-collector mode?
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

babazaroni wrote:The above discussion is about SDA and SCL being on single bit ports.

What happens when they are on the same port, like a 4bit port, on a U series part?

Can one bit be driving while the other bit is not driving and in open-collector mode?
Although I have never done this, from memory, I think Xmos used a single port implementation to configure a codec (write registers only) the limitation was no detection of ACK.

regards
Al
Hagrid
Active Member
Posts: 44
Joined: Mon Jul 29, 2013 4:33 am

Post by Hagrid »

Doing i2c from a single multipin port would be problematic. As the state of the pin is controlled by the direction (logic high is input state, logic low is output low state) you would be unable to have different states on different pins on the same port as all pins on the port have to be the same direction.

Any bits being read from the slave device would involve generating a clock cycle while monitoring the data line as input.

So clock and data need to be on different ports. But these ports themselves don't need to be single pins as long as the other pins on the ports can follow the required direction changes.
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

You cannot do open drain with a multi-bit port, not without
some external circuitry. You can fake it though (drive low
for low, switch to input for "high").
User avatar
Ross
XCore Expert
Posts: 966
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

XMOS has an implementation of i2c on a shared port. On pre-xCORE-200 it has the limitation of write access only. xCORE-200 has no such restriction. Its implemented as Segher suggests. All the code is on github.
User avatar
davelacey
Experienced Member
Posts: 104
Joined: Fri Dec 11, 2009 8:29 pm

Post by davelacey »

Just to be clear. On the xCORE-200 for a multi-bit port implementation you do not do an input to stop driving. The port can be configured in to "drive low" mode (see set_port_drive_low() is xs1.h) which means that when the port outputs a 0 on a pin it drives and when it outputs a 1 is will stop driving. For example, doing:

Code: Select all

p <: 0b01
will drive low on bit 1 and stop driving on bit 0. This allows you to implement the correct behaviour for I2C, in addition you can use the peek() function in xs1.h to see the actual value sampled on the port e.g.

Code: Select all

p <: 0b01   // drive bit 1 low, do not drive on bit 1
x = peek(p);  // this will either be 0b00 or 0b01 depending on whether there is a external drive
                    // down on the pin connected to bit 0
This lets you check for ACKs, implement clock stretching etc.

The library on xmos.com (http://www.xmos.com/support/libraries/lib_i2c) has clock stretching support.

Dave
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Thanks Dave very useful information, that new feature for the xCORE-200 might just prove rather handy for something I am working on.
User avatar
Ross
XCore Expert
Posts: 966
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Sorry I just re-read my post and realised it wasn't very clear at all regarding xCORE-200!