Dear Freescale Community!
I've successfully set up a toolchain to program the KL25Z dev board, and I need some kind of help using I2C!
I'am trying to access the onboard inertia sensor, I can address it correctly, I receive ACK on my commands, but when I want to receive data, I cannot get the proper data back.
Example: I want to read out the "Who I am" register, the chip accepts my request, but I cannot get back the 0x2A result, as I should. Here is my code:
I2C0_F |= I2C_F_MULT(0); //erata says MULT with different value of 0 blocks RESTART condition
I2C0_F |= I2C_F_ICR(63); //~317 kbaud
I2C0_C1 |= I2C_C1_IICEN_MASK;//enable I2C module
I2C0_C1 |= I2C_C1_TX_MASK;//set up for transmit
I2C0_C1 |= I2C_C1_MST_MASK;//I2C START action
for(delay=0;delay<10000;delay++);
i2c_send_byte(0x3a);//ACK=ok, i tested it
i2c_send_byte(0x0d);//ACK=ok, i tested it
I2C0_C1 |= I2C_C1_RSTA_MASK;//restart
i2c_send_byte(0x3b); //ACK=ok, i tested it
I2C0_C1 &= ~I2C_C1_TX_MASK; //enable i2c receive
if(I2C0_D); //trigger receive in I2C bus, Here Iam just reading the data register. If i miss this step I cannot receive anything
while(1){
if((I2C0_S & I2C_S_TCF_MASK) != I2C_S_TCF_MASK) break;}
while(1){ if((I2C0_S & I2C_S_TCF_MASK)) break;}
for(delay=0;delay<10000;delay++);
I2C0_C1 |= I2C_C1_TXAK_MASK; //generate no ack condition
I2C0_C1 |= I2C_C1_TX_MASK; //enable transmission, by this the next read of data register will not trigger byte reception
c=I2C0_D; //after completion of reception I read out the data register
if(c == 0x2a) GPIOB_PDOR &=~(1 << 18); //I cannot get the proper result
I hope you can breifly help me, how to receive data on i2c bus!
Thank you in advance!
Roth K.
Solved! Go to Solution.
Hi Karl,
just a wild shot: there is an issue in the KL25Z around 'repeated start'. I was bumping into this one, and it could be your problem:
KL25Z and I2C: Missing Repeated Start Condition | MCU on Eclipse
I recommend that you check your clock settings/dividers if this is your problem.
In any case, I recommend that you use a logic analyzer to check what is going on the bus.
If you have another FRDM-KL25Z, you could turn it into a low logic analzyer too (Turning the Freedom Board into a Logic Analyzer | MCU on Eclipse).
Altough I'm using Processor Expert, this post with the sources on GitHub might be helpful:
Extended Driver for the MMA8451Q Accelerometer | MCU on Eclipse
I hope this helps.
Hi Karl,
just a wild shot: there is an issue in the KL25Z around 'repeated start'. I was bumping into this one, and it could be your problem:
KL25Z and I2C: Missing Repeated Start Condition | MCU on Eclipse
I recommend that you check your clock settings/dividers if this is your problem.
In any case, I recommend that you use a logic analyzer to check what is going on the bus.
If you have another FRDM-KL25Z, you could turn it into a low logic analzyer too (Turning the Freedom Board into a Logic Analyzer | MCU on Eclipse).
Altough I'm using Processor Expert, this post with the sources on GitHub might be helpful:
Extended Driver for the MMA8451Q Accelerometer | MCU on Eclipse
I hope this helps.
Thank you for your help!
Formerly i've figured out the lack of restart condition in the silicon erata sheet.
I met a strange thing about the MMA8452Q inertia sensor:
The datasheet of the sensor says that the "Who I am" field is factory programmed at 0x2A value.
I decided to use the onboard USB to serial converter, to debug the received value.
Result: The value as "Who I am" sent back as 0x1A data.
After this I was curious about the other register's default values, and I find out that the other values
are read correctly, only the "Who I am" identification data were incorrect.
Thanks to this documentation problem, I spent 2 days without success, and I have modified my code multiple times
because I thought the problem is with me...
Sorry, I made the mistake. When I downloaded the datasheet of the 8452 insted of 8451, thats why I wanted to read 0x2a instead of 0x1a.
The documentation correct, sorry!