AnsweredAssumed Answered

imx28 i2c PIO Queue Mode

Question asked by liu xing on Jun 25, 2015
Latest reply on Jun 26, 2015 by liu xing

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

Outcomes