int I2C::transfer(i2c_msg_s *msgv, unsigned msgs) { int ret; unsigned retry_count = 0; /* force the device address into the message vector */ for (unsigned i = 0; i < msgs; i++) msgv[i].addr = _address; do { /* * I2C architecture means there is an unavoidable race here * if there are any devices on the bus with a different frequency * preference. Really, this is pointless. */ I2C_SETFREQUENCY(_dev, _frequency); ret = I2C_TRANSFER(_dev, msgv, msgs); /* success */ if (ret == OK) break; /* if we have already retried once, or we are going to give up, then reset the bus */ if ((retry_count >= 1) || (retry_count >= _retries)) up_i2creset(_dev); } while (retry_count++ < _retries); return ret; }
int I2C::transfer(i2c_msg_s *msgv, unsigned msgs) { int ret; unsigned retry_count = 0; /* force the device address into the message vector */ for (unsigned i = 0; i < msgs; i++) msgv[i].addr = _address; do { ret = I2C_TRANSFER(_dev, msgv, msgs); /* success */ if (ret == OK) break; /* if we have already retried once, or we are going to give up, then reset the bus */ if ((retry_count >= 1) || (retry_count >= _retries)) up_i2creset(_dev); } while (retry_count++ < _retries); return ret; }
static int lps25h_do_transfer(FAR struct lps25h_dev_t *dev, FAR struct i2c_msg_s *msgv, size_t nmsg) { int ret = -EIO; int retries; for (retries = 0; retries < LPS25H_I2C_RETRIES; retries++) { ret = I2C_TRANSFER(dev->i2c, msgv, nmsg); if (ret >= 0) { return 0; } else { /* Some error. Try to reset I2C bus and keep trying. */ #ifdef CONFIG_I2C_RESET ret = up_i2creset(dev->i2c); if (ret < 0) { lps25h_dbg("up_i2creset failed: %d\n", ret); return ret; } #endif continue; } } lps25h_dbg("xfer failed: %d\n", ret); return ret; }
int I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned recv_len) { struct i2c_msg_s msgv[2]; unsigned msgs; int ret; unsigned retry_count = 0; do { // debug("transfer out %p/%u in %p/%u", send, send_len, recv, recv_len); msgs = 0; if (send_len > 0) { msgv[msgs].addr = _address; msgv[msgs].flags = 0; msgv[msgs].buffer = const_cast<uint8_t *>(send); msgv[msgs].length = send_len; msgs++; } if (recv_len > 0) { msgv[msgs].addr = _address; msgv[msgs].flags = I2C_M_READ; msgv[msgs].buffer = recv; msgv[msgs].length = recv_len; msgs++; } if (msgs == 0) return -EINVAL; /* * I2C architecture means there is an unavoidable race here * if there are any devices on the bus with a different frequency * preference. Really, this is pointless. */ I2C_SETFREQUENCY(_dev, _frequency); ret = I2C_TRANSFER(_dev, &msgv[0], msgs); /* success */ if (ret == OK) break; /* if we have already retried once, or we are going to give up, then reset the bus */ if ((retry_count >= 1) || (retry_count >= _retries)) up_i2creset(_dev); } while (retry_count++ < _retries); return ret; }
int I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned recv_len) { struct i2c_msg_s msgv[2]; unsigned msgs; int ret; unsigned retry_count = 0; do { // DEVICE_DEBUG("transfer out %p/%u in %p/%u", send, send_len, recv, recv_len); msgs = 0; if (send_len > 0) { msgv[msgs].addr = _address; msgv[msgs].flags = 0; msgv[msgs].buffer = const_cast<uint8_t *>(send); msgv[msgs].length = send_len; msgs++; } if (recv_len > 0) { msgv[msgs].addr = _address; msgv[msgs].flags = I2C_M_READ; msgv[msgs].buffer = recv; msgv[msgs].length = recv_len; msgs++; } if (msgs == 0) { return -EINVAL; } ret = I2C_TRANSFER(_dev, &msgv[0], msgs); /* success */ if (ret == OK) { break; } /* if we have already retried once, or we are going to give up, then reset the bus */ if ((retry_count >= 1) || (retry_count >= _retries)) { up_i2creset(_dev); } } while (retry_count++ < _retries); return ret; }
static int transfer(uint8_t address, uint8_t *send, unsigned send_len, uint8_t *recv, unsigned recv_len) { struct i2c_msg_s msgv[2]; unsigned msgs; int ret; // debug("transfer out %p/%u in %p/%u", send, send_len, recv, recv_len); msgs = 0; if (send_len > 0) { msgv[msgs].addr = address; msgv[msgs].flags = 0; msgv[msgs].buffer = send; msgv[msgs].length = send_len; msgs++; } if (recv_len > 0) { msgv[msgs].addr = address; msgv[msgs].flags = I2C_M_READ; msgv[msgs].buffer = recv; msgv[msgs].length = recv_len; msgs++; } if (msgs == 0) return -1; /* * I2C architecture means there is an unavoidable race here * if there are any devices on the bus with a different frequency * preference. Really, this is pointless. */ I2C_SETFREQUENCY(i2c, 400000); ret = I2C_TRANSFER(i2c, &msgv[0], msgs); // reset the I2C bus to unwedge on error if (ret != OK) up_i2creset(i2c); return ret; }
/* * Reset the peripheral and generate a recovery sequence on the bus. * To be used when the bus is stuck. */ inline void i2c_reset(void) { dbg_info("%s()\n", __func__); up_i2creset(sw_exp_dev); }