コード例 #1
0
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;
}
コード例 #2
0
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;

}
コード例 #3
0
ファイル: i2c_driver.c プロジェクト: acassis/ros2_nuttx
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;
}