Daily Archives: 2023-08-08

Screen: I2C to Drive RGB LEDs 2

More example code to use I2C on VoCore Screen driver board. These i2c function should be easier to understand and use.

int v2s_i2c_read_reg16(uint8_t addr, uint16_t reg, uint8_t *d, uint8_t size)
{
    uint8_t buf[64] = {0};
    int r;

    if (size > 58)
        return -1;         // required data is too much.

    buf[0] = addr;         // i2c device address
    buf[1] = sizeof(reg);  // write 2 bytes for register.
    buf[2] = size;         // read data size.
    buf[3] = reg >> 8;     // i2c device register high byte.
    buf[4] = reg & 0xff;   // i2c device register low byte.

    // send data to device i2c buffer.
    r = libusb_control_transfer(h, 0x40, 0xb5, 0, 0, buf, 5, 100);
    if (r < 0)
        return r;

    // trigger write to device, must send same device address.
    r = libusb_control_transfer(h, 0xc0, 0xb6, 0, 0, buf, 1, 100);
    if (r < 0)
        return r;

    // trigger read from device, first byte need to be the address.
    r = libusb_control_transfer(h, 0xc0, 0xb7, 0, 0, buf, size + 1, 100);
    if (r < 0)
        return r;

    memcpy(d, buf + 1, size);
    return size;
}

int v2s_i2c_write_reg16(uint8_t addr, uint8_t reg, uint8_t *d, uint8_t size)
{
    uint8_t buf[64] = {0};
    int r;

    if (size > 58)
        return -1;         // required data is too much.

    buf[0] = addr;
    buf[1] = sizeof(reg) + size;  // write 2 bytes for register and rest for data.
    buf[2] = 0;            // read data size.
    buf[3] = reg >> 8;     // i2c device register high byte.
    buf[4] = reg & 0xff;   // i2c device register low byte.

    memcpy(buf + 5, d, size);

    // send data to device i2c buffer.
    r = libusb_control_transfer(h, 0x40, 0xb5, 0, 0, buf, 5 + size, 100);
    if (r < 0)
        return r;

    // trigger write to device, first byte need to be the address.
    r = libusb_control_transfer(h, 0xc0, 0xb6, 0, 0, buf, 1, 100);
    if (r < 0)
        return r;

    return size;
}