Пример #1
0
/* busy waiting for byte data transfer completion */
static int
motoi2c_busy_wait(struct motoi2c_softc *sc, uint8_t cr)
{
	uint8_t sr;
	u_int timo;
	int error = 0;

	timo = 1000;
	while (((sr = I2C_READ(I2CSR)) & SR_MIF) == 0 && --timo)
		DELAY(10);

	if (timo == 0) {
		DPRINTF(("%s: timeout (sr=%#x, cr=%#x)\n",
		    __func__, sr, I2C_READ(I2CCR)));
		error = ETIMEDOUT;
	}
	/*
	 * RXAK is only valid when transmitting.
	 */
	if ((cr & CR_MTX) && (sr & SR_RXAK)) {
		DPRINTF(("%s: missing rx ack (%#x): spin=%u\n",
		    __func__, sr, 1000 - timo));
		error = EIO;
	}
	I2C_WRITE(I2CSR, 0);
	return error;
}
Пример #2
0
/**
  * @brief  Reads a block of data from the EEPROM.
  * @param  pBuffer : pointer to the buffer that receives the data read
  *   from the EEPROM.
  * @param  ReadAddr : EEPROM's internal address to read from.
  * @param  NumByteToRead : number of bytes to read from the EEPROM.
  * @retval None
  */
void I2C_EE_BufferRead(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead)
{
  I2C_START();
  I2C_SEND_DATA(I2C_EEPROM_ADDRESS|EE_CMD_WRITE);
  I2C_WAIT_ACK();
#ifdef EE_M24C08
  I2C_SEND_DATA(ReadAddr);
  I2C_WAIT_ACK();
#else
  I2C_SEND_DATA((uint8_t)((ReadAddr & 0xFF00) >> 8));
  I2C_WAIT_ACK();
  I2C_SEND_DATA((uint8_t)(ReadAddr & 0x00FF));
  I2C_WAIT_ACK();
#endif
	
  I2C_START();
  I2C_SEND_DATA(I2C_EEPROM_ADDRESS|EE_CMD_READ);
  I2C_WAIT_ACK();
  while (NumByteToRead) {
    if (NumByteToRead == 1) {
      *pBuffer =I2C_READ();
      I2C_NO_ACK();
      I2C_STOP();
    }
    else {
      *pBuffer =I2C_READ();
      I2C_ACK();
      pBuffer++;
    }
    NumByteToRead--;
  }
}
Пример #3
0
void ms5611_polling(){
  
  static __xdata u8 * __xdata next_buf = pressure_data;
  
  if(ms5611_capture){
    ms5611_capture = FALSE;
    
    send_command(0x00);
    i2c0_read_write(I2C_READ(I2C_ADDRESS_RW), next_buf, 3);
    next_buf += 3;
    
    switch(capture_cycle++){
      case 0:
      case 2:
        send_command(0x52); // Read ADC2 (temperature) with OSR=512
        break;
      case 3: // Rotate
        capture_cycle = 0;
        data_hub_assign_page(make_packet);
        next_buf = pressure_data;
      case 1:
        send_command(0x42); // Read ADC1 (pressure) with OSR=512
        break; 
    }
  }
}
Пример #4
0
static int max1704x_getreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr,
                             FAR uint16_t *regval)
{
  uint8_t buffer[2];
  int ret;

  /* Set the I2C address and address size */

  I2C_SETADDRESS(priv->i2c, priv->addr, 7);

  /* Write the register address */

  ret = I2C_WRITE(priv->i2c, &regaddr, 1);
  if (ret < 0)
    {
      batdbg("I2C_WRITE failed: %d\n", ret);
      return ret;
    }

  /* Restart and read 16-bits from the register */

  ret = I2C_READ(priv->i2c, buffer, 2);
  if (ret < 0)
    {
      batdbg("I2C_READ failed: %d\n", ret);
      return ret;
    }

  /* Return the 16-bit value */

  return (uint16_t)buffer[0] << 8 | (uint16_t)buffer[1];
  return OK;
}
Пример #5
0
/**
 * prcmu_abb_read() - Read register value(s) from the ABB.
 * @slave:	The I2C slave address.
 * @reg:	The (start) register address.
 * @value:	The read out value(s).
 * @size:	The number of registers to read.
 *
 * Reads register value(s) from the ABB.
 * @size has to be 1 for the current firmware version.
 */
