Hello, how would a baremetal code of reading two bytes with I2c from a sensor look like.
The following code ist from twr-kl25Demo and reads one byte. How i could read the 2. byte. The Sensor just excect an Acknowledge after the first byte, but how to integrade that in the code below. I Also dont understand why theres
i2c_give_nack(I2C0_B); after
i2c_get_ack(I2C0_B);
i2c_set_rx_mode(I2C0_B);
and why there is a reading after i2c_stop. Could someone Comment this pls. Thanks a lot
uint8 result;
i2c_start(I2C0_B);
i2c_write_byte(I2C0_B, MMA8451_I2C_ADDRESS | I2C_WRITE);
i2c_wait(I2C0_B);
i2c_get_ack(I2C0_B);
i2c_write_byte(I2C0_B, addr);
i2c_wait(I2C0_B);
i2c_get_ack(I2C0_B);
i2c_repeated_start(I2C0_B);
i2c_write_byte(I2C0_B, MMA8451_I2C_ADDRESS | I2C_READ);
i2c_wait(I2C0_B);
i2c_get_ack(I2C0_B);
i2c_set_rx_mode(I2C0_B);
i2c_give_nack(I2C0_B);
result = i2c_read_byte(I2C0_B);
i2c_wait(I2C0_B);
i2c_stop(I2C0_B);
result = i2c_read_byte(I2C0_B);
pause();
return result;
those routines are poorly done, they are illogical and it does not work, who was the stupid programmer who made them?
Hi asdasd aram,
Actually, how to read two bytes with I2c from a sensor is just like what my colleague already answer you in the other tip:KL25z I2C two bytes reading.
Now, I will give you the following code how to read more than 1byte, this code is from K60, but the reading flow is the same, you can refer to it and modify your KL25 code.
unsigned char I2CReadMultiRegisters(unsigned char u8RegisterAddress, unsigned char bytes)
{
unsigned char n=bytes;
int i;
/* Send Slave Address */
IIC_StartTransmission(SlaveID,MWSR);
i2c_Wait();
/* Write Register Address */
I2C0_D = u8RegisterAddress;
i2c_Wait();
/* Do a repeated start */
I2C0_C1 |= I2C_C1_RSTA_MASK;
/* Send Slave Address */
I2C0_D = (ACCEL_I2C_ADDRESS << 1) | 0x01; //read address
i2c_Wait();
/* Put in Rx Mode */
I2C0_C1 &= (~I2C_C1_TX_MASK);
/* Ensure TXAK bit is 0 */
I2C0_C1 &= ~I2C_C1_TXAK_MASK;
/* Dummy read */
result[0] = I2C0_D ;
i2c_Wait();
for(i=0;i<n-2;i++)
{
/* Read first byte */
result[i] = I2C0_D;
i2c_Wait();
}
/* Turn off ACK since this is second to last read*/
I2C0_C1 |= I2C_C1_TXAK_MASK;
/* Read second byte */
result[i++] = I2C0_D;
i2c_Wait();
/* Send stop */
i2c_Stop();
/* Read third byte */
result[i++] = I2C0_D;
printf("%3d %3d %3d\n",result[0],result[2],result[4]);
return result[0];
}
The code have the comment will help you to understand, the I2C is really a bit special to kinetis.
The special point is: first byte read need dummy read, details you can find the explanation in this paper:http://cache.freescale.com/files/sensors/doc/app_note/AN4481.pdf
Another special point is the last byte read, please just do like the example code.
I wish my answer will help you!
If you still have question, please let me know!
Best regards!
Jing