Monthly Archives: July 2022

Screen: Special Command

The screen has some special commands which can be used to control its brightness and flip the screen, but because the command is not compatible for all type of screen, so test it before use it. Here is a reference for use such command.

For fbusb driver, we have a file named command in /sys folder, we can use it to send the command.

# turn off backlight
echo -e '\x00\x51\x02\x00\x00\x00\x00\x00' > `find /sys/devices/platform/ -name command`
# set backlight brightness to max
echo -e '\x00\x51\x02\x00\x00\x00\xff\x00' > `find /sys/devices/platform/ -name command`
# set backlight brightness to 128(half)
echo -e '\x00\x51\x02\x00\x00\x00\x80\x00' > `find /sys/devices/platform/ -name command`

Here is an example of libusb.

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#include <libusb-1.0/libusb.h>

static libusb_context *context = NULL;
static libusb_device_handle *handle = NULL;

unsigned char cmd_rotate[] = {0x00, 0x36, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char cmd_backlight[] = {0x00, 0x51, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};

int main(int argc, char *argv[])
{   
    if (argc != 3) {
        printf("usage: send_cmd [cmd: m|b] [param]\n");
        printf("example: mirror by axis x,y [0,1,2,3]\n\tsend_cmd m 1\n");
        printf("example: set backlight [0~255]\n\tsend_cmd b 120\n");
        return 0;
    }
    
    libusb_init(&context);
    handle = libusb_open_device_with_vid_pid(context, 0xc872, 0x1004);
    if (handle == NULL) {
        printf("no device.\n");
        return -1;
    }

    libusb_claim_interface(handle, 0);
    libusb_set_interface_alt_setting(handle, 0, 0);
    
    switch (argv[1][0]) {
    case 'm':
        cmd_rotate[6] = atoi(argv[2]);
        libusb_control_transfer(handle, 0x40, 0xb0, 0, 0, cmd_rotate, 8, 100);
        break;
        
    case 'b':
        cmd_backlight[6] = atoi(argv[2]);
        libusb_control_transfer(handle, 0x40, 0xb0, 0, 0, cmd_backlight, 8, 100);
        break;
        
    default:
        printf("command is not supported.");
        break;
    }
        
    libusb_release_interface(handle, 0);
    libusb_close(handle);
    libusb_exit(context);
    return 0;
}

Also please check https://vocore.io/screen.html, the v2scrctl source code for libusb.

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…

Screen: 7inch ready

After months hard work, the 7inch(6.8in exactly) screen is ready in time. 🙂

This screen is pretty special, because the screen main design target is for real car but not like our current 4inch/5inch screen for consumer usage. So it can stand even worse environment like hot area over 65C.

Here is its shape: