Warning The information on this page hasn't been updated for two years. It is very likely that things don't work like this any longer.
This is an old revision of the document!
LG ACB8300
The LG ACB8300 is a cheap monitor calibration utility. It is designed for LG monitors and is currently only supported by LG's True Color Pro software.
I bought such a device, even though I don't have a LG display. My initial thought was that the device was just another rebranded colorimeter - but it turned out it was wrong.
This page describes the USB protocol as well as the work towards integrating it into Argyll CMS.
Debugging the LG_ACB8300.dll
I traced parts of the LG_ACB8300.dll with OllyDBG. I built a small C wrapper around the library in order to have access to the funtions and their parameters. The wrapper simply loads the DLL entry points and calls DeviceOpen, Get_ADC, Get_XYZ, etc. in order to reverse engineer the functionality.
Inside the Get_XYZ function, a lot of floating point magic is going on. After reversing all the floating point assembly, it turns out that the conversion from ADC to XYZ is performing as follows:
- Read ADC value from device
- Do an offset correction (can be read from calibration)
- Apply a correction matrix (can be read from calibration)
- Do an offset correction (can be read from calibration)
- Apply a monitor correction matrix
The monitor correction matrix is hardcoded in the DLL. The SetMonitorType() function simply loads a different matrix into memory.
The data section contains 7 different monitor types. Monitor Type 1 is a simple unity matrix.
For my DLL, the memory locations are:
| Monitor Type | Location |
|---|---|
| 0 | 0x1000c150 |
| 1 | 0x1000c198 |
| 2 | 0x1000c1e0 |
| 3 | 0x1000c228 |
| 4 | 0x1000c108 |
| 5 | 0x1000c030 |
| 6 | 0x1000c0c0 |
The next 9 double numbers at the memory locations define the correction matrices. They are in row-column order.
Hacking the USB protocol
The USB protocol consists of input reports and output reports, with a fixed length of 43 bytes. The host speaks first, the device responds (most of the time).
Initialisation
Send: 0x01
Response: 0x3
Read Calibration
Send: 0x51
Response: 0x53
Send: 0x52
Response: 0x53
Send: 0x54
Response: 0x53
Send: 0x55
Response: 0x53
Read ADC values
Send: 0x31
Response: 0x32
Read Firmware version
Send: 0x80
Response: 0x88
Wait for button inpurt
Send: 0x05
Response: 0x03
Whenever the button is pressed, the device sends 0x62.