I2C internal register address

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

I2C internal register address

Postby hippicurean » Mon Feb 27, 2012 1:18 pm

Hi there,

I don't work with leJOS directly, but I'm using a software platform (nxtOSEK) that borrows drivers from leJOS - albeit rather antiquated ones. I've looked at the recent code of "i2c.c" and some changes have left me a little baffled. Previous versions had the function i2c_start_transaction(int port, U32 address, int internal_address, int n_internal_address_bytes, U8 *data, U32 nbytes, int write) which was later changed to i2c_start(int port, U32 address...int write). But in recent versions, the function has been modified to i2c_start(int port, U32 address, U8 *write_data, int write_len, int read_len). What happened to the internal register address?

As I understand, to access data from a typical NXT sensor, the starting address of the internal register has to be specified, followed by the number of address bytes that will indicate the required number of increments of the address. So, how does the new I2C implementation achieve this? I keep reading about queries regarding Standard Mode vs Lego Mode. Is it related to my question?

Cheers
Hippie
hippicurean
New User
 
Posts: 10
Joined: Wed Aug 31, 2011 9:40 am

Re: I2C internal register address

Postby skoehler » Mon Feb 27, 2012 2:37 pm

The internal register number has been moved to the byte array. It's really just the first byte that is transmitted after the actual I2C adress. And I wanted our interface to reflect that. Also, people had serious trouble understanding that the internal register number was simply the first byte - especially if the sensor's I2C protocol wasn't organized by "internal registers".
skoehler
leJOS Team Member
 
Posts: 1418
Joined: Thu Oct 30, 2008 4:54 pm

Re: I2C internal register address

Postby hippicurean » Tue Feb 28, 2012 2:14 am

Thanks for the reply, skoehler. You mentioned that the "internal register number has been moved to the byte array." Would you mind explaining to a novice what that means? Also, you said that the internal register address is only the first byte. This brings to mind something that has confused me for awhile. I'm able to read from the HiTechnic Compass Sensor using a combination of Matlab, Simulink and nxtOSEK. The sensor's internal registers 0x44 and 0x45 are where the data is being read. During my learning process, I've programmed a microcontroller to respond to the same device ID and internal registers as the compass sensor. I discovered to my surprise that the microcontroller only detects the first register address being sent by the NXT master. Till now, I still can't understand how it's able to read data from the second register of the compass sensor.
http://www.hitechnic.com/cgi-bin/commer ... ey=NMC1034

So, what modifications would I have to make in order to port the new drivers to a system which is still sending arguments for the internal register and the number of register bytes? Thanks.

Cheers
Hippie
hippicurean
New User
 
Posts: 10
Joined: Wed Aug 31, 2011 9:40 am

Re: I2C internal register address

Postby skoehler » Tue Feb 28, 2012 9:22 am

hippicurean wrote:Thanks for the reply, skoehler. You mentioned that the "internal register number has been moved to the byte array." Would you mind explaining to a novice what that means?


You see the write_data parameter? The first byte of the array that the write_data pointer points to is now the internal register address. What used to be the first byte is now the second byte etc.

hippicurean wrote:Also, you said that the internal register address is only the first byte. This brings to mind something that has confused me for awhile. I'm able to read from the HiTechnic Compass Sensor using a combination of Matlab, Simulink and nxtOSEK. The sensor's internal registers 0x44 and 0x45 are where the data is being read. During my learning process, I've programmed a microcontroller to respond to the same device ID and internal registers as the compass sensor. I discovered to my surprise that the microcontroller only detects the first register address being sent by the NXT master.


First of all, the NXT only sends one register number (0x45). The I2C sensor must automatically append the value of 0x46 if the NXT master reads two bytes and not one. There's a certain name for that I2C behaviour (multi register read or something like it). It is not possible to read multiple non-adjacent registers at the same time.
skoehler
leJOS Team Member
 
Posts: 1418
Joined: Thu Oct 30, 2008 4:54 pm

Re: I2C internal register address

Postby hippicurean » Wed Feb 29, 2012 4:24 am

skoehler wrote:The first byte of the array that the write_data pointer points to is now the internal register address. What used to be the first byte is now the second byte etc.

Righto. nxtOSEK uses the old " i2c_start()/i2c_start_transaction()" interface. Let's see if I understand this enough to modify the old functions into a new layer to work with the latest "i2c_start()". If I'm only reading two bytes off a sensor and have no need to send any configuration bytes, I can copy the value of the old "internal_address" argument to the first byte of the "*write_data" array, and the old "nbytes" will now be "read_len" (in this case: 2) or "write_len" (in this case: 0). Is that correct? Now it starts to get rather confusing. The code is a bit too complex and has too few comments for novice like me to comprehend. Is "*write_data" also used as a data buffer for a READ command? If so, does the data from the slave slot into the second array position or overwrite everything in it? If not, where is the read data buffer?

skoehler wrote:First of all, the NXT only sends one register number (0x45). The I2C sensor must automatically append the value of 0x46 if the NXT master reads two bytes and not one.

I had always thought that it was the master device that does the automatic increment of the register address. How else would the slave know if the master wanted to access the next sequential register address?

Thanks for taking the time to help. It's much appreciated.

