It seem to solve the tip latching problem, but still there are some arbitration issues. The piece of schematic:
http://i41.tinypic.com/2h3a32d.png And the code:
int i2c_init(int prescaler,void* isr,int BASE,int IRQ,int IRQ_ICID){
int res=1;
IOWR_16DIRECT(BASE,OC_I2C_PRER_LO,prescaler);
if(IORD_16DIRECT(BASE,OC_I2C_PRER_LO)==prescaler){
IOWR_8DIRECT(BASE,OC_I2C_CTR,0xC0);
if(IORD_8DIRECT(BASE,OC_I2C_CTR)==0xC0){
if(alt_ic_isr_register(IRQ_ICID,IRQ,isr,NULL,NULL)==0){
res=0;
}
}
}
return res;
}
static void i2c_isr(void *context){
printf("Status register: %d\n",IORD_8DIRECT(I2C_BASE,OC_I2C_SR));
IOWR_8DIRECT(I2C_BASE,OC_I2C_CR,0x01);
}
int main()
{
if(i2c_init(PreSC,(void*)i2c_isr,I2C_BASE,I2C_IRQ,I2C_IRQ_INTERRUPT_CONTROLLER_ID)==0){
IOWR_8DIRECT(I2C_BASE,OC_I2C_TXR,0x80); //write slave address+write bit
IOWR_8DIRECT(I2C_BASE,OC_I2C_CR,0x90); //set STA, set WR
IOWR_8DIRECT(I2C_BASE,OC_I2C_TXR,0x02); //write subaddr
IOWR_8DIRECT(I2C_BASE,OC_I2C_CR,0x10); //set WR
IOWR_8DIRECT(I2C_BASE,OC_I2C_TXR,0x81); //write addr+read bit
IOWR_8DIRECT(I2C_BASE,OC_I2C_CR,0x90); //set WR, set STA
IOWR_8DIRECT(I2C_BASE,OC_I2C_CR,0x68); //set NACK, set STO, SET RD
printf("RxD=%d\n",IORD_8DIRECT(I2C_BASE,OC_I2C_RXR));
}else{
printf("I2C init fail!\n");
}
return 0;
}
Right after i register the ISR, the arbitration lost occures (once). Then not a single acknowledgement from slave (ADV7180) proceed.