Exemple #1
0
int i2c_read(int device, unsigned char *buf, int count)
{
    int cnt = count;
    int timeout = 5;

    device &= 0xFF;

    i2c_open();

L_try_again:
    if (timeout < 0)
        goto L_timeout;

    __i2c_send_nack();    /* Master does not send ACK, slave sends it */

    __i2c_send_start();
    if (i2c_put_data( (device << 1) | I2C_READ ) < 0)
        goto device_err;

    __i2c_send_ack();    /* Master sends ACK for continue reading */

    while (cnt)
    {
        if (cnt == 1)
        {
            if (i2c_get_data(buf, 0) < 0)
                break;
        }
        else
        {
            if (i2c_get_data(buf, 1) < 0)
                break;
        }
        cnt--;
        buf++;
    }

    __i2c_send_stop();
    i2c_close();
    return count - cnt;

device_err:
    timeout--;
    __i2c_send_stop();
    goto L_try_again;

L_timeout:
    __i2c_send_stop();
    logf("Read I2C device 0x%2x failed.", device);
    i2c_close();
    return -1;
}
Exemple #2
0
int i2c_read(unsigned char device, unsigned char *buf,
	       unsigned char address, int count)
{
	int cnt = count;
	int timeout = 5;

L_try_again:

	if (timeout < 0)
		goto L_timeout;

	__i2c_send_nack();	/* Master does not send ACK, slave sends it */
	__i2c_send_start();
	if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
		goto device_werr;
#ifndef CONFIG_TOUCHSCREEN_AK4183
	if (i2c_put_data(address) < 0)
		goto address_err;
#endif

	__i2c_send_start();
	if (i2c_put_data( (device << 1) | I2C_READ ) < 0)
		goto device_rerr;
	__i2c_send_ack();	/* Master sends ACK for continue reading */
	while (cnt) {
		if (cnt == 1) {
			if (i2c_get_data(buf, 0) < 0)
				break;
		} else {
			if (i2c_get_data(buf, 1) < 0)
				break;
		}
		cnt--;
		buf++;
	}
#ifdef CONFIG_TOUCHSCREEN_AK4183
	__i2c_send_nack();
#endif
	__i2c_send_stop();
	return count - cnt;
 device_rerr:
 device_werr:
 address_err:
	timeout --;
	__i2c_send_stop();
	goto L_try_again;

L_timeout:
	__i2c_send_stop();
	printk("Read I2C device 0x%2x failed.\n", device);
	return -ENODEV;
}
Exemple #3
0
static inline void stmi2c_clear_pending_interrupts(uint32_t i2c)
{
  uint16_t SR1 = I2C_SR1(i2c);

  // Certainly do not wait for buffer interrupts:
  // -------------------------------------------
  i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);			// Disable TXE, RXNE

  // Error interrupts are handled separately:
  // ---------------------------------------

  // Clear Event interrupt conditions:
  // --------------------------------

  // Start Condition Was Generated
  if (BIT_X_IS_SET_IN_REG( I2C_SR1_SB, SR1 ) )
  {
    // SB: cleared by software when reading SR1 and writing to DR
    i2c_send_data(i2c, 0x00);
  }
  // Address Was Sent
  if (BIT_X_IS_SET_IN_REG(I2C_SR1_ADDR, SR1) )
  {
    // ADDR: Cleared by software when reading SR1 and then SR2
    uint16_t SR2 __attribute__ ((unused)) = I2C_SR2(i2c);
  }
  // Byte Transfer Finished
  if (BIT_X_IS_SET_IN_REG(I2C_SR1_BTF, SR1) )
  {
    // SB: cleared by software when reading SR1 and reading/writing to DR
    uint8_t dummy __attribute__ ((unused)) = i2c_get_data(i2c);
    i2c_send_data(i2c, 0x00);
  }

}
uchar
i2c_read (uchar dev_addr, unsigned int offset, int alen, uchar * data,
	  int len)
{
	uchar status = 0;
	unsigned int i2cFreq = CONFIG_SYS_I2C_SPEED;

	DP (puts ("i2c_read\n"));

	i2c_init (i2cFreq, 0);	/* set the i2c frequency */

	status = i2c_start ();

	if (status) {
#ifdef DEBUG_I2C
		printf ("Transaction start failed: 0x%02x\n", status);
#endif
		return status;
	}

	status = i2c_set_dev_offset (dev_addr, offset, 0, alen);	/* send the slave address + offset */
	if (status) {
#ifdef DEBUG_I2C
		printf ("Failed to set slave address & offset: 0x%02x\n",
			status);
#endif
		return status;
	}

	i2c_init (i2cFreq, 0);	/* set the i2c frequency again */

	status = i2c_start ();
	if (status) {
#ifdef DEBUG_I2C
		printf ("Transaction restart failed: 0x%02x\n", status);
#endif
		return status;
	}

	status = i2c_select_device (dev_addr, 1, 0);	/* send the slave address */
	if (status) {
#ifdef DEBUG_I2C
		printf ("Address not acknowledged: 0x%02x\n", status);
#endif
		return status;
	}

	status = i2c_get_data (data, len);
	if (status) {
#ifdef DEBUG_I2C
		printf ("Data not recieved: 0x%02x\n", status);
#endif
		return status;
	}

	return 0;
}
Exemple #5
0
static uint32_t i2c_read(uint8_t reg)
{
    //    while ((I2C_SR2(i2c) & I2C_SR2_BUSY)) {
    //    }

    i2c_send_start(I2C_PORT);

    /* Wait for master mode selected */
    while (!((I2C_SR1(I2C_PORT) & I2C_SR1_SB)
           & (I2C_SR2(I2C_PORT) & (I2C_SR2_MSL | I2C_SR2_BUSY))));

    i2c_send_7bit_address(I2C_PORT, SLAVE_ADDRESS, I2C_WRITE);

    /* Waiting for address is transferred. */
    while (!(I2C_SR1(I2C_PORT) & I2C_SR1_ADDR));

    /* Cleaning ADDR condition sequence. */
    uint32_t reg32 = I2C_SR2(I2C_PORT);
    (void) reg32; /* unused */

    /*  Common stuff ABOVE HERE     */

    i2c_send_data(I2C_PORT, reg);
    while (!(I2C_SR1(I2C_PORT) & (I2C_SR1_BTF)));

    i2c_send_start(I2C_PORT);

    /* Wait for master mode selected */
    while (!((I2C_SR1(I2C_PORT) & I2C_SR1_SB)
           & (I2C_SR2(I2C_PORT) & (I2C_SR2_MSL | I2C_SR2_BUSY))));

    i2c_send_7bit_address(I2C_PORT, SLAVE_ADDRESS, I2C_READ);

    /* Waiting for address is transferred. */
    while (!(I2C_SR1(I2C_PORT) & I2C_SR1_ADDR));

    i2c_disable_ack(I2C_PORT);

    /* Cleaning ADDR condition sequence. */
    reg32 = I2C_SR2(I2C_PORT);
    (void) reg32; /* unused */

    i2c_send_stop(I2C_PORT);

    while (!(I2C_SR1(I2C_PORT) & I2C_SR1_RxNE));
    uint32_t result = i2c_get_data(I2C_PORT);

    i2c_enable_ack(I2C_PORT);
    I2C_SR1(I2C_PORT) &= ~I2C_SR1_AF;
    return result;
}
Exemple #6
0
static int i2c_get_ack()
{
	int error=0;
	int ack;
    
	error+= i2c_set_lines(0,1);
	error+= i2c_set_lines(1,1);
	ack = i2c_get_data();
	error+= i2c_set_lines(0,1);

	if (error)
	{
		LOG(8,("I2C: get_ack - %d value:%x\n",error,ack));
	}

	return ack;
}
Exemple #7
0
static unsigned char i2c_readbyte(int ack_required)
{
	int i;
	unsigned char data=0;
    
	/*read data*/
	i2c_set_lines(0,1);
	for (i=7; i>=0; i--) 
	{
		i2c_set_lines(1,1);
		if (i2c_get_data()==1)
			data |= (1<<i);
		i2c_set_lines(0,1);
	}

	/*send acknowledge*/
	if (ack_required) i2c_send_ack();

	return data;
}
static uint32_t i2c_read(uint32_t i2c, uint8_t address, uint8_t reg)
{
	while ((I2C_SR2(i2c) & I2C_SR2_BUSY));

	i2c_start(i2c, address, I2C_WRITE);
	i2c_send_data(i2c, reg);

	while (!(I2C_SR1(i2c) & (I2C_SR1_BTF)));

	i2c_start(i2c, address, I2C_READ);

	i2c_send_stop(i2c);

	while (!(I2C_SR1(i2c) & I2C_SR1_RxNE));

	uint32_t result = i2c_get_data(i2c);

	I2C_SR1(i2c) &= ~I2C_SR1_AF;

	return result;
}
Exemple #9
0
void read_i2c(uint32_t i2c, uint8_t i2c_addr, uint8_t reg, uint8_t size,
	      uint8_t *data)
{
	int wait;
	int i;
	while (i2c_busy(i2c) == 1);
	while (i2c_is_start(i2c) == 1);
	/*Setting transfer properties*/
	i2c_set_bytes_to_transfer(i2c, 1);
	i2c_set_7bit_address(i2c, i2c_addr);
	i2c_set_write_transfer_dir(i2c);
	i2c_disable_autoend(i2c);
	/*start transfer*/
	i2c_send_start(i2c);

	wait = true;
	while (wait) {
		if (i2c_transmit_int_status(i2c)) {
			wait = false;
		}
		while (i2c_nack(i2c)); /* Some error */
	}
	i2c_send_data(i2c, reg);

	while (i2c_is_start(i2c) == 1);
	/*Setting transfer properties*/
	i2c_set_bytes_to_transfer(i2c, size);
	i2c_set_7bit_address(i2c, i2c_addr);
	i2c_set_read_transfer_dir(i2c);
	i2c_enable_autoend(i2c);
	/*start transfer*/
	i2c_send_start(i2c);

	for (i = 0; i < size; i++) {
		while (i2c_received_data(i2c) == 0);
		data[i] = i2c_get_data(i2c);
	}
}
Exemple #10
0
// Doc ID 13902 Rev 11 p 712/1072
// Transfer Sequence Diagram for Master Receiver for N>2
static inline enum STMI2CSubTransactionStatus stmi2c_readmany(uint32_t i2c, struct i2c_periph *periph, struct i2c_transaction *trans)
{
  uint16_t SR1 = I2C_SR1(i2c);

  // Start Condition Was Just Generated
  if (BIT_X_IS_SET_IN_REG( I2C_SR1_SB, SR1 ) )
  {
    i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
    // The first data byte will be acked in read many so the slave knows it should send more
    i2c_nack_current(i2c);
    i2c_enable_ack(i2c);
    // Clear the SB flag
    i2c_send_data(i2c, trans->slave_addr | 0x01);

    // Document the current Status
    periph->status = I2CAddrRdSent;
  }
  // Address Was Sent
  else if (BIT_X_IS_SET_IN_REG(I2C_SR1_ADDR, SR1) )
  {
    periph->idx_buf = 0;

    // Enable RXNE: receive an interrupt any time a byte is available
    // only enable if MORE than 3 bytes need to be read
    if (periph->idx_buf < (trans->len_r - 3))
    {
      i2c_enable_interrupt(i2c, I2C_CR2_ITBUFEN);
    }

    // ACK is still on to get more DATA
    // Read SR2 to clear the ADDR (next byte will start arriving)
    uint16_t SR2 __attribute__ ((unused)) = I2C_SR2(i2c);

    // Document the current Status
    periph->status = I2CReadingByte;
  }
  // one or more bytes are available AND we were interested in Buffer interrupts
  else if ( (BIT_X_IS_SET_IN_REG(I2C_SR1_RxNE, SR1) ) && (BIT_X_IS_SET_IN_REG(I2C_CR2_ITBUFEN, I2C_CR2(i2c)))  )
  {
    // read byte until 3 bytes remain to be read (e.g. len_r = 6, -> idx=3 means idx 3,4,5 = 3 remain to be read
    if (periph->idx_buf < (trans->len_r - 3))
    {
      trans->buf[periph->idx_buf] = I2C_DR(i2c);
      periph->idx_buf ++;
    }
    // from : 3bytes -> last byte: do nothing
    //
    // finally: this was the last byte
    else if (periph->idx_buf >= (trans->len_r - 1))
    {
      i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);

      // Last Value
      trans->buf[periph->idx_buf] = i2c_get_data(i2c);
      periph->idx_buf ++;

      // We got all the results
      trans->status = I2CTransSuccess;

      return STMI2C_SubTra_Ready_StopRequested;
    }

    // Check for end of transaction: start waiting for BTF instead of RXNE
    if (periph->idx_buf < (trans->len_r - 3))
    {
      i2c_enable_interrupt(i2c, I2C_CR2_ITBUFEN);
    }
    else // idx >= len-3: there are 3 bytes to be read
    {
      // We want to halt I2C to have sufficient time to clear ACK, so:
      // Stop listening to RXNE as it will be triggered infinitely since we did not empty the buffer
      // on the next (second in buffer) received byte BTF will be set (buffer full and I2C halted)
      i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
    }
  }
  // Buffer is full while this was not a RXNE interrupt
  else if (BIT_X_IS_SET_IN_REG(I2C_SR1_BTF, SR1) )
  {
    // Now the shift register and data register contain data(n-2) and data(n-1)
    // And I2C is halted so we have time

    // --- Make absolutely sure the next 2 I2C actions are performed with no delay
    __I2C_REG_CRITICAL_ZONE_START;

    // First we clear the ACK while the SCL is held low by BTF
    i2c_disable_ack(i2c);

    // Now that ACK is cleared we read one byte: instantly the last byte is being clocked in...
    trans->buf[periph->idx_buf] = i2c_get_data(i2c);
    periph->idx_buf ++;

    // Now the last byte is being clocked. Stop in MUST be set BEFORE the transfer of the last byte is complete
    PPRZ_I2C_SEND_STOP(i2c);

    __I2C_REG_CRITICAL_ZONE_STOP;


    // --- end of critical zone -----------

    // Document the current Status
    periph->status = I2CStopRequested;

    // read the byte2 we had in the buffer (BTF means 2 bytes available)
    trans->buf[periph->idx_buf] = i2c_get_data(i2c);
    periph->idx_buf ++;

    // Ask for an interrupt to read the last byte (which is normally still busy now)
    // The last byte will be received with RXNE
    i2c_enable_interrupt(i2c, I2C_CR2_ITBUFEN);
  }
  else // Event Logic Error
  {
    return STMI2C_SubTra_Error;
  }

  return STMI2C_SubTra_Busy;
}