diff --git a/bsp/imxrt/libraries/drivers/drv_i2c.c b/bsp/imxrt/libraries/drivers/drv_i2c.c index 117b29f3d3471d70988c66e3beb08d9c2a29f9fa..3ad48de112a4ffd3d330b3e51bb5bea28e4ce732 100644 --- a/bsp/imxrt/libraries/drivers/drv_i2c.c +++ b/bsp/imxrt/libraries/drivers/drv_i2c.c @@ -8,6 +8,7 @@ * 2017-08-08 Yang the first version * 2018-03-24 LaiYiKeTang add hardware iic * 2019-04-22 tyustli add imxrt series support + * 2021-07-18 emlsyx fix read failure bug * */ @@ -126,81 +127,24 @@ static rt_err_t imxrt_lpi2c_configure(struct imxrt_i2c_bus *bus, lpi2c_master_co LPI2C_MasterInit(bus->I2C, cfg, LPI2C_CLOCK_FREQUENCY); return RT_EOK; } - -status_t LPI2C_MasterCheck(LPI2C_Type *base, uint32_t status) +static rt_err_t imxrt_lpi2c_wait_fifo_empty(LPI2C_Type *base) { - status_t result = kStatus_Success; + size_t tx_count = 0xFFU; + size_t rx_count = 0xFFU; - /* Check for error. These errors cause a stop to automatically be sent. We must */ - /* clear the errors before a new transfer can start. */ - status &= 0x3c00; - if (status) + /* Check master tx FIFO empty or not */ + LPI2C_MasterGetFifoCounts(base, &rx_count, &tx_count); + while (tx_count || rx_count) { - /* Select the correct error code. Ordered by severity, with bus issues first. */ - if (status & kLPI2C_MasterPinLowTimeoutFlag) - { - result = kStatus_LPI2C_PinLowTimeout; - } - else if (status & kLPI2C_MasterArbitrationLostFlag) - { - result = kStatus_LPI2C_ArbitrationLost; - } - else if (status & kLPI2C_MasterNackDetectFlag) - { - result = kStatus_LPI2C_Nak; - } - else if (status & kLPI2C_MasterFifoErrFlag) - { - result = kStatus_LPI2C_FifoError; - } - else - { - assert(false); - } - - /* Clear the flags. */ - LPI2C_MasterClearStatusFlags(base, status); - - /* Reset fifos. These flags clear automatically. */ - base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK; + LPI2C_MasterGetFifoCounts(base, &rx_count, &tx_count); } - return result; -} - -/*! - * @brief Wait until the tx fifo all empty. - * @param base The LPI2C peripheral base address. - * @retval #kStatus_Success - * @retval #kStatus_LPI2C_PinLowTimeout - * @retval #kStatus_LPI2C_ArbitrationLost - * @retval #kStatus_LPI2C_Nak - * @retval #kStatus_LPI2C_FifoError - */ -static status_t LPI2C_MasterWaitForTxFifoAllEmpty(LPI2C_Type *base) -{ - uint32_t status; - size_t txCount; - - do + /* Check communicate with slave successful or not */ + if (LPI2C_MasterGetStatusFlags(base) & kLPI2C_MasterNackDetectFlag) { - status_t result; - - /* Get the number of words in the tx fifo and compute empty slots. */ - LPI2C_MasterGetFifoCounts(base, NULL, &txCount); - - /* Check for error flags. */ - status = LPI2C_MasterGetStatusFlags(base); - result = LPI2C_MasterCheck(base, status); - if (result) - { - return result; - } + return RT_EEMPTY; } - - while (txCount); - - return kStatus_Success; + return RT_EOK; } static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, @@ -221,17 +165,14 @@ static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, { if (imxrt_i2c->msg[i].flags & RT_I2C_RD) { - if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Write) != kStatus_Success) + if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success) { i = 0; break; } - while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag) - { - } - - if (LPI2C_MasterRepeatedStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success) + /* Check communicate with slave successful or not */ + if (RT_EOK != imxrt_lpi2c_wait_fifo_empty(imxrt_i2c->I2C)) { i = 0; break; @@ -251,17 +192,14 @@ static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, break; } - while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag) - { - } - - if (LPI2C_MasterSend(imxrt_i2c->I2C, imxrt_i2c->msg[i].buf, imxrt_i2c->msg[i].len) != kStatus_Success) + /* Check communicate with slave successful or not */ + if (RT_EOK != imxrt_lpi2c_wait_fifo_empty(imxrt_i2c->I2C)) { i = 0; break; } - if (LPI2C_MasterWaitForTxFifoAllEmpty(imxrt_i2c->I2C) != kStatus_Success) + if (LPI2C_MasterSend(imxrt_i2c->I2C, imxrt_i2c->msg[i].buf, imxrt_i2c->msg[i].len) != kStatus_Success) { i = 0; break; @@ -351,7 +289,6 @@ int rt_hw_i2c_init(void) return 0; } - -INIT_DEVICE_EXPORT(rt_hw_i2c_init); +INIT_BOARD_EXPORT(rt_hw_i2c_init); #endif /* BSP_USING_I2C */