does imx286 i2c controller support PIO Queue mode.I want to disable interrupt in PIO Queue mode.however,i can't meter the sda and scl signal when i write/read i2c bus.
who can help me check the following code?
void I2COpen(UINT devId)
{
HW_I2C_CTRL0_CLR(devId, BM_I2C_CTRL0_SFTRST);
HW_I2C_CTRL0_CLR(devId, BM_I2C_CTRL0_CLKGATE);
// asserting soft-reset
HW_I2C_CTRL0_SET(devId, BM_I2C_CTRL0_SFTRST);
// waiting for confirmation of soft-reset
while (!HW_I2C_CTRL0(devId).B.CLKGATE);
// Done.
HW_I2C_CTRL0_CLR(devId, BM_I2C_CTRL0_SFTRST | BM_I2C_CTRL0_CLKGATE);
// disable interrupts at the beginning
HW_I2C_CTRL1_CLR(devId, BM_I2C_CTRL1_BCAST_SLAVE_EN |
BM_I2C_CTRL1_BUS_FREE_IRQ_EN |
BM_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ_EN |
BM_I2C_CTRL1_SLAVE_STOP_IRQ_EN |
BM_I2C_CTRL1_SLAVE_IRQ_EN |
BM_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ_EN |
BM_I2C_CTRL1_NO_SLAVE_ACK_IRQ_EN |
BM_I2C_CTRL1_EARLY_TERM_IRQ_EN |
BM_I2C_CTRL1_MASTER_LOSS_IRQ_EN
);
// Clear the CTRL0 register
HW_I2C_CTRL0_CLR(devId, BM_I2C_CTRL0_RUN |
BM_I2C_CTRL0_MULTI_MASTER |
BM_I2C_CTRL0_CLOCK_HELD |
BM_I2C_CTRL0_RETAIN_CLOCK |
BM_I2C_CTRL0_PRE_SEND_START |
BM_I2C_CTRL0_POST_SEND_STOP
);
// enable the clock
HW_I2C_CTRL0_CLR(devId, BM_I2C_CTRL0_CLKGATE);
//100k
HW_I2C_TIMING0_WR(devId, 0x00780030); // high time = 120 clocks, read bit at 48 for 95KHz at 24mhz
HW_I2C_TIMING1_WR(devId, 0x00800030); // low time at 128, write bit at 48 for 95 kHz at 24 MHz
HW_I2C_TIMING2_WR(devId, 0x0015000D); // bus free count of 21 lead in count of 13
HW_I2C_CTRL1_SET(devId, BM_I2C_CTRL1_ACK_MODE);
HW_I2C_CTRL1_CLR(devId, 0x0000FF00);
HW_I2C_QUEUECTRL_SET(devId,BM_I2C_QUEUECTRL_PIO_QUEUE_MODE);
HW_I2C_CTRL0_SET(devId,BM_I2C_CTRL0_RUN);
HW_I2C_QUEUECTRL_CLR(devId,BM_I2C_QUEUECTRL_QUEUE_RUN);
}
UINT I2CRead(BYTE SlaveAddr,BYTE subaddr,VOID *pBuffer,UINT32 size)
{
UINT32 QueCmd = 0,RxSize = 0,RxCnt = 0;
DWORD dwTickCnt = 0;
DWORD *ptrRx = NULL;
QueCmd = CMD_I2C_WRITE|BF_I2C_CTRL0_XFER_COUNT(3);
HW_I2C_QUEUECMD_WR(I2C_INDEX,QueCmd);
memset(TxBuf,0x00,100);
TxBuf[0] = (SlaveAddr << 1)|I2C_WRITE;
TxBuf[1] = subaddr;
TxBuf[2] = SlaveAddr << 1)|I2C_READ;
ptrRx = (DWORD *)&TxBuf[0];
HW_I2C_DATA_WR(I2C_INDEX,*ptrRx);
QueCmd = CMD_I2C_READ|BF_I2C_CTRL0_XFER_COUNT(size);
QueCmd |= BM_I2C_QUEUECMD_POST_SEND_STOP;
HW_I2C_QUEUECMD_WR(I2C_INDEX,QueCmd);
HW_I2C_QUEUECTRL_SET(I2C_INDEX,BM_I2C_QUEUECTRL_QUEUE_RUN);
ptrRx= (DWORD *)&RxBuf[0];
RxSize = (size+3)/4;
dwTickCnt = OALGetTickCountEx();
while(RxSize)
{
if(OALGetTickCountEx()-dwTickCnt>1000)break;
if(!(HW_I2C_QUEUESTAT_RD(I2C_INDEX)&BM_I2C_QUEUESTAT_RD_QUEUE_EMPTY))
{
*ptrRx = HW_I2C_QUEUEDATA_RD(I2C_INDEX);
ptrRx++;
RxSize--;
RxCnt += 4;
}
}
if(RxCnt)
{
RxCnt =(RxCnt>size)?size:RxCnt;
}
HW_I2C_QUEUECTRL_CLR(I2C_INDEX,BM_I2C_QUEUECTRL_QUEUE_RUN);
memcpy(pBuffer,&RxBuf[0],RxCnt);
return RxCnt;
}
//////////////////////
after set HW_I2C_QUEUECTRL.QUEUE_RUN
HW_I2C_QUEUESTAT = 0x00002048
HW_I2C_QUEUECMD = 0x00120001