int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
{
	int r;

	if (size != 1)
		return -EINVAL;

	r = mutex_lock_interruptible(&mb5_transfer.lock);
	if (r)
		return r;

	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
		cpu_relax();

	writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP);
	writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
	writeb(reg, REQ_MB5_I2C_REG);

	writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
	if (!wait_for_completion_timeout(&mb5_transfer.work,
			msecs_to_jiffies(500))) {
		pr_err("prcmu: prcmu_abb_read timed out.\n");
		r = -EIO;
		goto unlock_and_return;
	}
	r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
	if (!r)
		*value = mb5_transfer.ack.value;

unlock_and_return:
	mutex_unlock(&mb5_transfer.lock);
	return r;
}
Пример #6
0
static int bq2425x_getreg8(FAR struct bq2425x_dev_s *priv, uint8_t regaddr,
                           FAR uint8_t *regval)
{
  uint8_t val;
  int ret;

  /* Set the I2C address and address size */

  I2C_SETADDRESS(priv->i2c, priv->addr, 7);

  /* Write the register address */

  ret = I2C_WRITE(priv->i2c, &regaddr, 1);
  if (ret < 0)
    {
      batdbg("I2C_WRITE failed: %d\n", ret);
      return ret;
    }

  /* Restart and read 8-bits from the register */

  ret = I2C_READ(priv->i2c, &val, 1);
  if (ret < 0)
    {
      batdbg("I2C_READ failed: %d\n", ret);
      return ret;
    }

  /* Copy 8-bit value to be returned */

  *regval = val;
  return OK;
}
Пример #7
0
static uint8_t ov2640_getreg(FAR struct i2c_dev_s *i2c, uint8_t regaddr)
{
  uint8_t regval;
  int ret;

  /* Write the register address */

  ret = I2C_WRITE(i2c, &regaddr, 1);
  if (ret < 0)
    {
      gdbg("ERROR: I2C_WRITE failed: %d\n", ret);
      return 0;
    }

  /* Restart and read 8-bits from the register */

  ret = I2C_READ(i2c, &regval, 1);
  if (ret < 0)
    {
      gdbg("ERROR: I2C_READ failed: %d\n", ret);
      return 0;
    }
#ifdef CONFIG_OV2640_REGDEBUG
  else
    {
      dbg("%02x -> %02x\n", regaddr, regval);
    }
#endif

  return regval;
}
Пример #8
0
static int lm75_readb16(FAR struct lm75_dev_s *priv, uint8_t regaddr,
                        FAR b16_t *regvalue)
{
  uint8_t buffer[2];
  int ret;

  /* Write the register address */

  I2C_SETADDRESS(priv->i2c, priv->addr, 7);
  ret = I2C_WRITE(priv->i2c, &regaddr, 1);
  if (ret < 0)
    {
      sndbg("I2C_WRITE failed: %d\n", ret);
      return ret;
    }

  /* Restart and read 16-bits from the register (discarding 7) */

  ret = I2C_READ(priv->i2c, buffer, 2);
  if (ret < 0)
    {
      sndbg("I2C_READ failed: %d\n", ret);
      return ret;
    }

  /* Data format is:  TTTTTTTT Txxxxxxx where TTTTTTTTT is a nine-bit,
   * signed temperature value with LSB = 0.5 degrees centigrade.  So the
   * raw data is b8_t
   */

  *regvalue = b8tob16((b8_t)buffer[0] << 8 | (b8_t)buffer[1]);
  sndbg("addr: %02x value: %08x ret: %d\n", regaddr, *regvalue, ret);
  return OK;
}
Пример #9
0
static void headset_on_work(struct work_struct *work)
{
	unsigned char reg_value;

//	I2C_WRITE(MAX9879_INPUTMODE_CTRL,0x70); // dINA = 1(mono), dINB = 1(mono)

	I2C_READ(MAX9879_OUTPUTMODE_CTRL,&reg_value);

	if(reg_value & 0x80)
	{
		reg_value &= 0x7F;
		I2C_WRITE(MAX9879_OUTPUTMODE_CTRL, reg_value);
		I2C_WRITE(MAX9879_SPKVOL_CTRL,0x0); // MAX 0x1F : 0dB
		I2C_WRITE(MAX9879_LEFT_HPHVOL_CTRL,0x0); // MAX 0x1F : 0dB
		I2C_WRITE(MAX9879_RIGHT_HPHVOL_CTRL,0x0); // MAX 0x1F : 0dB

	}

//	msleep(1000);
//	I2C_WRITE(MAX9879_LEFT_HPHVOL_CTRL,0x17); // MAX 0x1F : 0dB
//	I2C_WRITE(MAX9879_RIGHT_HPHVOL_CTRL,0x17); // MAX 0x1F : 0dB

#if 0
	if(is_incall == 0)
	{
		msleep(6000);
	} else {
		msleep(300);
	}
#else
	msleep(600);
#endif
	max9879_i2c_headset_onoff(true);
}
Пример #10
0
uint8 HalI2CReadSingle(uint8 addr)
{
    uint8 ret = 0xFF;

    if (i2cMstStrt(0) != mstAddrAckW) {
        I2C_STOP();
        return ret;
    }

    I2C_WRITE(addr);

    if (I2CSTAT != mstDataAckW) {
        I2C_STOP();
        return ret;
    }

    if (i2cMstRepeatedStrt(I2C_MST_RD_BIT) != mstAddrAckR) {
        I2C_STOP();
        return ret;
    }

    I2C_SET_NACK();

    // read a byte from the I2C interface
    I2C_READ(ret);

    if (I2CSTAT != mstDataNackR) {
        ret = 0xFF;
    }

    I2C_STOP();
    return ret;
}
Пример #11
0
static Status tml_Rx(uint8_t *pBuff, uint16_t buffLen, uint16_t *pBytesRead) {
    if(I2C_READ(pBuff, 3) == kStatus_Success)
    {
    	if ((pBuff[2] + 3) <= buffLen)
    	{
			if (pBuff[2] > 0)
			{
				if(I2C_READ(&pBuff[3], pBuff[2]) == kStatus_Success)
				{
					*pBytesRead = pBuff[2] + 3;
				}
				else return ERROR;
			} else
			{
				*pBytesRead = 3;
			}
    	}
		else return ERROR;
   }
    else return ERROR;

	return SUCCESS;
}
Пример #12
0
void ms5611_init(){
  { // Read Coefficient 1-6 from PROM
    u8 i, cmd;
    __xdata u8 *buf;
    for(i = 0, cmd = 0xA2, buf = &(pressure_data[12]); 
        i < 6; 
        ++i, cmd += 2, buf += 2){
      send_command(cmd);
      i2c0_read_write(I2C_READ(I2C_ADDRESS_RW), buf, 2);
    }
  }
  
  send_command(0x42); // Read ADC1 (pressure) with OSR=512
  capture_cycle = 0;
  ms5611_capture = FALSE;
}
Пример #13
0
uint8_t I2C_read_volume()
{
	uint8_t volume ;
  I2C_START();
  I2C_SEND_DATA(I2C_CAT5137_ADDRESS|EE_CMD_WRITE);
  I2C_WAIT_ACK();
  I2C_SEND_DATA(0);
  I2C_WAIT_ACK();
  I2C_START();
  I2C_SEND_DATA(I2C_CAT5137_ADDRESS|EE_CMD_READ);
  I2C_WAIT_ACK();
  volume = I2C_READ();
  I2C_NO_ACK();
  I2C_STOP();
	return volume ;
}
Пример #14
0
/* Receive data from switch to SVC */
inline int i2c_switch_receive_msg(uint8_t *buf, unsigned int size)
{
    int ret;

    i2c_select_device(I2C_ADDR_SWITCH);

    ret = I2C_READ(sw_exp_dev, buf, size);
    if (ret) {
        dbg_error("%s(): Error %d\n", __func__, ret);
        return ERROR;
    }

    dbg_verbose("%s()\n", __func__);
    dbg_print_buf(DBG_VERBOSE, buf, size);

    return 0;
}
Пример #15
0
/**************************************************************************************************
 * @fn          HalI2CRead
 *
 * @brief       Read from the I2C bus as a Master.
 *
 * input parameters
 *
 * @param       len - Number of bytes to read.
 * @param       pBuf - Pointer to the data buffer to put read bytes.
 *
 * output parameters
 *
 * None.
 *
 * @return      The number of bytes successfully read.
 */
