Daily Archives: 2022-07-21

Screen: I2C to Drive RGB LEDs

Currently our V7B board has I2C interface exported, and actually we can control it through USB port.

Note: This I2C mainly is used for upgrade firmware on the usb bus, so it might be risk to use, if you send wrong data to it, it might broken firmware.

Here is the I2C API, only three commands:

#define CMD_SCREEN_I2C          0xb5
#define CMD_SCREEN_I2C_WR 0xb6
#define CMD_SCREEN_I2C_RD 0xb7

Here is the example of writing data to I2C EEPROM

        if (load_from_file(argv[2], buf, 0x2000) < 0) {
            printf("no firmware file.\n");
            return -1;
        }
        
        for (pos = 0; pos < 0x2000; pos += BLOCK_SIZE) {
            cmd[0] = EEPROM_ADDR;
            cmd[1] = BLOCK_SIZE + 2; // write register address 2byte and data 16byte.
            cmd[2] = 0;     // read eight byte.
            cmd[3] = pos >> 8;
            cmd[4] = pos;
            
            memcpy(cmd + 5, buf + pos, BLOCK_SIZE);
            ret = libusb_control_transfer(handle, 0x40, CMD_SCREEN_I2C, 0, 0, cmd, BLOCK_SIZE + 5, 200);
            // write register address and data to i2c bus.
            ret = libusb_control_transfer(handle, 0xc0, CMD_SCREEN_I2C_WR, 0, 0, cmd, 1, 200);
            
            if (pos % 0x100 == 0) {
                printf(".");
                fflush(stdout);
            }
        }

Here is the example of reading data from I2C EEPROM

        for (pos = 0; pos < 0x2000; pos += BLOCK_SIZE) {
            cmd[0] = EEPROM_ADDR;
            cmd[1] = 2;     // write register address.
            cmd[2] = BLOCK_SIZE;
            cmd[3] = pos >> 8;
            cmd[4] = pos;
            
            ret = libusb_control_transfer(handle, 0x40, CMD_SCREEN_I2C, 0, 0, cmd, 5, 200);
            // write register address to i2c bus.
            ret = libusb_control_transfer(handle, 0xc0, CMD_SCREEN_I2C_WR, 0, 0, cmd, 1, 200);
            // read from i2c bus.
            ret = libusb_control_transfer(handle, 0xc0, CMD_SCREEN_I2C_RD, 0, 0, cmd, BLOCK_SIZE + 1, 200);
            
            memcpy(buf + pos, cmd + 1, BLOCK_SIZE);
            if (pos % 0x100 == 0) {
                printf(".");
                fflush(stdout);
            }
        }

With this I2C interface, we can easy control RGB LED driver chip like AW9523 and other chips. Then it will save a lot of cost make customized board, do not need arduino and USBhub chip anymore.

To be continue…