int i2ctool_get(FAR struct i2ctool_s *i2ctool, FAR struct i2c_dev_s *dev, uint8_t regaddr, uint16_t *result) { struct i2c_msg_s msg[2]; union { uint16_t data16; uint8_t data8; } u; int ret; /* Set up data structures */ msg[0].addr = i2ctool->addr; msg[0].flags = 0; msg[0].buffer = ®addr; msg[0].length = 1; msg[1].addr = i2ctool->addr; msg[1].flags = I2C_M_READ; if (i2ctool->width == 8) { msg[1].buffer = &u.data8; msg[1].length = 1; } else { msg[1].buffer = (uint8_t*)&u.data16; msg[1].length = 2; } if (i2ctool->start) { ret = I2C_TRANSFER(dev, &msg[0], 1); if (ret== OK) { ret = I2C_TRANSFER(dev, &msg[1], 1); } } else { ret = I2C_TRANSFER(dev, msg, 2); } /* Return the result of the read operation */ if (ret == OK) { if (i2ctool->width == 8) { *result = (uint16_t)u.data8; } else { *result = u.data16; } } return ret; }
static int cs2100_read_ratio(FAR const struct cs2100_config_s *config, uint32_t *ratio) { struct i2c_msg_s msg; uint8_t buffer[4]; int ret; DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer); /* Construct the I2C message (write N+1 bytes with no restart) */ buffer[0] = CS2100_RATIO0; msg.frequency = config->i2cfreq; msg.addr = config->i2caddr; msg.flags = 0; msg.buffer = buffer; msg.length = 1; /* Send the address followed by a STOP */ ret = I2C_TRANSFER(config->i2c, &msg, 1); if (ret == OK) { msg.frequency = config->i2cfreq; msg.addr = config->i2caddr; msg.flags = I2C_M_READ; msg.buffer = buffer; msg.length = 4; /* Read the ratio registers beginning with another START */ ret = I2C_TRANSFER(config->i2c, &msg, 1); /* Return the ratio */ if (ret == OK) { *ratio = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) | ((uint32_t)buffer[2] << 8) | (uint32_t)buffer[0]; regdbg("%02x->%04l\n", CS2100_RATIO0, (unsigned long)*ratio); } } 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(i2c_msg_s *msgv, unsigned msgs) { int ret; unsigned retry_count = 0; /* force the device address and Frequency into the message vector */ for (unsigned i = 0; i < msgs; i++) { msgv[i].frequency = _bus_clocks[_bus - 1]; 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)) { I2C_RESET(_dev); } } while (retry_count++ < _retries); return ret; }
static int cs2100_write_reg(FAR const struct cs2100_config_s *config, uint8_t regaddr, uint8_t regval) { struct i2c_msg_s msgs[2]; regdbg("%02x<-%02x\n", regaddr, regval); DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer); /* Construct the I2C message (write N+1 bytes with no restart) */ msga[0].frequency = config->i2cfreq; msgs[0].addr = config->i2caddr; msgs[0].flags = 0; msgs[0].buffer = ®addr; msgs[0].length = 1; msga[1].frequency = config->i2cfreq; msgs[1].addr = config->i2caddr; msgs[1].flags = I2C_M_NORESTART; msgs[1].buffer = ®val; msgs[1].length = 1; /* Send the message */ return I2C_TRANSFER(config->i2c, msgs, 2); }
static int cs2100_write_ratio(FAR const struct cs2100_config_s *config, uint32_t ratio) { struct i2c_msg_s msg; uint8_t buffer[5]; regdbg("%02x<-%04l\n", CS2100_RATIO0, (unsigned long)ratio); DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer); /* Construct the I2C message (write N+1 bytes with no restart) */ buffer[0] = CS2100_RATIO0; buffer[1] = (uint8_t)(ratio >> 24); buffer[2] = (uint8_t)((ratio >> 16) & 0xff); buffer[3] = (uint8_t)((ratio >> 8) & 0xff); buffer[4] = (uint8_t)(ratio & 0xff); msg.addr = config->i2caddr; msg.flags = 0; msg.buffer = buffer; msg.length = 5; /* Send the message */ return I2C_TRANSFER(config->i2c, &msg, 1); }
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; }
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(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].frequency = _bus_clocks[_bus - 1]; 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].frequency = _bus_clocks[_bus - 1];; 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)) { I2C_RESET(_dev); } } while (retry_count++ < _retries); return ret; }
static int cs2100_read_reg(FAR const struct cs2100_config_s *config, uint8_t regaddr, uint8_t *regval) { struct i2c_msg_s msg; int ret; DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer); /* Construct the I2C message (write 1 bytes, restart, read N bytes) */ msg.frequency = config->i2cfreq; msg.addr = config->i2caddr; msg.flags = 0; msg.buffer = ®addr; msg.length = 1; /* Send the address followed by a STOP */ ret = I2C_TRANSFER(config->i2c, &msg, 1); if (ret == OK) { msg.frequency = config->i2cfreq; msg.addr = config->i2caddr; msg.flags = I2C_M_READ; msg.buffer = regval; msg.length = 1; /* Read the register beginning with another START */ ret = I2C_TRANSFER(config->i2c, &msg, 1); if (ret == OK) { regdbg("%02x->%02x\n", regaddr, *regval); } } return ret; }
static int lm75_i2c_write(FAR struct lm75_dev_s *priv, FAR const uint8_t *buffer, int buflen) { struct i2c_msg_s msg; /* Setup for the transfer */ msg.frequency = CONFIG_LM75_I2C_FREQUENCY, msg.addr = priv->addr; msg.flags = 0; msg.buffer = (FAR uint8_t *)buffer; /* Override const */ msg.length = buflen; /* Then perform the transfer. */ return I2C_TRANSFER(priv->i2c, &msg, 1); }
static int lm75_i2c_read(FAR struct lm75_dev_s *priv, FAR uint8_t *buffer, int buflen) { struct i2c_msg_s msg; /* Setup for the transfer */ msg.frequency = CONFIG_LM75_I2C_FREQUENCY, msg.addr = priv->addr, msg.flags = I2C_M_READ; msg.buffer = buffer; msg.length = buflen; /* Then perform the transfer. */ return I2C_TRANSFER(priv->i2c, &msg, 1); }
int i2c_writeread(FAR struct i2c_dev_s *dev, FAR const struct i2c_config_s *config, FAR const uint8_t *wbuffer, int wbuflen, FAR uint8_t *rbuffer, int rbuflen) { struct i2c_msg_s msg[2]; unsigned int flags; int ret = -1; /* 7- or 10-bit address? */ DEBUGASSERT(config->addrlen == 10 || config->addrlen == 7); flags = (config->addrlen == 10) ? I2C_M_TEN : 0; /* Format two messages: The first is a write */ msg[0].addr = config->address; msg[0].flags = flags; msg[0].buffer = (FAR uint8_t *)wbuffer; /* Override const */ msg[0].length = wbuflen; /* The second is either a read (rbuflen > 0) or a write (rbuflen < 0) with * no restart. */ if (rbuflen > 0) { msg[1].flags = (flags | I2C_M_READ); } else { msg[1].flags = (flags | I2C_M_NORESTART); rbuflen = -rbuflen; } msg[1].addr = config->address; msg[1].buffer = rbuffer; msg[1].length = rbuflen; /* Then perform the transfer * * REVISIT: The following two operations must become atomic in order to * assure thread safety. */ if (dev != 0x0) { I2C_SETFREQUENCY(dev, config->frequency); ret = I2C_TRANSFER(dev, msg, 2); } return ret; }
uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr) { /* 16-bit data read sequence: * * Start - I2C_Write_Address - STMPE811_Reg_Address - * Repeated_Start - I2C_Read_Address - STMPE811_Read_Data_1 - * STMPE811_Read_Data_2 - STOP */ struct i2c_msg_s msg[2]; uint8_t rxbuffer[2]; int ret; /* Setup 8-bit STMPE811 address write message */ msg[0].addr = priv->config->address; /* 7-bit address */ msg[0].flags = 0; /* Write transaction, beginning with START */ msg[0].buffer = ®addr; /* Transfer from this address */ msg[0].length = 1; /* Send one byte following the address * (no STOP) */ /* Set up the 8-bit STMPE811 data read message */ msg[1].addr = priv->config->address; /* 7-bit address */ msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ msg[1].buffer = rxbuffer; /* Transfer to this address */ msg[1].length = 2; /* Receive two bytes following the address * (then STOP) */ /* Perform the transfer */ ret = I2C_TRANSFER(priv->i2c, msg, 2); if (ret < 0) { idbg("I2C_TRANSFER failed: %d\n", ret); return 0; } #ifdef CONFIG_STMPE811_REGDEBUG dbg("%02x->%02x%02x\n", regaddr, rxbuffer[0], rxbuffer[1]); #endif return (uint16_t)rxbuffer[0] << 8 | (uint16_t)rxbuffer[1]; }
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; }
uint8_t adxl345_getreg8(FAR struct adxl345_dev_s *priv, uint8_t regaddr) { /* 8-bit data read sequence: * * Start - I2C_Write_Address - ADXL345_Reg_Address - * Repeated_Start - I2C_Read_Address - ADXL345_Read_Data - STOP */ struct i2c_msg_s msg[2]; uint8_t regval; int ret; /* Setup 8-bit ADXL345 address write message */ msg[0].addr = priv->config->address; /* 7-bit address */ msg[0].flags = 0; /* Write transaction, beginning with START */ msg[0].buffer = ®addr; /* Transfer from this address */ msg[0].length = 1; /* Send one byte following the address * (no STOP) */ /* Set up the 8-bit ADXL345 data read message */ msg[1].addr = priv->config->address; /* 7-bit address */ msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */ msg[1].buffer = ®val; /* Transfer to this address */ msg[1].length = 1; /* Receive one byte following the address * (then STOP) */ /* Perform the transfer */ ret = I2C_TRANSFER(priv->i2c, msg, 2); if (ret < 0) { sndbg("I2C_TRANSFER failed: %d\n", ret); return 0; } #ifdef CONFIG_ADXL345_REGDEBUG dbg("%02x->%02x\n", regaddr, regval); #endif return regval; }
int ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval) { /* 8-bit data read sequence: * * Start - I2C_Write_Address - SSD1306_Reg_Address - SSD1306_Write_Data - STOP */ struct i2c_msg_s msg; uint8_t txbuffer[2]; int ret; #ifdef CONFIG_LCD_SSD1306_REGDEBUG _err("-> 0x%02x\n", regval); #endif /* Setup to the data to be transferred. Two bytes: The SSD1306 register * address followed by one byte of data. */ txbuffer[0] = 0x00; txbuffer[1] = regval; /* Setup 8-bit SSD1306 address write message */ msg.frequency = CONFIG_SSD1306_I2CFREQ; /* I2C frequency */ msg.addr = priv->addr; /* 7-bit address */ msg.flags = 0; /* Write transaction, beginning with START */ msg.buffer = txbuffer; /* Transfer from this address */ msg.length = 2; /* Send two bytes following the address * then STOP */ /* Perform the transfer */ ret = I2C_TRANSFER(priv->i2c, &msg, 1); if (ret < 0) { lcderr("ERROR: I2C_TRANSFER failed: %d\n", ret); } return ret; }
void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr, uint8_t regval) { /* 8-bit data read sequence: * * Start - I2C_Write_Address - STMPE811_Reg_Address - STMPE811_Write_Data - STOP */ struct i2c_msg_s msg; uint8_t txbuffer[2]; int ret; #ifdef CONFIG_STMPE811_REGDEBUG dbg("%02x<-%02x\n", regaddr, regval); #endif /* Setup to the data to be transferred. Two bytes: The STMPE811 register * address followed by one byte of data. */ txbuffer[0] = regaddr; txbuffer[1] = regval; /* Setup 8-bit STMPE811 address write message */ msg.addr = priv->config->address; /* 7-bit address */ msg.flags = 0; /* Write transaction, beginning with START */ msg.buffer = txbuffer; /* Transfer from this address */ msg.length = 2; /* Send two byte following the address * (then STOP) */ /* Perform the transfer */ ret = I2C_TRANSFER(priv->i2c, &msg, 1); if (ret < 0) { idbg("I2C_TRANSFER failed: %d\n", ret); } }
int ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len) { struct i2c_msg_s msg[2]; uint8_t transfer_mode; int ret; /* 8-bit data read sequence: * * Start - I2C_Write_Address - Data transfer select - SSD1306_Write_Data - STOP */ /* Send the SSD1306 register address (with no STOP) */ transfer_mode = 0x40; /* Select data transfer */ msg[0].frequency = CONFIG_SSD1306_I2CFREQ; /* I2C frequency */ msg[0].addr = priv->addr; /* 7-bit address */ msg[0].flags = 0; /* Write transaction, beginning with START */ msg[0].buffer = &transfer_mode; /* Transfer mode send */ msg[0].length = 1; /* Send the one byte register address */ /* Followed by the SSD1306 write data (with no RESTART, then STOP) */ msg[1].frequency = CONFIG_SSD1306_I2CFREQ; /* I2C frequency */ msg[1].addr = priv->addr; /* 7-bit address */ msg[1].flags = I2C_M_NORESTART; /* Write transaction with no RESTART */ msg[1].buffer = data; /* Transfer from this address */ msg[1].length = len; /* Send the data, then STOP */ ret = I2C_TRANSFER(priv->i2c, msg, 2); if (ret < 0) { lcderr("ERROR: I2C_TRANSFER failed: %d\n", ret); } return ret; }
static int i2cdrvr_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; FAR struct i2c_driver_s *priv; FAR struct i2c_transfer_s *transfer; int ret; i2cvdbg("cmd=%d arg=%lu\n", cmd, arg); /* Get our private data structure */ DEBUGASSERT(filep != NULL && filep->f_inode != NULL); inode = filep->f_inode; priv = (FAR struct i2c_driver_s *)inode->i_private; DEBUGASSERT(priv); /* Get exclusive access to the I2C driver state structure */ ret = sem_wait(&priv->exclsem); if (ret < 0) { int errcode = errno; DEBUGASSERT(errcode < 0); return -errcode; } /* Process the IOCTL command */ switch (cmd) { /* Command: I2CIOC_TRANSFER * Description: Perform an I2C transfer * Argument: A reference to an instance of struct i2c_transfer_s. * Dependencies: CONFIG_I2C_DRIVER */ case I2CIOC_TRANSFER: { /* Get the reference to the i2c_transfer_s structure */ transfer = (FAR struct i2c_transfer_s *)((uintptr_t)arg); DEBUGASSERT(transfer != NULL); /* Perform the transfer */ ret = I2C_TRANSFER(priv->i2c, transfer->msgv, transfer->msgc); } break; #ifdef CONFIG_I2C_RESET /* Command: I2CIOC_RESET * Description: Perform an I2C bus reset in an attempt to break loose * stuck I2C devices. * Argument: None * Dependencies: CONFIG_I2C_DRIVER && CONFIG_I2C_RESET */ case I2CIOC_RESET: { ret = I2C_RESET(priv->i2c); } break; #endif default: ret = -ENOTTY; break; } sem_post(&priv->exclsem); return ret; }