AnsweredAssumed Answered

How  to understand the behavior of NVIC: i2c interrupt stay pending for a long time.

Question asked by Nataliya Doni on Apr 7, 2015
Latest reply on Apr 13, 2015 by Yasuhiko Koumoto

In my code I use i2c interface.  It works well for some time. But I found that in some revisions I had error in i2c interface.

I2c 100kHz, master.

After transmiting some bytes to slave i2c have stopped and in debug mode NVIC redisters show pending i2c interrupt.(NVICISPR0=0x01000000).

i2c_waitfor return 1.I

Below I show i2c interrupt code and waiting procedure.

I found this thing happends when the least byte of I2C0 interrupt code enter  and the least byte of  BNE.N  instruction in i2c_waitfor()  are the same. There is 512 byte between them.

Is  this my mistake or something wrong in processor pipeline?

What can you advise?

 

void I2C0_isr(void){

unsigned char Dum;

i2c_timeout=0;

I2C0_S |= I2C_S_IICIF_MASK;

   //ack

        if (i2c_adr_length>0){

       

          if (i2c_adr_length==2){I2C0_D = i2c_adr_ptr>>8;}else{I2C0_D = i2c_adr_ptr&0xff; } i2c_adr_length--; return;

           }else{

             

              if (i2c_curbyte==0){//конец адреса

               if ((I2C0_S&I2C_S_RXAK_MASK)!=0){i2c_Stop(); bus_error|=2;return;}

                     if (MasterTransmission == MRSW){i2c_EnterRxMode(); Dum = I2C0_D; i2c_curbyte=1;return;}  

                     if ((MasterTransmission&0x80) != 0){MasterTransmission&=0x7f;   IIC_ReStartTransmission(MasterTransmission);     return;

                    }

             

               

             }

          

  if (MasterTransmission == MWSR){// write

     if (i2c_curbyte==i2c_length){

        i2c_Stop();

    }else{

          if ((I2C0_S&I2C_S_RXAK_MASK)==0){

              I2C0_D = *i2c_buf_ptr++;

              i2c_curbyte++;

      }else{

       bus_error|=4;

        i2c_Stop();

      }

    }

  }else{

       // master read

    if (i2c_curbyte==i2c_length){

           i2c_Stop();

    }

     if (i2c_curbyte==(i2c_length-1)){

           i2c_DisableAck();

       } 

   *(uint8 *)(i2c_buf_ptr+i2c_curbyte-1) = I2C0_D;i2c_curbyte++;

  

  }

}

}

 

unsigned int i2c_waitfor(void){

while ((i2c_length > i2c_curbyte)||(((I2C0_S&0xf2)!=0x80))){

    if (i2c_timeout==60000){

    

    return(1);

   }

    i2c_timeout++;

  }

  return(0);

}

Attachments

Outcomes