Exemplo n.º 1
0
/**
 * @brief Reads an 8-bit register from an I2C slave 
 */
uint8_t i2c_read_register(register uint8_t slaveId, register uint8_t registerAddress){
  /* loop while the bus is still busy */
	i2c_wait_while_busy();
	
	/* send I2C start signal and set write direction, also enables ACK */
	i2c_send_start();
	
	/* send the slave address and wait for the I2C bus operation to complete */
	i2c_send_byte(I2C_WRITE_ADDRESS(slaveId));
	
	/* send the register address */
	i2c_send_byte(registerAddress);
	
	/* signal a repeated start condition */
	i2c_send_repeated_start();

	/* send the read address */
	i2c_send_byte(I2C_READ_ADDRESS(slaveId));
	
	/* switch to receive mode but disable ACK because only one data byte will be read */
	i2c_enter_receive_mode_without_ack();
	
	/* read a dummy byte to drive the clock */
	i2c_read_dummy_byte();
	
	/* stop signal */
	i2c_send_stop();
	
	/* fetch the last received byte */
	register uint8_t result = I2C0->D;
	return result;
}
Exemplo n.º 2
0
int i2c_read (uint8_t chip_id, uint8_t reg_addr, uint8_t* buffer, uint16_t len)
{
	int status = 0;

	/* send chip internal register address (pointer register) */
	if (status == 0) i2c_send_start ();
	if (status == 0) status = i2c_write_byte (chip_id << 1 | I2C_WRITE_OPER);
	if (status == 0) status = i2c_write_byte (reg_addr);
	if (status == 0) i2c_send_repeated_start ();

	/* send again chip id before to switch to read mode */
	if (status == 0) status = i2c_write_byte ((chip_id << 1) | I2C_READ_OPER);
	if (status == 0) i2c_switch_to_read_operation(len > 1);

	/* read specified number of bytes */
	if (status == 0) {
		while (len > 1) {
			*buffer++ = i2c_read_byte (--len > 1);
		}
	}
	i2c_send_stop ();
	if (status == 0) *buffer++ = i2c_read_byte (false);

	return status;
}
Exemplo n.º 3
0
/**
 * @brief Reads multiple 8-bit registers from an I2C slave
 * @param[in] slaveId The slave device ID
 * @param[in] startRegisterAddress The first register address
 * @param[in] registerCount The number of registers to read; Must be greater than or equal to two.
 * @param[out] buffer The buffer to write into
 * @return 0 is successful, 1 if not
 */
static int i2c_read_registers_internal(register uint8_t slaveId, register uint8_t startRegisterAddress, register uint8_t registerCount, uint8_t *const buffer){
  if(registerCount < 2)
    return -1;
	
	/* loop while the bus is still busy */
	i2c_wait_while_busy();
	
	/* send I2C start signal and set write direction, also enables ACK */
	i2c_send_start();
	
	/* send the slave address and wait for the I2C bus operation to complete */
	i2c_send_byte(I2C_WRITE_ADDRESS(slaveId));
	
	/* send the register address */
	i2c_send_byte(startRegisterAddress);
	
	/* signal a repeated start condition */
	i2c_send_repeated_start();

	/* send the read address */
	i2c_send_byte(I2C_READ_ADDRESS(slaveId));
	
	/* switch to receive mode and assume more than one register */
	i2c_enter_receive_mode_with_ack();
	
	/* read a dummy byte to drive the clock */
	i2c_read_dummy_byte();
	
	/* for all remaining bytes, read */
	--registerCount;
	uint8_t index = 0;
	while (--registerCount > 0)
	{
		/* fetch and store value */
		register uint8_t value = I2C0->D;
		buffer[index++] = value;
		
		/* wait for completion */
		i2c_wait();
	}
	
	/* disable ACK and read second-to-last byte */
	i2c_disable_ack();
	
	/* fetch and store value */
	buffer[index++] = I2C0->D;
	
	/* wait for completion */
	i2c_wait();
	
	/* stop signal */
	i2c_send_stop();
	
	/* fetch the last received byte */
	buffer[index++] = I2C0->D; 
  
  return 0;
}