Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
6 years ago.
I2C specific sequence
Hi,
I have an KX224 accelerometer and I want to read its buffer using I2C. There is a "Sequence 4" in datasheet (http://kionixfs.kionix.com/en/datasheet/KX224-1053-Specifications-Rev-2.0.pdf - page 21) which is supposed to replicate in order to read the buffer, but I don't know how to do it. The buffer contains accelerometer data. In order to read it, you have to read one register with one byte. Because the buffer actually contains 2048 bytes, you have to send ACK after each reading to update the next value from the FIFO into the same register.
I tried using: i2c.write((int)((KX224_DEVICE_ADDRESS_1E << 1) | I2C_WRITE), ®, 1, true); int c = i2c.read((int)((KX224_DEVICE_ADDRESS_1E << 1) | I2C_READ), &out, 1, true);
Using a logic analyzer, I get this from the above code:
Can someone help me?
Thanks, Gabriel
1 Answer
6 years ago.
You first need to set the register from which to read and then read a byte from that register. Normally, multiple sequential read operations would automatically increment the selected register address and thus read from the next sequential register. However, the specific register address for ''sequence 4'' is linked to an internal fifo and every subsequent read operation does not access the next register, but instead sends the next value in the fifo. The problem with your code is that you read only one byte from the fifo, the master does not send an acknowledge since it is the last byte, and it does not send a Stop because you set the 'repeated start' parameter to 'true'.
Try this:
//reg = address of fifo //set the register address, select repeated start for the follow-on read i2c.write((int)((KX224_DEVICE_ADDRESS_1E << 1) | I2C_WRITE), ®, 1, true); //now read multiple bytes from the fifo register (10 in this case), make sure there is enough room in the buffer ''out'' for all 10 //dont use repeated start char out[16]; int c = i2c.read((int)((KX224_DEVICE_ADDRESS_1E << 1) | I2C_READ), &out, 10); //buffer out[0..9] now holds the 10 bytes from the fifo register
BTW you dont need to set the read/write bit in the slaveaddress. That is handled by the i2C lib. Just use:
... i2c.write ((KX224_DEVICE_ADDRESS_1E << 1), ®, 1, true); .. int c = i2c.read ((KX224_DEVICE_ADDRESS_1E << 1), &out, 10);
Thank for your answer! It looks like it's working. I am still having issues about the values that I am getting, but it looks like the I2C sequence is good.
posted by 29 Oct 2018Hi again,
Do you have any idea how should I do the sequence 6? I want to test it in high speed mode as well.
Thanks, Gabriel
posted by 31 Oct 2018The default clockspeed for I2C is 100000 bits/s. You should be able to increase that to 400000 for normal (fastmode) I2C ports. Try
i2c.frequency(400000);
Note that not all mbed platforms support the same speeds. Use the scope to verify.
The highspeed mode is again not available on all mbed platforms and may depend on the specific I2C pins (ie I2C hardware engine) that you select. You need to check the documentation and perhaps even the mbed lib implementation code.
If it does work, you might be able to tweak the i2c calls to make the slave play at the highspeed mode. Something like this:
char reg = 0x08; // magic byte 00001xxx char out[16]; //buffer //send magic byte, and dummy byte, select repeated start for the follow-on read //use repeated start i2c.write (reg, out, 0, true); //set the new freq (note: might be too high or not work...) i2c.frequency (3000000); //now prepare to read from the fifo register //use repeated start reg = fifo read address; // set the fifo address int c = i2c.write( (int)(KX224_DEVICE_ADDRESS_1E << 1), ®, 1, true); //now read multiple bytes from the fifo register (10 in this case), make sure there is enough room in the buffer ''out'' for all 10 //dont use repeated start int c = i2c.read( (int)(KX224_DEVICE_ADDRESS_1E << 1), out, 10); //restore the freq i2c.frequency (100000);
Wim, I will try your code for I2C high speed. Indeed, my MCU does not support HS, but I will give it a try. I am trying not the way around with SPI to compare the speeds. I will post a question for that as well :). Thanks for your help!
posted by Gabriel Arnautu 05 Nov 2018