Exemplo n.º 1
0
/**
 ****************************************************************************************
 * @brief Start a data transmission.
 * @param[in]  saddr         slave device address(7bits, without R/W bit)
 * @return Error code
 * @description
 * This function is used to complete an I2C write transaction from start to stop. All the intermittent steps
 * are handled in the interrupt handler while the interrupt is enabled.
 * Before this function is called, the read length, write length, I2C master buffer,
 * and I2C state need to be filled. Please refer to I2C_BYTE_WRITE().
 * As soon as the end of the data transfer is detected, the callback function is called.
 *****************************************************************************************
 */
static enum I2C_ERR_CODE i2c_write(uint8_t saddr)
{
    uint32_t reg;
    uint32_t timeout = 0;

    if (i2c_bus_check() == I2C_BUS_BUSY) {
        return I2C_CONFLICT;
    }
    else {
        i2c_env.i2cOpFsm = I2C_OP_WRDATA;
    }

    // start write slave address with write bit
    reg = I2C_MASK_WR_EN
        | I2C_MASK_START
        | ((saddr << 1) & 0xFE);
    i2c_i2c_SetTXD(QN_I2C, reg);

    do {
        timeout++;
        if (timeout > I2C_MAX_TIMEOUT) {
            return I2C_TIMEOUT;
        }
#if CONFIG_I2C_ENABLE_INTERRUPT==FALSE
        i2c_polling();
#endif

        if (i2c_env.i2cOpFsm == I2C_OP_ABORT) {
            return I2C_NO_ACK;
        }

    } while (i2c_env.i2cOpFsm != I2C_OP_FINISH);

#if I2C_CALLBACK_EN==TRUE
    // Call end of transmission callback
    if (i2c_env.callback != NULL)
    {
        i2c_env.callback();
    }
#endif

    return I2C_NO_ERROR;
}
Exemplo n.º 2
0
/**
 ****************************************************************************************
 * @brief Start a data reception.
 * @param[in]  saddr         slave device address(7bits, without R/W bit)
 * @return Error code
 * @description
 * This function is used to complete an I2C read transaction from start to stop. All the intermittent steps
 * are handled in the interrupt handler while the interrupt is enabled.
 * Before this function is called, the read length, write length, I2C master buffer,
 * and I2C state need to be filled. Please refer to I2C_BYTE_READ().
 * As soon as the end of the data transfer is detected, the callback function is called.
 *****************************************************************************************
 */
static enum I2C_ERR_CODE i2c_read(uint8_t saddr)
{
    uint32_t reg;
    uint32_t timeout = 0;

    if (i2c_bus_check() == I2C_BUS_BUSY) {
        return I2C_CONFLICT;
    }

    if (i2c_env.i2cTxCount) {
        i2c_env.i2cOpFsm = I2C_OP_SETADDR;
        // start write slave address with write bit
        reg = I2C_MASK_WR_EN
            | I2C_MASK_START
            | ((saddr << 1) & 0xFE);
        i2c_i2c_SetTXD(QN_I2C, reg);


        do {
            timeout++;
            if (timeout > I2C_MAX_TIMEOUT) {
                return I2C_TIMEOUT;
            }
#if CONFIG_I2C_ENABLE_INTERRUPT==FALSE
            i2c_polling();
#endif

            if (i2c_env.i2cOpFsm == I2C_OP_ABORT) {
                return I2C_NO_ACK;
            }

        } while (i2c_env.i2cOpFsm != I2C_OP_RDDATA);
    }
    else {
        // does not need write address, directly read data from device
        i2c_env.i2cOpFsm = I2C_OP_RDDATA;
    }
    
    // start write slave address with read bit
    reg = I2C_MASK_WR_EN
        | I2C_MASK_START
        | ((saddr << 1) | 0x01);
    i2c_i2c_SetTXD(QN_I2C, reg);

    timeout = 0;
    do {
        timeout++;
        if (timeout > I2C_MAX_TIMEOUT) {
            return I2C_TIMEOUT;
        }
#if CONFIG_I2C_ENABLE_INTERRUPT==FALSE
        i2c_polling();
#endif

        if (i2c_env.i2cOpFsm == I2C_OP_ABORT) {
            return I2C_NO_ACK;
        }

    } while (i2c_env.i2cOpFsm != I2C_OP_FINISH);

#if I2C_CALLBACK_EN==TRUE
    // Call end of reception callback
    if (i2c_env.callback != NULL)
    {
        i2c_env.callback();
    }
#endif

    return I2C_NO_ERROR;
}
Exemplo n.º 3
0
/**
 ****************************************************************************************
 * @brief Start a data reception.
 * @param[in]      saddr          slave device address (7bits, without R/W bit)
 * @description
 * This function is used to complete an I2C read transaction from start to stop. All the intermittent steps
 * are handled in the interrupt handler while the interrupt is enabled.
 * Before this function is called, the read length, write length, I2C master buffer,
 * and I2C state need to be filled. Please refer to I2C_BYTE_READ().
 * As soon as the end of the data transfer is detected, the callback function is called.
 *****************************************************************************************
 */
void i2c_read(uint8_t saddr)
{
    uint32_t reg;
    uint32_t timeout = 0;

    if (i2c_bus_check() == I2C_BUS_BUSY) {
        return;
    }

    if (i2c_env.i2cTxCount) {
        i2c_env.i2cOpFsm = I2C_OP_SETADDR;
        // start write slave address with write bit
        reg = I2C_MASK_WR_EN
            | I2C_MASK_START
            | ((saddr << 1) & 0xFE);
        i2c_i2c_SetTXD(QN_I2C, reg);

#ifdef SLP_TEST_EN
        // Wait For Interrupt
        __WFI();  // Enter sleep mode
        // Wakeup when I2C interrupt is triggered
#endif

        do {
            timeout++;
            if (timeout > I2C_MAX_TIMEOUT) {
                break;
            }
#if CONFIG_I2C_ENABLE_INTERRUPT==FALSE
            i2c_polling();
#endif
        } while ((i2c_env.i2cOpFsm != I2C_OP_RDDATA)&&(i2c_env.i2cOpFsm != I2C_OP_ABORT));
    }
    else {
        // does not need write address, directly read data from device
        i2c_env.i2cOpFsm = I2C_OP_RDDATA;
    }
    
    // start write slave address with read bit
    reg = I2C_MASK_WR_EN
        | I2C_MASK_START
        | ((saddr << 1) | 0x01);
    i2c_i2c_SetTXD(QN_I2C, reg);

    timeout = 0;
    do {
        timeout++;
        if (timeout > I2C_MAX_TIMEOUT){
            break;
        }
#if CONFIG_I2C_ENABLE_INTERRUPT==FALSE
        i2c_polling();
#endif
    } while (i2c_env.i2cOpFsm != I2C_OP_FINISH);

#if I2C_CALLBACK_EN==TRUE
    // Call end of reception callback
    if ((i2c_env.i2cOpFsm == I2C_OP_FINISH) && (i2c_env.callback != NULL))
    {
        i2c_env.callback();
    }
#endif

}