I2C bug

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C bug

1,839 Views
martindusek
Contributor V

I'm getting some weird behaviour with my slave IIC driver on FRDM-KL02Z board (REV C, REV B) when STOP interrupt is enabled. This is my slave driver:

void IicSlaveInit( void){

   IIC->C1 = 0;

   IIC->FLT |= I2C_FLT_STOPIE_MASK; // enable stop interrupt    IIC->C1 |= I2C_C1_IICEN_MASK; // enable    IIC->C1 |= I2C_C1_IICIE_MASK; // enable interrupt }

static int Event; // just some dummy variable...

void __irq I2C0_IRQHandler( void) {

   if(IIC->S & I2C_S_IAAS_MASK) {     // BKPT1

      Event = 0;

   } else if(IIC->FLT & I2C_FLT_STOPF_MASK) {

      Event = 1;

   } else if(IIC->S & I2C_S_TCF_MASK) {

      Event = 2; // BKPT2

   } else {

      Event = 3;

   }

  IIC->C1 &= ~I2C_C1_IICIE_MASK;

}

With STOP interrupt enabled in IicSlaveInit() function the ISR is executed (and ends with Event == 2) on IIC START condition. I expect no interrupt on START condition.

Notes:

1) Before the test, IIC bus is idle (both SDA and SCL pulled high by pull up resistors). Nothing else than the IIC START condition happens on the bus (observed by scope).

2) With STOP interrupt disabled there is no interrupt when START condition appers on the bus.

Why this happens?

Labels (1)
Tags (1)
10 Replies

952 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Martin,

I found in RM there is some note for the STOPIE bit, please kindly refer to the following for details.

1.png

maybe your ISR has to be changed accordingly.

Hope that helps,


Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

952 Views
martindusek
Contributor V

Dear Kan,

thanks for your reply. Please let me explain the issue once more.

I have no problem with STOPF flag. The problem is inconsistent firing of interrupts. As stated before, I'm getting interrupt on START condition (when STOPIE set to 1). The source of the interrupt on the START condition is TCF flag because I get Event == 2 when the ISR returns to my main program.

If I disable STOPIE, I'm getting no interrupt on START condition.

0 Kudos

952 Views
Kan_Li
NXP TechSupport
NXP TechSupport

!Hi Martin,

Just some update for this issue, our Lead AE for this part recommend you referring to RM , Figure 35-30. Typical I2C interrupt routine, which have full details on how to implement a slave i2c ISR, and he provided his slave i2c driver code as well. Please kindly refer to the attachment for more details.


Hope that helps,

Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

952 Views
martindusek
Contributor V

Dear Kan,

unfortunately, I need to detect STOP condition on the bus so the standard interrupt routine is not suitable for me.

I can live with that false interrupt on START condition when the STOP condition interrupt is enabled, but it seems it is some undocumented behaviour of IIC module (at least I haven't got an answer why that false interrupt triggers) ....

0 Kudos

952 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Martin,

I just got the feedback from our AE team, they told me the above iic_slave driver code has already take stop condition detection into account, you may find STOPIE bit is set in void IIC_Init( void )

   I2C0_FLT |=0x20;

and in void I2C0_IRQHandler( void ), a code snippet is assigned for that case:

void I2C0_IRQHandler( void )

{

    //    if( I2C0_S & I2C_S_IICIF_MASK )

            if(I2C0_FLT & 0x40)

            {

                    I2C0_FLT |= 0x40;

                    I2C0_S |= I2C_S_IICIF_MASK;

                    if( !(I2C0_S & I2C_S_SRW_MASK) )

                    {

                        I2C0_FLT |=0x40;

                        I2C0_S |= I2C_S_IICIF_MASK;                      

                        if(I2C_RW==0)

                        I2C_Write();

                                      

                        I2C_RW=1;

                        SMB_RCount=0;

                    }

                    else

                    {

                        Dummy = I2C0_D;

                    }

            }

Please kindly try that driver in your application and let me know if you have any issue.


Hope that helps,

Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

952 Views
Kan_Li
NXP TechSupport
NXP TechSupport

!Hi Martin,

Have you used the driver code with STOPIE enabled? is the problem still there after that try? Actually I also tested that interrupt source on my side with FRDM-KL05Z, I tried to pull PTB4 down to GND to simulate the START signal, but I2C interrupt didnt happen in that case? did you successfully observe that interrupt hit by doing that? Please kindly help to clarify. I attached my source code here for your reference.


Hope that helps,

Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

952 Views
martindusek
Contributor V

Your program ends with hard fault - you don't turn on clock of PORTB module. My code is attached (it won't compile in CodeWarrior as I use CrossStudio for ARM).


On START condition, the interrupt is hit. Status and FLT register holds these values at that moment:

I2C0->S = 0xA2

I2C0->FLT = 0x30

0 Kudos

952 Views
Kan_Li
NXP TechSupport
NXP TechSupport

!Hi Martin,

I am sorry for that mistake, the code is from a IAR project, KL05_SC, you know, the PORTA and PORTB clock are enabled in sysinit() out of reset , so I didn't enable them twice. I am using your code for this issue now, and trying to simulate I2C transfer with 2 GPIOs which connected with I2C0_SCL and I2C0_SDA to reproduce your issue, but so far I didnt find that I2C start condition would generate interrupt of STOP detection , but I could see IAAS and BUSY bits are set in I2C_S after I2C start signals, not sure if you have done that before, but I will send your my code when I finish the test. Here I attached the I2C timing I simulated by 2 GPIOs. The slave address is 0xA0 in my case.

tek00000.png

You may find the IRQ didnt toggle in above case, so I am wondering how you confirm interrupt happens when I2C slave received start condition, would you please help to clarify?


Thanks for your patience!!

Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

952 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Martin,

Thanks for the clarification!!

Actually I found TCF bit is set our of reset as below:

1.png

so if your  code just enables interrupt before clearing this bit, ISR would be hit whether I2C start condition detected or not, and I think maybe you can poll this bit in main application or enable interrupt after a reading or writing is issued.


Hope that helps,

Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

952 Views
martindusek
Contributor V

Thanks for explanation. Now I understand why I get Event == 2 in my program.

What I don't understand is why interrupt triggers on START condition on IIC bus - there is no such interrupt source for IIC module stated in reference manual for the CPU used in FRDM-KL02Z. And what I understand even less is why it depends on STOPIE bit: If STOPIE bit set - START condition triggers interrupt. If not set - START condition doesn't trigger interrupt.

0 Kudos