Cheers
Hippie
hippicurean
New User
 
Posts: 10
Joined: Wed Aug 31, 2011 9:40 am

Re: I2C internal register address

Postby gloomyandy » Wed Feb 29, 2012 9:28 am

The auto increment feature is not part of i2c it is purely up to the slave device how to interpret the data sent to it.So for instance if you want to build a device that takes a "register address" of say 27 and a read length of say 5 and returns bytes from memory locations in the slave of 2 4 6 7 9 then that is fine, you may also choose if the register address of 28 to return bytes from addresses 3, 4, 5, 6, 7. This would not be a very consistent device but there is nothing to stop you doing it. Generally most devices designed for the NXT support auto increment and if you read 3 bytes from address 40 you will get the same results as reading one byte from 40, one from 41 and one from 42 (assuming the data does not change between the reads), however not all devices support this, on some devices you have to issue multiple reads to read multiple bytes... Usually the datasheet of the device will give the details of all of this...

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4042
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: I2C internal register address

Postby skoehler » Wed Feb 29, 2012 12:38 pm

hippicurean wrote:
skoehler wrote:First of all, the NXT only sends one register number (0x45). The I2C sensor must automatically append the value of 0x46 if the NXT master reads two bytes and not one.

I had always thought that it was the master device that does the automatic increment of the register address. How else would the slave know if the master wanted to access the next sequential register address?


The slave receives two I2C bytes: its I2c address and the internal register number (e.g. 0x45). Then the slave starts sending the byte which belong to 0x45 and the slave then continues to send as long as the master lets him do it. Because the master is in charge how many bytes the slave is allowed to send. The slave simply sends as long as it is permitted to. However, devices without the auto-increment feature will not show this behaviour.
skoehler
leJOS Team Member
 
Posts: 1418
Joined: Thu Oct 30, 2008 4:54 pm

Re: I2C internal register address

Postby hippicurean » Wed Feb 29, 2012 12:51 pm

Thanks for clearing up my misunderstanding about the auto-increment feature, Andy and skoehler. Now, could any of you (or anyone else) help me with modifying the old "i2c_start()/i2c_start_transaction()" code to interface with the new "i2c_start()"? I asked a few questions previously regarding this issue but no one has yet answered them.

Cheers
Hippie
hippicurean
New User
 
Posts: 10
Joined: Wed Aug 31, 2011 9:40 am

Re: I2C internal register address

Postby skoehler » Thu Mar 01, 2012 2:12 pm

hippicurean wrote:Thanks for clearing up my misunderstanding about the auto-increment feature, Andy and skoehler. Now, could any of you (or anyone else) help me with modifying the old "i2c_start()/i2c_start_transaction()" code to interface with the new "i2c_start()"? I asked a few questions previously regarding this issue but no one has yet answered them.


I have no clue about nxtOSEK. I'm not sure if anybody here has. Why don't you contact the nxtOSEK developers? Also, the task you're up to sounds like it is something fairly simple, that any C-programmer should be capable of.
skoehler
leJOS Team Member
 
Posts: 1418
Joined: Thu Oct 30, 2008 4:54 pm

Re: I2C internal register address

Postby hippicurean » Fri Mar 02, 2012 8:49 am

skoehler wrote:Why don't you contact the nxtOSEK developers?

There is only one person listed as the developer on the project's SourceForge site. I tried contacting him on and off for many months before he finally replied to say that he's too busy to tweak nxtOSEK to utilise the latest leJOS drivers. So, that leaves me with hardly any other option. I know what the seven function arguments in the old system are for. But in the new function, there are now five arguments. I need to write a new function to act as a translation layer. However, there aren't enough comments for me to understand how everything works in "i2c.c" and so I have trouble writing the necessary code. I can only follow the code partially.

You mentioned previously that the old "internal_address" argument is now sent to the first byte of the "*write_data" array. Is "*write_data" also used as the read buffer? Is "write_len" equal "0" in read mode, or is it equal to "1" because it still has to write that first register address to the slave? And I suppose the old "n_internal_address_bytes" is redundant. If someone could answer these simple questions, it'll go a long way to help me improve my understanding of how "i2c.c" works. Thanks.

Cheers
Hippie
hippicurean
New User
 
Posts: 10
Joined: Wed Aug 31, 2011 9:40 am

Re: I2C internal register address

Postby gloomyandy » Wed Mar 14, 2012 11:42 am

The obvious way to do this is to look at the leJOS Java code that used the old function and the new function, that should provide enough information to allow you to write a translation layer.

Sven has already provided pretty much all of the information there is. Basically the values that used to be be provided as the internal_address (and the corresponding n_internal_address_bytes) now need to be sent as part of the write data. Just work your way through things from there. If there are address bytes (determined by the value of n_internal_address_bytes) to write put them in the write buffer, then add any data that is in your "old" write buffer, the new write length is the total of these two lengths. The read len is exactly what it says the number of bytes you want to read from the device.

To be honest I think you would be better off changing the code that calls these functions to do things the new way rather than writing a translation function. The new interface is actually much easier to understand (assuming you understand how i2c actually works)...
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4042
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK


Return to NXJ Software

Who is online

Users browsing this forum: Yahoo [Bot] and 2 guests

more stuff