uint8 HalI2CRead(uint8 len, uint8 *pBuf)
{
  uint8 cnt = 0;

  if (i2cMstStrt(I2C_MST_RD_BIT) != mstAddrAckR)
  {
    len = 0;
  }

  // All bytes are ACK'd except for the last one which is NACK'd. If only
  // 1 byte is being read, a single NACK will be sent. Thus, we only want
  // to enable ACK if more than 1 byte is going to be read.
  if (len > 1)
  {
    I2C_SET_ACK();
  }

  while (len > 0)
  {
    // slave devices require NACK to be sent after reading last byte
    if (len == 1)
    {
      I2C_SET_NACK();
    }

    // read a byte from the I2C interface
    I2C_READ(*pBuf++);
    cnt++;
    len--;

    if (I2CSTAT != mstDataAckR)
    {
      if (I2CSTAT != mstDataNackR)
      {
        // something went wrong, so don't count last byte
        cnt--;
      }
      break;
    }
  }
  I2C_STOP();

  return cnt;
}
Пример #16
0
static int mb7040_readrange(FAR struct mb7040_dev_s *priv,
                            FAR uint16_t *range)
{
  uint8_t buffer[2];
  int ret;

  /* Read two bytes */

  I2C_SETADDRESS(priv->i2c, priv->addr, 7);
  ret = I2C_READ(priv->i2c, buffer, sizeof(buffer));
  if (ret < 0)
    {
      sndbg("I2C_READ failed: %d\n", ret);
      return ret;
    }

  *range = (uint16_t)buffer[0] << 8 | (uint16_t)buffer[1];
  sndbg("range: %04x ret: %d\n", *range, ret);
  return ret;
}
Пример #17
0
static int lm75_readconf(FAR struct lm75_dev_s *priv, FAR uint8_t *conf)
{
  uint8_t buffer;
  int ret;

  /* Write the configuration register address */

  I2C_SETADDRESS(priv->i2c, priv->addr, 7);

  buffer = LM75_CONF_REG;
  ret = I2C_WRITE(priv->i2c, &buffer, 1);
  if (ret < 0)
    {
      sndbg("I2C_WRITE failed: %d\n", ret);
      return ret;
    }

  /* Restart and read 8-bits from the register */

  ret = I2C_READ(priv->i2c, conf, 1);
  sndbg("conf: %02x ret: %d\n", *conf, ret);
  return ret;
}
Пример #18
0
void i2c_read(unsigned char dev, unsigned int addr, int alen, unsigned char *data, int len)
{
	I2C_READ(dev, addr, alen, data, len);
}
Пример #19
0
int
motoi2c_exec(void *v, i2c_op_t op, i2c_addr_t addr,
	const void *cmdbuf, size_t cmdlen,
	void *databuf, size_t datalen,
	int flags)
{
	struct motoi2c_softc * const sc = v;
	uint8_t sr;
	uint8_t cr;
	int error;

	sr = I2C_READ(I2CSR);
	cr = I2C_READ(I2CCR);

#if 0
	DPRINTF(("%s(%#x,%#x,%p,%zu,%p,%zu,%#x): sr=%#x cr=%#x\n",
	    __func__, op, addr, cmdbuf, cmdlen, databuf, datalen, flags,
	    sr, cr));
#endif

	if ((cr & CR_MSTA) == 0 && (sr & SR_MBB) != 0) {
		/* wait for bus becoming available */
		u_int timo = 100;
		do {
			DELAY(10);
		} while (--timo > 0 && ((sr = I2C_READ(I2CSR)) & SR_MBB) != 0);

		if (timo == 0) {
			DPRINTF(("%s: bus is busy (%#x)\n", __func__, sr));
			return ETIMEDOUT;
		}
	}

	/* reset interrupt and arbitration-lost flags (all others are RO) */
	I2C_WRITE(I2CSR, 0);
	sr = I2C_READ(I2CSR);

	/*
	 * Generate start (or restart) condition
	 */
	/* CR_RTSA is write-only and transitory */
	uint8_t rsta = (cr & CR_MSTA ? CR_RSTA : 0);
	cr = CR_MEN | CR_MTX | CR_MSTA;
	I2C_WRITE(I2CCR, cr | rsta);

	DPRINTF(("%s: started: sr=%#x cr=%#x/%#x\n",
	    __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR)));

	sr = I2C_READ(I2CSR);
	if (sr & SR_MAL) {
		DPRINTF(("%s: lost bus: sr=%#x cr=%#x/%#x\n",
		    __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR)));
		I2C_WRITE(I2CCR, 0);
		DELAY(10);
		I2C_WRITE(I2CCR, CR_MEN | CR_MTX | CR_MSTA);
		DELAY(10);
		sr = I2C_READ(I2CSR);
		if (sr & SR_MAL) {
			error = EBUSY;
			goto out;
		}
		DPRINTF(("%s: reacquired bus: sr=%#x cr=%#x/%#x\n",
		    __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR)));
	}

	/* send target address and transfer direction */
	uint8_t addr_byte = (addr << 1)
	    | (cmdlen == 0 && I2C_OP_READ_P(op) ? 1 : 0);
	I2C_WRITE(I2CDR, addr_byte);

	error = motoi2c_busy_wait(sc, cr);
	if (error) {
		DPRINTF(("%s: error sending address: %d\n", __func__, error));
		if (error == EIO)
			error = ENXIO;
		goto out;
	}

	const uint8_t *cmdptr = cmdbuf;
	for (size_t i = 0; i < cmdlen; i++) {
		I2C_WRITE(I2CDR, *cmdptr++);

		error = motoi2c_busy_wait(sc, cr);
		if (error) {
			DPRINTF(("%s: error sending cmd byte %zu (cr=%#x/%#x):"
			    " %d\n", __func__, i, I2C_READ(I2CCR), cr, error));
			goto out;
		}
	}

	if (cmdlen > 0 && I2C_OP_READ_P(op)) {
		KASSERT(cr & CR_MTX);
		KASSERT((cr & CR_TXAK) == 0);
		I2C_WRITE(I2CCR, cr | CR_RSTA);
#if 0
		DPRINTF(("%s: restarted(read): sr=%#x cr=%#x(%#x)\n",
		    __func__, I2C_READ(I2CSR), cr | CR_RSTA, I2C_READ(I2CCR)));
#endif

		/* send target address and read transfer direction */
		addr_byte |= 1;
		I2C_WRITE(I2CDR, addr_byte);

		error = motoi2c_busy_wait(sc, cr);
		if (error) {
			if (error == EIO)
				error = ENXIO;
			goto out;
		}
	}

	if (I2C_OP_READ_P(op)) {
		uint8_t *dataptr = databuf;
		cr &= ~CR_MTX;		/* clear transmit flags */
		if (datalen <= 1)
			cr |= CR_TXAK;
		I2C_WRITE(I2CCR, cr);
		DELAY(10);
		(void)I2C_READ(I2CDR);		/* dummy read */
		for (size_t i = 0; i < datalen; i++) {
			/*
			 * If a master receiver wants to terminate a data
			 * transfer, it must inform the slave transmitter by
			 * not acknowledging the last byte of data (by setting
			 * the transmit acknowledge bit (I2CCR[TXAK])) before
			 * reading the next-to-last byte of data. 
			 */
			error = motoi2c_busy_wait(sc, cr);
			if (error) {
				DPRINTF(("%s: error reading byte %zu: %d\n",
				    __func__, i, error));
				goto out;
			}
			if (i == datalen - 2) {
				cr |= CR_TXAK;
				I2C_WRITE(I2CCR, cr);
			} else if (i == datalen - 1 && I2C_OP_STOP_P(op)) {
				cr = CR_MEN;
				I2C_WRITE(I2CCR, cr);
			}
			*dataptr++ = I2C_READ(I2CDR);
		}
		if (datalen == 0) {
			if (I2C_OP_STOP_P(op)) {
				cr = CR_MEN;
				I2C_WRITE(I2CCR, cr);
			}
			(void)I2C_READ(I2CDR);	/* dummy read */
			error = motoi2c_busy_wait(sc, cr);
			if (error) {
				DPRINTF(("%s: error reading dummy last byte:"
				    "%d\n", __func__, error));
				goto out;
			}
		}
	} else {
		const uint8_t *dataptr = databuf;
		for (size_t i = 0; i < datalen; i++) {
			I2C_WRITE(I2CDR, *dataptr++);
			error = motoi2c_busy_wait(sc, cr);
			if (error) {
				DPRINTF(("%s: error sending data byte %zu:"
				    " %d\n", __func__, i, error));
				goto out;
			}
		}
	}

 out:
	/*
	 * If we encountered an error condition or caller wants a STOP,
	 * send a STOP.
	 */
	if (error || (cr & CR_TXAK) || ((cr & CR_MSTA) && I2C_OP_STOP_P(op))) {
		cr = CR_MEN;
		I2C_WRITE(I2CCR, cr);
		DPRINTF(("%s: stopping: cr=%#x/%#x\n", __func__,
		    cr, I2C_READ(I2CCR)));
	}

	DPRINTF(("%s: exit sr=%#x cr=%#x: %d\n", __func__,
	    I2C_READ(I2CSR), I2C_READ(I2CCR), error));

	return error;
}