Skip to main content
Graduate II
February 2, 2024
Solved

Accessing 16 Bit Registers on I2C

  • February 2, 2024
  • 1 reply
  • 5757 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)

    1 reply

    Graduate II
    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)

    Visitor 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 

    Graduate II
    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