Why doesn't the NXT support high speed I2C?

Discussion specific to the intelligent brick, sensors, motors, and more.
aswin0
Posts: 201
Joined: 29 Sep 2010, 06:58

Why doesn't the NXT support high speed I2C?

Post by aswin0 »

Why doesn't the NXT support high speed I2C? The onboard chips do support this according to the data sheet.
My blog: nxttime.wordpress.com
gloomyandy
Posts: 323
Joined: 29 Sep 2010, 05:03

Re: Why doesn't the NXT support high speed I2C?

Post by gloomyandy »

The nxt does support high speed i2c but it is used to talk to some of the internal devices (I seem to remember it is used to talk to the ATMega). There is only a single i2c hardware device on the Arm chip. I guess they could have used it as a bus device, but that is not really compatible with the sensor port design that they have used. So I guess that Lego decided to go with a software implementation. Given that the only Lego sensor to use i2c (the ultrasonic sensor), struggles to keep up with the 9600 baud software i2c I guess that they saw no reason to do any better...

You can make the software implementation run faster (as done by RobotC), but this can end up using a lot of cpu cycles. I measured the cpu usage for the leJOS firmware (which at the time used a similar implementation to that used in the Lego firmware), and just driving a single port used approx 25% of the cpu (Since then we've reduced that considerably)... This was mainly from the timer based interrupt handler which generates approx 20,000 interrupts a second to drive the i2c code...
aswin0
Posts: 201
Joined: 29 Sep 2010, 06:58

Re: Why doesn't the NXT support high speed I2C?

Post by aswin0 »

Ok, I understand. Thanks
My blog: nxttime.wordpress.com
philoo
Posts: 76
Joined: 29 Sep 2010, 09:04
Location: Paris, France
Contact:

Re: Why doesn't the NXT support high speed I2C?

Post by philoo »

Another point to consider is hardware limitations: the NXT is very well protected by (relatively) high value resistors (4.7k) but coupled with cable capacitance, this severely reduces possible bit rate.
Philo
gloomyandy
Posts: 323
Joined: 29 Sep 2010, 05:03

Re: Why doesn't the NXT support high speed I2C?

Post by gloomyandy »

Hi,
So I've been tweaking the i2c code in the leJOS firmware. With that I can run reliably at 125KHz (as opposed to the standard 9.6KHz). This seems to work with all of the non Lego i2c devices I have (half a dozen or so in all). I can even combine most of them on a single bus (using a port splitter). Any faster than this though and things seem to fall apart...


Andy
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: Why doesn't the NXT support high speed I2C?

Post by mattallen37 »

gloomyandy wrote:Hi,
So I've been tweaking the i2c code in the leJOS firmware. With that I can run reliably at 125KHz (as opposed to the standard 9.6KHz). This seems to work with all of the non Lego i2c devices I have (half a dozen or so in all). I can even combine most of them on a single bus (using a port splitter). Any faster than this though and things seem to fall apart...


Andy
Wow, perhaps john should think about adding higher speeds to the enhanced FW, as an option. I know that a lot of the higher speed stuff I do (for visual displays and such) would look a lot better if I had higher I2C speeds. Even "just" 10x would be really cool.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
aswin0
Posts: 201
Joined: 29 Sep 2010, 06:58

Re: Why doesn't the NXT support high speed I2C?

Post by aswin0 »

philoo wrote:Another point to consider is hardware limitations: the NXT is very well protected by (relatively) high value resistors (4.7k) but coupled with cable capacitance, this severely reduces possible bit rate.
Well, I soldered over these resistors at one port. ;)
I use robotC and this support baud rates of 30K but I could use some extra bandwidth as I have a 3-axis accelerometer and a 3-axis gyro on the same port. One read out of both sensors takes two requests of 1 bytes and two replies of 6 bytes (not counting I2C overhead).
My blog: nxttime.wordpress.com
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: Why doesn't the NXT support high speed I2C?

Post by afanofosc »

gloomyandy wrote: So I've been tweaking the i2c code in the leJOS firmware. With that I can run reliably at 125KHz (as opposed to the standard 9.6KHz). This seems to work with all of the non Lego i2c devices I have (half a dozen or so in all). I can even combine most of them on a single bus (using a port splitter). Any faster than this though and things seem to fall apart...
Andy, could you point me to your tweaked code and/or send me a copy? I am definitely interested in adding faster I2C support to the enhanced NBC/NXC firmware.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
gloomyandy
Posts: 323
Joined: 29 Sep 2010, 05:03

Re: Why doesn't the NXT support high speed I2C?

