/** * @brief Close the I2C device * * @param id I2C device to close. */ void i2c_close(const i2c_device id) { if (I2C_DATA(id) ->fd >= 0) { close(I2C_DATA(id) ->fd); } free(id); }
/*! \brief master sends slave address \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] addr: slave address \param[in] trandirection: transmitter or receiver only one parameter can be selected which is shown as below: \arg I2C_TRANSMITTER: transmitter \arg I2C_RECEIVER: receiver \param[out] none \retval none */ void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection) { /* master is a transmitter or a receiver */ if (I2C_TRANSMITTER == trandirection) { addr = addr & I2C_TRANSMITTER; } else { addr = addr | I2C_RECEIVER; } /* send slave address */ I2C_DATA(i2c_periph) = addr; }
/** * @brief Write a frame to I2C device containing \a pbtTx content * * @param id I2C device. * @param pbtTx pointer on buffer containing data * @param szTx length of the buffer * @return NFC_SUCCESS on success, otherwise driver error code */ int i2c_write(i2c_device id, const uint8_t *pbtTx, const size_t szTx) { LOG_HEX(LOG_GROUP, "TX", pbtTx, szTx); ssize_t writeCount; writeCount = write(I2C_DATA(id) ->fd, pbtTx, szTx); if ((const ssize_t) szTx == writeCount) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "wrote %d bytes successfully.", (int)szTx); return NFC_SUCCESS; } else { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Error: wrote only %d bytes (%d expected) (%s).", (int)writeCount, (int) szTx, strerror(errno)); return NFC_EIO; } }
/** Write one byte * * @param obj The I2C object * @param data Byte to be written * @return 0 if NAK was received, 1 if ACK was received, 2 for timeout. */ int i2c_byte_write(i2c_t *obj, int data) { int timeout; struct i2c_s *obj_s = I2C_S(obj); I2C_DATA(obj_s->i2c) = (uint8_t)data; /* wait until the byte is transmitted */ timeout = FLAG_TIMEOUT; while (((i2c_flag_get(obj_s->i2c, I2C_FLAG_TBE)) == RESET) && ((i2c_flag_get(obj_s->i2c, I2C_FLAG_BTC)) == RESET)) { if ((timeout--) == 0) { return 2; } } return 1; }
/** * @brief Read a frame from the I2C device and copy data to \a pbtRx * * @param id I2C device. * @param pbtRx pointer on buffer used to store data * @param szRx length of the buffer * @return length (in bytes) of read data, or driver error code (negative value) */ ssize_t i2c_read(i2c_device id, uint8_t *pbtRx, const size_t szRx) { ssize_t res; ssize_t recCount; recCount = read(I2C_DATA(id) ->fd, pbtRx, szRx); if (recCount < 0) { res = NFC_EIO; } else { if (recCount < (ssize_t)szRx) { res = NFC_EINVARG; } else { res = recCount; } } return res; }
/** * @brief Read a frame from the I2C device and copy data to \a pbtRx * * @param id I2C device. * @param pbtRx pointer on buffer used to store data * @param szRx length of the buffer * @return length (in bytes) of read data, or driver error code (negative value) */ ssize_t i2c_read(i2c_device id, uint8_t *pbtRx, const size_t szRx) { ssize_t res; ssize_t recCount; recCount = read(I2C_DATA(id) ->fd, pbtRx, szRx); if (recCount < 0) { res = NFC_EIO; log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Error: read only %d bytes (%d expected) (%s).", (int)recCount, (int) szRx, strerror(errno)); } else { if (recCount < (ssize_t)szRx) { res = NFC_EINVARG; } else { res = recCount; } } return res; }
/** Read one byte * * @param obj The I2C object * @param last Acknoledge * @return The read byte */ int i2c_byte_read(i2c_t *obj, int last) { int timeout; struct i2c_s *obj_s = I2C_S(obj); if (last) { /* disable acknowledge */ i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE); } else { /* enable acknowledge */ i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE); } /* wait until the byte is received */ timeout = FLAG_TIMEOUT; while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_RBNE)) == RESET) { if ((timeout--) == 0) { return -1; } } return (int)I2C_DATA(obj_s->i2c); }
/*! \brief I2C receive data function \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval data of received */ uint8_t i2c_data_receive(uint32_t i2c_periph) { return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph)); }
/*! \brief I2C transmit data function \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] data: data of transmission \param[out] none \retval none */ void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) { I2C_DATA(i2c_periph) = DATA_TRANS(data); }