CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

i2c read specific data address
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 16, 2019 12:11 am     Reply with quote

webgiorgio wrote:
However the burst reading isn't working. On the reads after the first one I
get again the value of the first read. It looks like the inclinometer isn't
incrementing the pointer to the next register.

i2c_start(); //start
i2c_write(incl_address); //send device address
i2c_write(0x28); //send address of the register I want to read
i2c_start(); //restart
i2c_write(incl_address+1); //send device read address (device address+1)
ACC_Data0 = i2c_read(); //Read register 28 and ACK
ACC_Data1 = i2c_read(0); //Read register 29 and NACK
i2c_stop(); //stop



The LSM303 data sheet says on page 21, in section 5.1.2:
Quote:

In order to read multiple bytes, it is necessary to assert the most
significant bit of the subaddress field
. In other words, SUB(7) must
be equal to 1 while SUB(6-0) represents the address of the first
register to be read.

This means instead of sending 0x28 you should send 0xA8.
Use:
Code:

i2c_write(0xA8);

or
Code:

i2c_write(0x28 | 0x80);
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Sat Nov 16, 2019 2:00 am     Reply with quote

Must admit I can't see this in the data sheet I have, but it makes sense!...

However as a 'comment', don't add one to get the read address. It is much
more 'intuitive', and 'readable', to use a syntax like:

Code:

#define READ (1) //bottom bit to specify a read transaction follows

//Then

I2c_write(incl_address | READ); //send device read address


It avoids thinking about incrementing addresses, instead you set the READ
bit in the address byte.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 16, 2019 2:15 am     Reply with quote

I was looking at a newer data sheet. In the data sheet that he links to
in his first post, it's on page 38. It's the 3rd paragraph in this section:
6.1.1 I2C operation
Quote:

The I2C embedded inside the LSM303AGR behaves like a slave device
and the following protocol must be adhered to. After the start condition
(ST) a slave address is sent, once a slave acknowledge (SAK) has been
returned, an 8-bit sub-address (SUB) is transmitted: the 7 LSb represent
the actual register address while the MSB enables address auto increment.
If the MSb of the SUB field is ‘1’, the SUB (register address) is
automatically increased to allow multiple data read/writes.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Sat Nov 16, 2019 2:23 am     Reply with quote

That is interesting. I pulled the sheet from the same link when the thread started. No section 6.1.1. Just pulled it again, and the new sheet has this!...
Aaargh.
How to really annoy anyone trying to use the chip.
Old sheet was Rev9, new sheet Rev10.
Makes total 'sense', quite a few chips have a bit that has to be set to
enable multi byte transfers.
With this, I'd use:
Code:


#define READ (1) //bottom bit to specify a read transaction follows
#define MBYTE (0x80)

//Then

I2c_write(incl_address | READ | MBYTE); //send device read address
//for multi-byte read


I just think it makes it clearer what is being done, and since defined
values are evaluated at compile time, costs nothing. Smile

As one other minor comment, change incl_address to INCL_ADDRESS.
There is a 'semi standard' in C to reserve 'ALL CAPITALS', for things
that are #defined. It is useful, since these do behave differently from
things like variables and it helps to 'remind' later that these are #DEFINED
values. Helps avoid silly errors.
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Sat Nov 16, 2019 3:13 am     Reply with quote

I was reading again and again the chapter 6.1.1 (i2c operation) but I could not understand by myself.
You guys have a lot of experience!

It all works now Very Happy Thanks!

Code:

#define READ (1) //0000 0001
#define MULTIBYTE (0x80) //1000 0000

void read_inclinometer_burstMode(){
      i2c_start();                 //start
      i2c_write(INCL_ADDRESS);     //send device address
      i2c_write(0x28 | MULTIBYTE); //send address of the register I want to read (with bit7 (MSB) equal 1 to enable mutibyte read)
      i2c_start();                 //restart
      i2c_write(INCL_ADDRESS | READ); //send device read address (device address+1)
      ACC_Data0 = i2c_read();    //Read register 28 and ACK
      ACC_Data1 = i2c_read();    //Read register 29 and ACK
      ACC_Data2 = i2c_read();    //Read register 2A and ACK
      ACC_Data3 = i2c_read();    //Read register 2B and ACK
      ACC_Data4 = i2c_read();    //Read register 2C and ACK
      ACC_Data5 = i2c_read(0);   //Read register 2D and NACK
      i2c_stop();
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group