Post by gloomyandy »

Hi John,
I've just checked the code in and you can see it here...
http://lejos.svn.sourceforge.net/viewvc ... iew=markup
It is a pretty small change, but it does depend very heavily on the existing leJOS i2c mechanism which is basically a state machine driven by a timer interrupt. For the high speed case I basically just call the state machine directly using a busy wait loop using one of the hardware timers to provide the short timing interval required. I'm not sure how will this would translate over to the standard firmware. You really don't get to run much code with a cycle time that is this short!

One other thing I found I had to add support for clock stretching when operating at this speed. It looks like the processor used in some of the mindsensors devices (and possibly others), need this.

Andy
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: Why doesn't the NXT support high speed I2C?

Post by afanofosc »

With Andy's help I have added support to the enhanced NBC/NXC firmware for a fast I2C mode. It is not yet nicely integrated into the NXC API functions but you can call it as shown in the i2c test code below:

Code: Select all

#define FAST 1

#ifdef FAST

#define I2C_MODE_FAST      0x08
#define I2C_MODE_NORESTART 0x04

#else

#define I2C_MODE_FAST      0x00

#endif

#define I2CWriteTest(_port, _cnt, _buf) \
asm { \
	set __CLSWArgs##_port.Port, _port|I2C_MODE_FAST \
	mov __CLSWArgs##_port.ReturnLen, _cnt \
	mov __CLSWArgs##_port.Buffer, _buf \
	syscall 21, __CLSWArgs##_port \
}

task tS1()
{
  SetSensorLowspeed(S1);
  byte msg[] = {0x10, 0x42}; // sensor on S1 has address 0x10
  byte reply[6];
  byte count;
  float time;
  unsigned long T1;
  while(true)
  {
    count = 2;
    T1 = CurrentTick();
    while (I2CCheckStatus(S1) != NO_ERR) Wait(0);
    I2CWriteTest(S1, count, msg);
    while (I2CBytesReady(S1) == 0) Wait(0);
    I2CRead(S1, count, reply);
    time = 499.0/500.0*time + (CurrentTick()-T1) / 500.0;
    TextOut(0, LCD_LINE1, FormatNum("%3.2f" , time));
  }
}

task tS3()
{
  SetSensorLowspeed(S3);
  byte msg[] = {0x02, 0x42};
  byte reply[6];
  byte count;
  float time;
  unsigned long T3;
  while(true)
  {
    count = 2;
    T3 = CurrentTick();
    while (I2CCheckStatus(S3) != NO_ERR) Wait(0);
    I2CWriteTest(S3, count, msg);
    while (I2CBytesReady(S3) == 0) Wait(0);
    I2CRead(S3, count, reply);
    time = 499.0/500.0*time + (CurrentTick()-T3) / 500.0;
    TextOut(0, LCD_LINE3, FormatNum("%3.2f" , time));
  }
}

task both()
{
  SetSensorLowspeed(S1);
  SetSensorLowspeed(S3);
  byte msg1[] = {0x10, 0x42};
  byte msg2[] = {0x02, 0x42};
  byte reply[6];
  byte count;
  float time;
  unsigned long T1;
  while(true)
  {
    count = 2;
    T1 = CurrentTick();
    while (I2CCheckStatus(S1) != NO_ERR) Wait(0);
    I2CWriteTest(S1, count, msg1);
    while (I2CBytesReady(S1) == 0) Wait(0);
    I2CRead(S1, count, reply);
    while (I2CCheckStatus(S3) != NO_ERR) Wait(0);
    I2CWriteTest(S3, count, msg2);
    while (I2CBytesReady(S3) == 0) Wait(0);
    I2CRead(S3, count, reply);
    time = 499.0/500.0*time + (CurrentTick()-T1) / 500.0;
    TextOut(0, LCD_LINE1, FormatNum("%3.2f" , time));
  }
}

task main()
{
//  Precedes(tS1);
  Precedes(tS3);
//  Precedes(tS1, tS3);
//  Precedes(both);
/*
  SetSensorLowspeed(S1);
  SetSensorLowspeed(S3);

  while (true)
  {
    TextOut(0, LCD_LINE1, I2CVendorId(S1, I2C_ADDR_DEFAULT));
    TextOut(0, LCD_LINE2, I2CVendorId(S3, I2C_ADDR_DEFAULT));
    Wait(SEC_1);
  }
*/
}
You can do that, I should say, once I make the latest build of the enhanced NBC/NXC firmware available publicly. If you are eager to help me test the firmware changes with your I2C devices please send me an email using the address in the BricxCC about box.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests