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);
}