Skip to main content
ZExpo.1
Associate III
February 2, 2024
Solved

Accessing 16 Bit Registers on I2C

  • February 2, 2024
  • 6 replies
  • 5801 views

What is the function of accessing 16 Bit Resisters available on VL6180 Controller?

This topic has been closed for replies.
Best answer by Tesla DeLorean

The I2C HAL API should allow you to define 8 or 16-bit wide addressing, and you can read multiple bytes. Registers in slaves typically auto-increment, such that you read 16-bit values as consecutive bytes, and recombine them, often in big-endian form

uint16_t ublox_ReadLength(void)
{
 uint8_t data[2];
 HAL_StatusTypeDef status = HAL_I2C_Mem_Read(&I2CHandle, (0x42 << 1), 0xFD, 1, data, sizeof(data), 100);
 if (status != HAL_OK)
 printf("ublox_ReadLength failed %d %08X\n", status, I2CHandle.ErrorCode);
 return(((uint16_t)data[0] << 8) + (uint16_t)data[1]); // Big Endian
}

The 0xFD register in this case being 1-byte (8-bit) and the data content 2-bytes (16-bit)

6 replies

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
February 2, 2024

The I2C HAL API should allow you to define 8 or 16-bit wide addressing, and you can read multiple bytes. Registers in slaves typically auto-increment, such that you read 16-bit values as consecutive bytes, and recombine them, often in big-endian form

uint16_t ublox_ReadLength(void)
{
 uint8_t data[2];
 HAL_StatusTypeDef status = HAL_I2C_Mem_Read(&I2CHandle, (0x42 << 1), 0xFD, 1, data, sizeof(data), 100);
 if (status != HAL_OK)
 printf("ublox_ReadLength failed %d %08X\n", status, I2CHandle.ErrorCode);
 return(((uint16_t)data[0] << 8) + (uint16_t)data[1]); // Big Endian
}

The 0xFD register in this case being 1-byte (8-bit) and the data content 2-bytes (16-bit)

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Associate II
March 9, 2024

i also have problem with reserver address 0x78 
am dealing with i2c eeprom 
the 7 bit address 0x78 in arduino need to be extracted from the 10 bit address 
using this part 
void writeLexChip(uint16_t TenBits_slave_address, uint8_t firstRegisterByte, uint8_t secondRegisterByte, uint8_t thirdRegisterByte, uint8_t *contentBuffer, uint16_t writeSize) {
ChipOn();
uint16_t slave_address_LSB = TenBits_slave_address & 0x0FF;
uint16_t slave_address_MSB = TenBits_slave_address & 0x300;
slave_address_MSB = slave_address_MSB >> 8;
uint8_t SevenBits_compat_address = 0x78 | slave_address_MSB;
contentBuffer[0] = slave_address_LSB;
contentBuffer[1] = firstRegisterByte;
contentBuffer[2] = secondRegisterByte;
contentBuffer[3] = thirdRegisterByte;
Wire.beginTransmission(SevenBits_compat_address);
Wire.write(contentBuffer, 4 + writeSize);
Wire.endTransmission(true);
Serial.println(F("Write OK"));
ChipOff();
}

now in stm32 nucleo f446re 
and i was very very very happy when i bought it 
thinking that it is very strong than arduino uno 
and after trying every line in the i2c hal 
it cant even show me the i2c eeprom address on i2c scanning
even the i2c scanners on the stm32 cube ide 
cannot deal with 10 bit devices 
when the uno and esp8266 can 
can any one help me 
and sorry for my bad english 

Tesla DeLorean
Guru
March 10, 2024

The STM32 wants the 7-bit address in the high order bits, ie 0x78 << 1 is 0xF0

ie Binary pattern 11110xxY xxxxxxxx where x represents the 10-bit address, and Y is the read/write bit

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..