Code Monkey home page Code Monkey logo

Comments (69)

rockowitz avatar rockowitz commented on June 25, 2024 1

@digitaltrails While there are monitors that use the DDC Null Message to indicate an unsupported feature, it's uncommon. I've never seen it on one of my monitors, and I own many. I was very surprised that your Benq monitor exhibits the behaviour - I think of them as one of the better manufacturers in regards to the DDC/CI spec.

Putting in a large amount of code to accommodate the infrequent and non-spec-compliant case at the expense of the common case that is spec compliant does not make sense.

I have rewritten the ddc layer code for testing monitor communication ((functions check_how_unsupported_reported() and initial_checks_by_dh() in file ddc_displays.c) to make it more coherent while also optimizing the common case of spec compliance. I've also reworked the capabilities code, and tweaked the dsa algorithm to avoid Null Messages driving the sleep step unnecessarily high.

Have at it!

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I did some more testing of just dragging the brightness slider in vdu_controls and was encountering quite a few failures, not absolute, but often, the cached dsa was:

* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* DEV EC C I Values
* Values {tries required, step, epoch seconds}
i2c-3 2a 3 3 5 {1,7,1688162253} {1,7,1688162267} {1,7,1688162267} {1,7,1688162269} {1,7,1688162269} {1,6,1688162269} {1,5,1688162269} {2,5,1688162276} {2,4,1688162277} {2,4,1688162279} {1,3,1688162286} {1,3,1688162294} {2,4,1688162296} {1,3,1688162298} {2,4,1688162299} {2,4,1688162301} {2,4,1688162302} {1,3,1688162309} {2,4,1688162314} {2,4,1688162316}

So I copied back the settled dsa file from the previous note:

FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* DEV EC C I Values
* Values {tries required, step, epoch seconds}
i2c-3 2a 5 3 5 {2,5,1688158861} {2,5,1688158862} {2,5,1688158863} {2,5,1688158865} {2,5,1688158866} {2,5,1688158867} {2,5,1688158869} {2,5,1688158870} {2,5,1688158872} {2,5,1688158874} {2,5,1688158875} {2,5,1688158877} {2,5,1688158878} {2,5,1688158879} {2,5,1688158880} {2,5,1688158881} {2,5,1688158882} {2,5,1688158884} {2,5,1688158885} {2,5,1688158886}

After switching to the above file, dragging the slider was totally error free.

Perhaps the dynamic adjustment is too optimistic for some old hardware. It works well for my newer LG. It seems OK for the HP ZR24w (but with the odd hiccup).

BTW, I was using a different (very old) machine for this test. I was using ddcutil 2.0.0-dev. Nvidia 470.182.03 driver (and older driver than my desktop machine) with a GTX 650Ti. DVI to DVI cable.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

@digitaltrails It looks like the dynamic sleep algorithm is being insufficiently conservative. After pulling the latest changes to branch 2.0.0-dev, please try running the following script, which will loop until the capabilities command fails. (You'll likely have to edit the location of the ddcutil executable.)

#!/bin/sh

opts="--noconfig --tid   --ts --disable-capabilities-cache  --enable-dynamic-sleep  --trcfunc dsa2_too_many_errors --trcfunc dsa2_too_few_errors --trcfunc dsa2_adjust_for_recent_successes --trcfunc dsa2_record_final --trcfunc dsa2_get_adjusted_sleep_multiplier --trcfunc ddc_write_read_with_retry --trcfunc dsa2_note_retryable_failure --trcfunc dsa2_next_retry_step --istats all  "

ddcutil=src/ddcutil
echo "\$? = $?"
while true; do
   cat $HOME/.cache/ddcutil/dsa
   cmd="$ddcutil $opts  cap"
   echo $cmd
   $cmd
   [ $? -eq 0 ] || break
done
cat $HOME/.cache/ddcutil/dsa

The output from the last (failed) iteration of the loop is what I'm looking for.

In case the problem only occurs when running vdu_controls, I've added some options that will direct all trace output to the system log, but the output will be voluminous. Let's try this first.

Thanks.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

It does occur stand alone (without vdu_controls). Output attached.
ddcutil-test-dyn-sleep.log

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

@digitaltrails The log you sent is perplexing. It shows all the ddc_write_read_with_retry() calls executing with sleep-multiplier from 1.0 to 2.0, yet all fail with a DDCRC_NULL_RESPONSE. It's as if I'm looking in the wrong place.

I've made some tweaks to the dsa2 algorithm and improved tracing. Please pull the latest 2.0.0-dev branch and execute the following updated script. Thanks.

#!/bin/sh

opts="--noconfig --tid   --ts --disable-capabilities-cache  --enable-dynamic-sleep  --trcfunc dsa2_too_many_errors --trcfunc dsa2_too_few_errors --trcfunc dsa2_adjust_for_rcnt_successes --trcfunc dsa2_record_final --trcfunc dsa2_get_adjusted_sleep_mult  --trcfunc dsa2_note_retryable_failure --trcfunc dsa2_next_retry_step --trcfunc ddc_initial_checks_by_dh  --trcfunc dsa2_note_retryable_failure --trcfunc dsa2_save_persistent_stats --trcfunc ddc_write_read_with_retry --istats all"

ddcutil=src/ddcutil                        # may have to change 
echo "\$? = $?"
while true; do
   cat $HOME/.cache/ddcutil/dsa
   cmd="$ddcutil $opts  cap --dis 1 $@"   # may have to change --display option for problematic monitor
   echo $cmd
   $cmd
   [ $? -eq 0 ] || break
done
cat $HOME/.cache/ddcutil/dsa

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Can the monitor or bus become overwhelmed. On at least one occasion it must have worked (because I have that dsa file with 2.0 in it). So I wonder if things are happening too fast for some aspect of the hardware/software. I've yet to find time to try the latest code - might have to be be tomorrow.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

@digitaltrails The log you sent is perplexing. It shows all the ddc_write_read_with_retry() calls executing with sleep-multiplier from 1.0 to 2.0, yet all fail with a DDCRC_NULL_RESPONSE. It's as if I'm looking in the wrong place.

I've made some tweaks to the dsa2 algorithm and improved tracing. Please pull the latest 2.0.0-dev branch and execute the following updated script. Thanks.

It seems to lockup - never exits. I ran it with strace, here is the tail end of the trace:

clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
readlink("/proc/self/fd/3", "/dev/i2c-3", 4096) = 10
readlink("/proc/self/fd/3", "/dev/i2c-3", 4096) = 10
readlink("/proc/self/fd/3", "/dev/i2c-3", 4096) = 10
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x7, 0), 0x7ffcc8316210) = 1
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000}, NULL) = 0
readlink("/proc/self/fd/3", "/dev/i2c-3", 4096) = 10
readlink("/proc/self/fd/3", "/dev/i2c-3", 4096) = 10
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x7, 0), 0x7ffcc83161e0) = 1
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=520, tv_nsec=105296000},```

ddcutil-test-2023-07-05.log

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

That doesn't help me much. What happens if you run with --trace all? The output will be voluminous, but should give a better idea of where the lockup occurs.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I ran ddcutil --trace all detect, the output reveals rather a large sleep:

...
(invoke_i2c_writer             )           strategy = I2C_IO_STRATEGY_IOCTL
(i2c_ioctl_writer              ) Starting  fh=3, filename=/dev/i2c-3, slave_address=0x37, bytect=5, pbytes=0x557ea21452f1 -> 51 82 01 df 63
   i2c_rdwr_ioctl_data at: 0x7ffebb5ca4a0
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0000
         len:     0x0005 (5)
         buf:     0x557ea21452f1 ->  51 82 01 df 63
(i2c_ioctl_writer              ) Done      Returning: OK(0). 
(invoke_i2c_writer             ) Done      Returning: OK(0). 
(tuned_sleep_with_trace        ) Starting  dh=Display_Handle[i2c-3: fd=3 @0x557ea2141490], sleep event type=SE_WRITE_TO_READ, special_sleep_time_millis=0
(tuned_sleep_with_trace        )           Called from func=ddc_i2c_write_read_raw, filename=ddc_packet_io.c, lineno=451, msg=|(null)|
(get_sleep_time                ) Starting  Sleep event type = SE_WRITE_TO_READ, special_sleep_time_millis=0
(get_sleep_time                ) Done      Returning: 50, *is_deferrable_loc = false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-3: fd=3 @0x557ea2141490], spec_sleep_time_millis=50
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier=10661921.00, Returning: 533096050
(sleep_millis_with_trace       )           Sleeping for 533096050 milliseconds. Event_type: SE_WRITE_TO_READ

trace-all-2023-07-06.log

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I don't know if it's significant, but on my normal desktop, when I woke up the monitors from suspend, this was running via vdu_controls (which retried successfully):

Journal Entry 2023-07-06 17:53:27.582445+12:00

MESSAGE                  : (dsa2_restore_persistent_stats) busno=0, resetting invalid cur_step from 11 to 10
PRIORITY                 : 3
SYSLOG_FACILITY          : 1
SYSLOG_IDENTIFIER        : ddcutil
SYSLOG_PID               : 3935
SYSLOG_TIMESTAMP         : Jul  6 17:53:27 
_AUDIT_LOGINUID          : 500
_AUDIT_SESSION           : 4
_BOOT_ID                 : 67e8da11-798b-425c-9dc1-5d4970df2f9f
_CAP_EFFECTIVE           : 0
_CMDLINE                 : ddcutil --enable-dynamic-sleep --force --brief getvcp 10 --edid 00ffffffffffff0022f069280101010108140104a53623782efc81a4554d9d25125054210800814081809500a940b300d1c001010101283c80a070b023403020360022602100001a000000fd003b3d185011000a202020202020000000fc004850205a523234770a20202020000000ff00434e5430303831314a360a2020003d
_COMM                    : ddcutil
_EXE                     : /home/michael/bin/ddcutil

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

The large sleep and the syslog message reflect the same problem. If the index into the steps array is beyond the end, the sleep multiplier used is whatever happens to be in memory, causing in your case the long sleep. There's a sanity check on the current step when restoring stats, which caused the syslog report.

I have reworked the functions that adjust the sleep-multiplier step based on recent successes and failures and in the process removed a cause of the above error. I have also tweaked the retryability of the DDC Null Response, which is ambiguous as an indication of whether an operation can be retried. The changes have been pushed to branch 2.0.0-dev.

I've also slightly modified the script to count the number of times through the loop. If you need to specify a display number or other display selector, the option can go on the script command line.

I've run the script against the 3 displays on this workstation (RX 580, amdgpu). Each ran until the display disappeared because it powered off: 3760 times for a HDMI connection, 1491 times for a DVI connection, and 4940 times for a DP connected monitor. Over the weekend I should have a chance to install a Nvidia card on a test system and run the script there.

#!/bin/sh

opts="--noconfig --tid   --ts --disable-capabilities-cache  --enable-dynamic-sleep  --trcfunc dsa2_too_many_errors --trcfunc dsa2_too_few_errors --trcfunc dsa2_adjust_for_rcnt_successes --trcfunc dsa2_record_final --trcfunc dsa2_get_adjusted_sleep_mult  --trcfunc dsa2_note_retryable_failure --trcfunc dsa2_next_retry_step --trcfunc ddc_initial_checks_by_dh  --trcfunc dsa2_note_retryable_failure --trcfunc dsa2_save_persistent_stats --trcfunc ddc_write_read_with_retry --istats all"

ddcutil=src/ddcutil                        # may have to change 
loopctr=0
while true; do
   loopctr=$((loopctr+1))
   printf "\n=====> Starting loop %d\n" $loopctr
   cat $HOME/.cache/ddcutil/dsa
   # cmd="$ddcutil detect"
   # echo $cmd
   # $cmd
   # [ $? -eq 0 ] || break
   cmd="$ddcutil $opts  cap  $@"  
   echo $cmd
   $cmd
   [ $? -eq 0 ] || break
done
printf "======> ddcutil command failed on loop %d\n" $loopctr
cat $HOME/.cache/ddcutil/dsa

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Some progress (but not all good):

# rm -rf .cache/ddcutil; bin/ddcutil --enable-dynamic-sleep detect 
(lock_display                  ) Starting  id=0x5576f786d5d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x5576f786d5d0]
(lock_display                  ) Done      Returning: NULL. id=0x5576f786d5d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x5576f786d5d0]
(unlock_display                ) Starting  id=0x5576f786d5d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x5576f786d5d0]
(unlock_display                ) Done      Returning: NULL. id=0x5576f786d5d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x5576f786d5d0]
Display 1
   I2C bus:  /dev/i2c-3
   DRM connector:           card0-DVI-D-1
   EDID synopsis:
      Mfg id:               BNQ - UNK
      Model:                BenQ T2200HD
      Product code:         30502  (0x7726)
      Serial number:        2C803527SL0
      Binary serial number: 21573 (0x00005445)
      Manufacture year:     2008,  Week: 51
   VCP version:         2.0

But capabilities fails with --enable-dynamic-sleep (but works if it is disabled):

% rm -rf .cache/ddcutil; bin/ddcutil --enable-dynamic-sleep capabilities 
(lock_display                  ) Starting  id=0x555a74e835d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x555a74e835d0]
(lock_display                  ) Done      Returning: NULL. id=0x555a74e835d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x555a74e835d0]
(unlock_display                ) Starting  id=0x555a74e835d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x555a74e835d0]
(unlock_display                ) Done      Returning: NULL. id=0x555a74e835d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x555a74e835d0]
(lock_display                  ) Starting  id=0x555a74e835d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x555a74e835d0]
(lock_display                  ) Done      Returning: NULL. id=0x555a74e835d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x555a74e835d0]
(app_get_capabilities_string) !!! Unable to get capabilities for monitor on Display_Handle[i2c-3: fd=3 @0x555a74e5c530]
(app_get_capabilities_string   ) Unexpected status code: DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message
(unlock_display                ) Starting  id=0x555a74e835d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x555a74e835d0]
(unlock_display                ) Done      Returning: NULL. id=0x555a74e835d0 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x555a74e835d0]

The loop script fails on loop 1.
ddcutil-test-dyn-sleep-2023-07-08.log

On my newer system with the LG+HP VDU's the loop script keeps looping, so it's just this old Beng and an old NVidia card.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

By any chance are you using an explicit --sleep-multiplier value greater than 2.0 for this monitor?

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

By any chance are you using an explicit --sleep-multiplier value greater than 2.0 for this monitor?

Definitely not in the manual tests I ran above. The command line is included at the top of each quoted output.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

@digitaltrails Please ignore the last comment I just deleted. I'm having a hard time coming with a reason why the monitor keeps returning the DDC Null Message when all that dynamic sleep is doing is varying the sleep time, whereas with dynamic sleep off there's just a single fixed sleep time.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

My suspicion is that i2c to the Beng or Nvidia-card is being driven too fast and getting swamped to the point that it behaves differently. I experimentally altered src/base/sleep.c to add some milliseconds, starting at 10 and doubling, I found that at += 80 the command rm -rf .cache/ddcutil; ddcutil capabilities works.

void sleep_millis_with_trace(
        int          milliseconds,
        const char * func,
        int          lineno,
        const char * filename,
        const char * message)
{
   bool debug = false;

   if (!message)
      message = "";

   milliseconds += 80;  /* experimenting with being a bit more conservative */

   DBGTRC_NOPREFIX(debug, DDCA_TRC_SLEEP,
                   "Sleeping for %d milliseconds. %s", milliseconds, message);

   if (milliseconds > 0)
      sleep_millis(milliseconds);
}

Perhaps what sleep multiplier will work may change if the driver/firmware/hardware is overwhelmed. The capabilities command seems a bit exceptional - perhaps it's more sensitive or prone to such glitches. A lot of hand waving and guessing on my part.

If a dsa based operation fails, could ddcutil fall back to the standard sleep multiplier?

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

More info: I just tried ddcutil 1.4.1 with the Beng and capabilities it failed until I set a sleep multiplier of 1.1:

% /usr/bin/ddcutil --version                                                                                                                          
ddcutil 1.4.1
...
% rm -rf ~/.cache/ddcutil ; /usr/bin/ddcutil --sleep-multiplier=1.1 capabilities
(lock_display                  ) Starting  id=0x55efac89c780 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x55efac89c780]
(lock_display                  ) Done      Returning: NULL. id=0x55efac89c780 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x55efac89c780]
(unlock_display                ) Starting  id=0x55efac89c780 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x55efac89c780]
(unlock_display                ) Done      Returning: NULL. id=0x55efac89c780 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x55efac89c780]
(lock_display                  ) Starting  id=0x55efac89c780 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x55efac89c780]
(lock_display                  ) Done      Returning: NULL. id=0x55efac89c780 -> Display_Lock_Record[Display_Path[/dev/i2c-3] @0x55efac89c780]
Model: T2200HD
MCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)
...

This is also true for 2.0.0-dev with --disable-dynamic-sleep. So the Beng is certainly a bit sluggish. Other commands such as detect, getvcp, and setvcp seem to work fine with a multiplier of 1.0 (possibly caching was hiding the difference in some past tests).

Edit: I was testing remotely, I just found a multiplier of 1.0 is fine as long as the screen isn't in power saving (but the power saving sate doesn't make any difference to `--enable-dynamic-sleep).

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

Your conjecture that the Nvidia card/Benq monitor combination is being driven too hard makes sense. The question is which is the culprit - that would take sniffing the line. The DDC Null Message is a bit of a catch-all. The relevant use here is "To tell the host that the display does not have any answer to give to the host (not ready or not expected)." Unfortunately that covers both a problem in the monitor (which could be request for a reply packet that comes in too soon or some other problem in the monitor's DDC/CI implementation), and the monitor having received a malformed request from the host. To make things even more ambiguous, some monitors use the Null Message to indicate an unsupported feature instead of setting a bit in a getvcp reply packet.

As I've noted elsewhere, reading the capabilities string is by far the most complex, error prone, and expensive DDC/CI operation, (setting aside reading and writing features of type Table, which is a generalization of reading the capabilities string and is rare). It requires multiple write request/read response cycles, since a single response can return at most 32 bytes.

Further conjecture. With dynamic sleep enabled, the initial requests with very short sleep time put the card/monitor into a problematic state from which they do not recover even as dynamic sleep increases the sleep multiplier to 2. Perhaps multi-part read requests (i.e. capabilities requests) should ignore dynamic sleep, or perhaps there should be special handling for the case where write/read requests consistently return the Null Message.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I can try the Beng on my main desktop. It also has a Nvidia card, but a more recent one and uses the 500 series driver instead of the 400 series. The next couple of days are a bit hectic, but Thursday NZ time at the latest.

The capabilities command takes so long, having it take a bit longer seems like an OK compromise.

The monitor does recover and respond to later commands. The time taken by me do a command recall in bash and pressing enter is roughly enough. Perhaps as a last resort you could delay a while and then try with a long sleep interval.

Instead of staring short and going longer, would starting long and going shorter, be more stable? I suppose the monitor is exchange is still eventually going to trip the problem.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I tried the Beng on my main desktop PC. It was connected DVI-HDMI, I'm using the Nvidia 525.116.04 driver. I had to use a sleep-multiplier of 1.1 to be able to get it to respond to the capabilities command:

rm -rf ~/.cache/ddcutil; ddcutil --disable-dynamic-sleep --sleep-multiplier 1.1 --display 2 capabilities

It seemed to always fail with a multiplier of 1.0, almost always succeed on 1.1, and I haven't seen 1.2 fail (in a about 6 tries).

Both getvcp and setvcp work fine with dynamic-sleep enabled.

Perhaps this monitor is too old and slow.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

@digitaltrails Based on your tests, I have modified multi_part_read_with_retry() to sleep for an optional amount of time after try_multi_part_read() indicates that all its calls to ddc_write_read_with_retry() received a NULL message response. Hopefully you can find a sleep duration that causes the video card or monitor to reset, if that is the problem. Temporary use option --i2 specifies the sleep time in milliseconds. add multi_part_read_with_retry to the list of traced functions. If the additional sleep occurs, a trace message is issued unconditionally.

Re:

Instead of staring short and going longer, would starting long and going shorter, be more stable?

We've seen that even when the cache file sets the initial multiplier to 2.0 the error occurs. And starting long on every ddcutil defeats the dynamic sleep adjustment, since it takes many ddcutil invocations to have enough data to adjust the sleep time downwards.

The original dynamic sleep algorithm added a 100 ms sleep in the retry loop of ddc_write_read_with_retry() in case of a DDC Null Message. Based on what you find I may try adding similar code to the the current dynamic sleep algorithm.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

@digitaltrails I have installed a Nvidia 660ti using driver 535.54 on a test system, and put my most ornery monitor, a Dell P2411h, on it. Lots of DDCRC_DDC_DATA errors, but no DDCRC_NULL_MESSAGE responses.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

The modified version works out of the box. There was no need to specify an --i2 value:

rm -rf ~/.cache/ddcutil ; ./bin/ddcutil  --enable-dynamic-sleep capabilities
Model: T2200HD
MCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)
   Op Code: 02 (VCP Response)
   Op Code: 03 (VCP Set)
   Op Code: 07 (Timing Request)
   Op Code: 0C (Save Settings)
   Op Code: E3 (Capabilities Reply)
   Op Code: F3 (Capabilities Request)
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)
   Feature: 08 (Restore color defaults)
   Feature: 10 (Brightness)
   Feature: 12 (Contrast)
   Feature: 14 (Select color preset)
      Values:
         05: 6500 K
         06: 7500 K
         08: 9300 K
         0b: User 1
   Feature: 16 (Video gain: Red)
   Feature: 18 (Video gain: Green)
   Feature: 1A (Video gain: Blue)
   Feature: 3E (Clock phase)
   Feature: 52 (Active control)
   Feature: 60 (Input Source)
      Values:
         01: VGA-1
         03: DVI-1
   Feature: 6C (Video black level: Red)
   Feature: 6E (Video black level: Green)
   Feature: 70 (Video black level: Blue)
   Feature: AC (Horizontal frequency)
   Feature: AE (Vertical frequency)
   Feature: B2 (Flat panel sub-pixel layout)
   Feature: B6 (Display technology type)
   Feature: C0 (Display usage time)
   Feature: C8 (Display controller type)
   Feature: C9 (Display firmware level)
   Feature: CC (OSD Language)
      Values:
         01: Chinese (traditional, Hantai)
         02: English
         03: French
         04: German
         05: Italian
         06: Japanese
         09: Russian
         0a: Spanish
   Feature: D6 (Power mode)
      Values:
         01: DPM: On,  DPMS: Off
         05: Write only value to turn off display
   Feature: DF (VCP Version)

Because I had replugged cables, I ran both a previous dev pull and the new one. The previous pull still fails, and the latest pull works. It's a bit slow on getting capabilities, which isn't an issue as far as I'm concerned. It hasn't failed in 10 or so attempts so far. Yay!

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

With --trcfunc:

(multi_part_read_with_retry    ) Starting  request_type=0xf3, request_subtype=0x00, all_zero_response_ok=false, max_multi_part_read_tries=8
(multi_part_read_with_retry    )           Start of while loop. try_ctr=0, max_multi_part_read_tries=8
(multi_part_read_with_retry    )           After try loop. tryctr=1, rc=0. ddc_excp=NULL
(multi_part_read_with_retry    ) Done      Returning: NULL. *buffer_loc = 0x5646d6783d10
   Buffer at 0x5646d6783d10, bytes addr=0x5646d67abb20, len=235, max_size=2048
           +0          +4          +8          +c            0   4   8   c   
   +0000   28 70 72 6f 74 28 6d 6f 6e 69 74 6f 72 29 74 79   (prot(monitor)ty
   +0010   70 65 28 4c 43 44 29 6d 6f 64 65 6c 28 54 32 32   pe(LCD)model(T22
   +0020   30 30 48 44 29 63 6d 64 73 28 30 31 20 30 32 20   00HD)cmds(01 02 
   +0030   30 33 20 30 37 20 30 43 20 45 33 20 46 33 29 76   03 07 0C E3 F3)v
   +0040   63 70 28 30 32 20 30 34 20 30 35 20 30 38 20 31   cp(02 04 05 08 1
   +0050   30 20 31 32 20 31 34 28 30 35 20 30 36 20 30 38   0 12 14(05 06 08
   +0060   20 30 42 29 20 31 36 20 31 38 20 31 41 20 33 45    0B) 16 18 1A 3E
   +0070   20 35 32 20 36 30 28 30 31 20 30 33 29 20 36 43    52 60(01 03) 6C
   +0080   20 36 45 20 37 30 20 41 43 20 41 45 20 42 32 20    6E 70 AC AE B2 
   +0090   42 36 20 43 30 20 43 38 20 43 39 20 20 43 43 28   B6 C0 C8 C9  CC(
   +00a0   30 31 20 30 32 20 30 33 20 30 34 20 30 35 20 30   01 02 03 04 05 0
   +00b0   36 20 30 39 20 30 41 29 20 44 36 28 30 31 20 30   6 09 0A) D6(01 0
   +00c0   35 29 20 44 46 29 6d 73 77 68 71 6c 28 31 29 61   5) DF)mswhql(1)a
   +00d0   73 73 65 74 5f 65 65 70 28 34 30 29 6d 63 63 73   sset_eep(40)mccs
   +00e0   5f 76 65 72 28 32 2e 30 29 29 00                  _ver(2.0)).     
Model: T2200HD
MCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)

   ...

   Feature: DF (VCP Version)
./bin/ddcutil --trcfunc multi_part_read_with_retry capabilities  0.02s user 0.42s system 3% cpu 12.209 total

Seems to always report tryctr=1 - which looking at the code seems to imply only 1 iteration.

The elapsed time is around 12.2 seconds, which does vary much, even with different --i2 values.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I tried the new version with the Beng connected to my normal desktop. The capabilities command most often works, but sometimes errors (perhaps 1 in 5). Typically:

+ ddcutil --trcfunc multi_part_read_with_retry --display 2 capabilities
(multi_part_read_with_retry    ) Starting  request_type=0xf3, request_subtype=0x00, all_zero_response_ok=false, max_multi_part_read_tries=8
(multi_part_read_with_retry    )           Start of while loop. try_ctr=0, max_multi_part_read_tries=8
(multi_part_read_with_retry    )           Terminating loop for DDCRC_ALL_RESPONSES_NULL
(multi_part_read_with_retry    )           After try loop. tryctr=1, rc=-3011. ddc_excp=Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(2), DDCRC_NULL_RESPONSE]
(multi_part_read_with_retry    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in multi_part_read_with_retry, causes: DDCRC_ALL_RESPONSES_NULL]. *buffer_loc = (nil)
(app_get_capabilities_string) !!! Unable to get capabilities for monitor on Display_Handle[i2c-1: fd=3 @0x55fe2155f4a0]
(app_get_capabilities_string   ) Unexpected status code: DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

Re the first log, tryctr is 1 because on the first iteration of the loop the call to try_multi_part_read() returned NULL, i.e. it succeeded. --i2 only applies when multi_part_read() returns ErrorInfo[DDC_ALL_RESPONSES_NULL] or ErrorInfo[DDC_NULL_RESPONSE].

However ...

Re the second log. Recall that some ill-behaved monitors use the DDC Null Message to indicate that a feature is not supported instead of setting the unsupported bit in a normal reply packet. As part of initialization, ddcutil tries to figure out if that is the case. So before applying the --i2 sleep value and retrying, multi_part_read_with_retry() checks to see if the Null Message indicates an unsupported feature and if so returns immediately. The initialization code got it wrong about how unsupported features are indicated. Why does multi_part_read_with_retry() even care about an unsupported feature when it is reading capabilities? The same code is used for reading Table type features, for which the only way to indicate an unsupported feature is the Null Message.

Bottom line is that the edge cases need better handling, particularly the check for how an unsupported feature is reported.

But see the next comment...

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

The latest set of changes implement an earlier mechanism for recovering from Null Message errors in ddc_write_read_with_retry(), which is (ultimately) called in multi_part_read_with_retry()'s loop. Utility option --f7 enables it. If the mechanism kicks in a trace message is written to the terminal unconditionally (and written to the system log).

The test script has been tweaked again:

#!/bin/sh

# trcopts="--trcfunc dsa2_too_many_errors --trcfunc dsa2_too_few_errors --trcfunc dsa2_adjust_for_rcnt_successes --trcfunc dsa2_record_final --trcfunc dsa2_get_adjusted_sleep_mult  --trcfunc dsa2_note_retryable_failure --trcfunc dsa2_next_retry_step --trcfunc ddc_initial_checks_by_dh  --trcfunc dsa2_note_retryable_failure --trcfunc dsa2_save_persistent_stats --trcfunc ddc_write_read_with_retry --trcfunc multi_part_read_with_retry --trcfunc adjust_sleep_time"
opts="--noconfig --tid --ts $trcopts --disable-capabilities-cache --enable-dynamic-sleep"

rm  $HOME/.cache/ddcutil/dsa
ddcutil=src/ddcutil                        # may have to change 
loopctr=0
while true; do
   loopctr=$((loopctr+1))
   printf "\n=====> Starting loop %d\n" $loopctr
   cat $HOME/.cache/ddcutil/dsa
   # cmd="$ddcutil detect"
   # echo $cmd
   # $cmd
   # [ $? -eq 0 ] || break
   cmd="$ddcutil $opts  cap  $@"   # if necessary, specify --display option here or on command line
   echo ""
   echo $cmd
   $cmd
   [ $? -eq 0 ] || break
done
printf "======> ddcutil command failed on loop %d\n" $loopctr
cat $HOME/.cache/ddcutil/dsa

I look forward to learning what you find.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Looking good. It's currently reached 41 iterations. I've left it running.

The script isn't passing --f7 - is that correct?

Some of my past looping tests on my main desktop will have been tripped up by vdu_controls, it was idle in the system tray, but would have been periodically checking ambient lux versus VDU brightness. I made sure it was off this time. This would only apply to my main desktop, not my older test machine. So perhaps failing every 5 or so tries was due to contention. Sorry about any confusion this may have caused.

=====> Starting loop 1
cat: /home/michael/.cache/ddcutil/dsa: No such file or directory

/home/michael/bin/ddcutil --display 2 --noconfig --tid --ts --disable-capabilities-cache --enable-dynamic-sleep cap
Model: T2200HD
MCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)
   Op Code: 02 (VCP Response)
   Op Code: 03 (VCP Set)
   Op Code: 07 (Timing Request)
   Op Code: 0C (Save Settings)
   Op Code: E3 (Capabilities Reply)
   Op Code: F3 (Capabilities Request)
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)
   Feature: 08 (Restore color defaults)
   Feature: 10 (Brightness)
   Feature: 12 (Contrast)
   Feature: 14 (Select color preset)
      Values:
         05: 6500 K
         06: 7500 K
         08: 9300 K
         0b: User 1
   Feature: 16 (Video gain: Red)
   Feature: 18 (Video gain: Green)
   Feature: 1A (Video gain: Blue)
   Feature: 3E (Clock phase)
   Feature: 52 (Active control)
   Feature: 60 (Input Source)
      Values:
         01: VGA-1
         03: DVI-1
   Feature: 6C (Video black level: Red)
   Feature: 6E (Video black level: Green)
   Feature: 70 (Video black level: Blue)
   Feature: AC (Horizontal frequency)
   Feature: AE (Vertical frequency)
   Feature: B2 (Flat panel sub-pixel layout)
   Feature: B6 (Display technology type)
   Feature: C0 (Display usage time)
   Feature: C8 (Display controller type)
   Feature: C9 (Display firmware level)
   Feature: CC (OSD Language)
      Values:
         01: Chinese (traditional, Hantai)
         02: English
         03: French
         04: German
         05: Italian
         06: Japanese
         09: Russian
         0a: Spanish
   Feature: D6 (Power mode)
      Values:
         01: DPM: On,  DPMS: Off
         05: Write only value to turn off display
   Feature: DF (VCP Version)

=====> Starting loop 2
FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* L    current lookback
* DEV EC C I L Values
* Values {tries required, step, epoch seconds}
i2c-0 3d 7 3 5 {1,7,1689307308} {1,7,1689307308}
i2c-1 2a 10 3 14 {1,7,1689307315} {1,6,1689307316} {1,5,1689307316} {1,4,1689307316} {1,3,1689307317} {1,2,1689307317} {1,1,1689307317} {1,0,1689307317} {1,0,1689307318} {1,0,1689307318} {1,0,1689307318} {1,0,1689307318} {1,0,1689307319} {1,0,1689307319} {1,0,1689307319} {1,0,1689307319} {1,0,1689307320} {1,0,1689307320} {1,0,1689307320} {1,0,1689307320}
i2c-3 9e 7 3 5 {1,7,1689307312} {1,7,1689307312}

/home/michael/bin/ddcutil --display 2 --noconfig --tid --ts --disable-capabilities-cache --enable-dynamic-sleep cap
Model: T2200HD
MCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)
   Op Code: 02 (VCP Response)
   Op Code: 03 (VCP Set)
   Op Code: 07 (Timing Request)
   Op Code: 0C (Save Settings)
   Op Code: E3 (Capabilities Reply)
   Op Code: F3 (Capabilities Request)
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)
   Feature: 08 (Restore color defaults)
   Feature: 10 (Brightness)
   Feature: 12 (Contrast)
   Feature: 14 (Select color preset)
      Values:
         05: 6500 K
         06: 7500 K
         08: 9300 K
         0b: User 1
   Feature: 16 (Video gain: Red)
   Feature: 18 (Video gain: Green)
   Feature: 1A (Video gain: Blue)
   Feature: 3E (Clock phase)
   Feature: 52 (Active control)
   Feature: 60 (Input Source)
      Values:
         01: VGA-1
         03: DVI-1
   Feature: 6C (Video black level: Red)
   Feature: 6E (Video black level: Green)
   Feature: 70 (Video black level: Blue)
   Feature: AC (Horizontal frequency)
   Feature: AE (Vertical frequency)
   Feature: B2 (Flat panel sub-pixel layout)
   Feature: B6 (Display technology type)
   Feature: C0 (Display usage time)
   Feature: C8 (Display controller type)
   Feature: C9 (Display firmware level)
   Feature: CC (OSD Language)
      Values:
         01: Chinese (traditional, Hantai)
         02: English
         03: French
         04: German
         05: Italian
         06: Japanese
         09: Russian
         0a: Spanish
   Feature: D6 (Power mode)
      Values:
         01: DPM: On,  DPMS: Off
         05: Write only value to turn off display
   Feature: DF (VCP Version)

=====> Starting loop 3
FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* L    current lookback
* DEV EC C I L Values
* Values {tries required, step, epoch seconds}
i2c-0 3d 7 3 5 {1,7,1689307308} {1,7,1689307308} {1,7,1689307321} {1,7,1689307321}
i2c-1 2a 10 3 20 {1,3,1689307328} {1,2,1689307329} {1,1,1689307329} {1,0,1689307329} {1,0,1689307329} {1,0,1689307330} {1,0,1689307330} {1,0,1689307330} {1,0,1689307330} {1,0,1689307331} {1,0,1689307331} {1,0,1689307331} {1,0,1689307331} {1,0,1689307332} {1,0,1689307332} {1,0,1689307332} {1,0,1689307332} {1,0,1689307333} {1,0,1689307333} {1,0,1689307333}
i2c-3 9e 7 3 5 {1,7,1689307312} {1,7,1689307312} {1,7,1689307326} {1,7,1689307326}

/home/michael/bin/ddcutil --display 2 --noconfig --tid --ts --disable-capabilities-cache --enable-dynamic-sleep cap
Model: T2200HD
MCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)
   Op Code: 02 (VCP Response)
   Op Code: 03 (VCP Set)
   Op Code: 07 (Timing Request)
   Op Code: 0C (Save Settings)
   Op Code: E3 (Capabilities Reply)
   Op Code: F3 (Capabilities Request)
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)
   Feature: 08 (Restore color defaults)
   Feature: 10 (Brightness)
   Feature: 12 (Contrast)
   Feature: 14 (Select color preset)
      Values:
         05: 6500 K
         06: 7500 K
         08: 9300 K
         0b: User 1
   Feature: 16 (Video gain: Red)
   Feature: 18 (Video gain: Green)
   Feature: 1A (Video gain: Blue)
   Feature: 3E (Clock phase)
   Feature: 52 (Active control)
   Feature: 60 (Input Source)
      Values:
         01: VGA-1
         03: DVI-1
   Feature: 6C (Video black level: Red)
   Feature: 6E (Video black level: Green)
   Feature: 70 (Video black level: Blue)
   Feature: AC (Horizontal frequency)
   Feature: AE (Vertical frequency)
   Feature: B2 (Flat panel sub-pixel layout)
   Feature: B6 (Display technology type)
   Feature: C0 (Display usage time)
   Feature: C8 (Display controller type)
   Feature: C9 (Display firmware level)
   Feature: CC (OSD Language)
      Values:
         01: Chinese (traditional, Hantai)
         02: English
         03: French
         04: German
         05: Italian
         06: Japanese
         09: Russian
         0a: Spanish
   Feature: D6 (Power mode)
      Values:
         01: DPM: On,  DPMS: Off
         05: Write only value to turn off display
   Feature: DF (VCP Version)

=====> Starting loop 4
FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* L    current lookback
* DEV EC C I L Values
* Values {tries required, step, epoch seconds}
i2c-0 3d 5 3 6 {1,7,1689307308} {1,7,1689307308} {1,7,1689307321} {1,7,1689307321} {1,7,1689307334} {1,6,1689307334}
i2c-1 2a 10 3 20 {1,3,1689307341} {1,2,1689307341} {1,1,1689307342} {1,0,1689307342} {1,0,1689307342} {1,0,1689307342} {1,0,1689307343} {1,0,1689307343} {1,0,1689307343} {1,0,1689307343} {1,0,1689307344} {1,0,1689307344} {1,0,1689307344} {1,0,1689307344} {1,0,1689307345} {1,0,1689307345} {1,0,1689307345} {1,0,1689307345} {1,0,1689307346} {1,0,1689307346}
i2c-3 9e 5 3 6 {1,7,1689307312} {1,7,1689307312} {1,7,1689307326} {1,7,1689307326} {1,7,1689307339} {1,6,1689307339}

/home/michael/bin/ddcutil --display 2 --noconfig --tid --ts --disable-capabilities-cache --enable-dynamic-sleep cap
Model: T2200HD
MCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)
   Op Code: 02 (VCP Response)
   Op Code: 03 (VCP Set)
   Op Code: 07 (Timing Request)
   Op Code: 0C (Save Settings)
   Op Code: E3 (Capabilities Reply)
   Op Code: F3 (Capabilities Request)
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)
   Feature: 08 (Restore color defaults)
   Feature: 10 (Brightness)
   Feature: 12 (Contrast)
   Feature: 14 (Select color preset)
      Values:
         05: 6500 K
         06: 7500 K
         08: 9300 K
         0b: User 1
   Feature: 16 (Video gain: Red)
   Feature: 18 (Video gain: Green)
   Feature: 1A (Video gain: Blue)
   Feature: 3E (Clock phase)
   Feature: 52 (Active control)
   Feature: 60 (Input Source)
      Values:
         01: VGA-1
         03: DVI-1
   Feature: 6C (Video black level: Red)
   Feature: 6E (Video black level: Green)
   Feature: 70 (Video black level: Blue)
   Feature: AC (Horizontal frequency)
   Feature: AE (Vertical frequency)
   Feature: B2 (Flat panel sub-pixel layout)
   Feature: B6 (Display technology type)
   Feature: C0 (Display usage time)
   Feature: C8 (Display controller type)
   Feature: C9 (Display firmware level)
   Feature: CC (OSD Language)
      Values:
         01: Chinese (traditional, Hantai)
         02: English
         03: French
         04: German
         05: Italian
         06: Japanese
         09: Russian
         0a: Spanish
   Feature: D6 (Power mode)
      Values:
         01: DPM: On,  DPMS: Off
         05: Write only value to turn off display
   Feature: DF (VCP Version)

=====> Starting loop 5
FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* L    current lookback
* DEV EC C I L Values
* Values {tries required, step, epoch seconds}
i2c-0 3d 3 3 8 {1,7,1689307308} {1,7,1689307308} {1,7,1689307321} {1,7,1689307321} {1,7,1689307334} {1,6,1689307334} {1,5,1689307346} {1,4,1689307347}
i2c-1 2a 10 3 20 {1,3,1689307354} {1,2,1689307354} {1,1,1689307354} {1,0,1689307354} {1,0,1689307355} {1,0,1689307355} {1,0,1689307355} {1,0,1689307355} {1,0,1689307356} {1,0,1689307356} {1,0,1689307356} {1,0,1689307356} {1,0,1689307357} {1,0,1689307357} {1,0,1689307357} {1,0,1689307357} {1,0,1689307358} {1,0,1689307358} {1,0,1689307358} {1,0,1689307358}
i2c-3 9e 3 3 8 {1,7,1689307312} {1,7,1689307312} {1,7,1689307326} {1,7,1689307326} {1,7,1689307339} {1,6,1689307339} {1,5,1689307351} {1,4,1689307351}

/home/michael/bin/ddcutil --display 2 --noconfig --tid --ts --disable-capabilities-cache --enable-dynamic-sleep cap
Model: T2200HD
MCCS version: 2.0
Commands:
   Op Code: 01 (VCP Request)
   Op Code: 02 (VCP Response)
   Op Code: 03 (VCP Set)
   Op Code: 07 (Timing Request)
   Op Code: 0C (Save Settings)
   Op Code: E3 (Capabilities Reply)
   Op Code: F3 (Capabilities Request)
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)
   Feature: 08 (Restore color defaults)
   Feature: 10 (Brightness)
   Feature: 12 (Contrast)
   Feature: 14 (Select color preset)
      Values:
         05: 6500 K
         06: 7500 K
         08: 9300 K
         0b: User 1
   Feature: 16 (Video gain: Red)
   Feature: 18 (Video gain: Green)
   Feature: 1A (Video gain: Blue)
   Feature: 3E (Clock phase)
   Feature: 52 (Active control)
   Feature: 60 (Input Source)
      Values:
         01: VGA-1
         03: DVI-1
   Feature: 6C (Video black level: Red)
   Feature: 6E (Video black level: Green)
   Feature: 70 (Video black level: Blue)
   Feature: AC (Horizontal frequency)
   Feature: AE (Vertical frequency)
   Feature: B2 (Flat panel sub-pixel layout)
   Feature: B6 (Display technology type)
   Feature: C0 (Display usage time)
   Feature: C8 (Display controller type)
   Feature: C9 (Display firmware level)
   Feature: CC (OSD Language)
      Values:
         01: Chinese (traditional, Hantai)
         02: English
         03: French
         04: German
         05: Italian
         06: Japanese
         09: Russian
         0a: Spanish
   Feature: D6 (Power mode)
      Values:
         01: DPM: On,  DPMS: Off
         05: Write only value to turn off display
   Feature: DF (VCP Version)

=====> Starting loop 6
FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* L    current lookback
* DEV EC C I L Values
* Values {tries required, step, epoch seconds}
i2c-0 3d 1 3 10 {1,7,1689307308} {1,7,1689307308} {1,7,1689307321} {1,7,1689307321} {1,7,1689307334} {1,6,1689307334} {1,5,1689307346} {1,4,1689307347} {1,3,1689307359} {1,2,1689307359}
i2c-1 2a 10 3 20 {1,3,1689307366} {1,2,1689307366} {1,1,1689307367} {1,0,1689307367} {1,0,1689307367} {1,0,1689307367} {1,0,1689307368} {1,0,1689307368} {1,0,1689307368} {1,0,1689307368} {1,0,1689307369} {1,0,1689307369} {1,0,1689307369} {1,0,1689307369} {1,0,1689307370} {1,0,1689307370} {1,0,1689307370} {1,0,1689307370} {1,0,1689307371} {1,0,1689307371}
i2c-3 9e 1 3 10 {1,7,1689307312} {1,7,1689307312} {1,7,1689307326} {1,7,1689307326} {1,7,1689307339} {1,6,1689307339} {1,5,1689307351} {1,4,1689307351} {1,3,1689307364} {1,2,1689307364}

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

Passing --f7 on the command line works for me:

rock@banner:/shared/playproj/i2c$ ./test_dsa_cap --f7
rm: cannot remove '/home/rock/.cache/ddcutil/dsa': No such file or directory

=====> Starting loop 1
cat: /home/rock/.cache/ddcutil/dsa: No such file or directory

src/ddcutil --noconfig --tid --ts --disable-capabilities-cache --enable-dynamic-sleep cap --f7
Model: Not specified
MCCS version: 2.1
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Passing --f7 on the command line works for me:

rock@banner:/shared/playproj/i2c$ ./test_dsa_cap --f7
rm: cannot remove '/home/rock/.cache/ddcutil/dsa': No such file or directory

=====> Starting loop 1
cat: /home/rock/.cache/ddcutil/dsa: No such file or directory

src/ddcutil --noconfig --tid --ts --disable-capabilities-cache --enable-dynamic-sleep cap --f7
Model: Not specified
MCCS version: 2.1
VCP Features:
   Feature: 02 (New control value)
   Feature: 04 (Restore factory defaults)
   Feature: 05 (Restore factory brightness/contrast defaults)

It was more that the script you asked me to run didn't actually pass --f7, but I can edit that in and run it again.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

Try adding --trcfunc ddc_initial_checks_by_dh. DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED should be set, not some other DREF_DDC_...FOR_UNSUPPORTED flag.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED

I restarted passing --f7 and --trcfunc ddc_initial_checks_by_dh, it is reporting DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED at startup. It seems to be looping fine, 14 iterations so far.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

This is the log from the above. It never failed I terminated the run.

f7-log.zip

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

The latest build is quite slow with other (non-Beng) monitors. For example with my LG Ddcutil-2dev takes above 5 seconds to do a getvcp compared to ddcutil-2rc1 which takes about 0.28.

% time ~/bin/ddcutil --display 3 getvcp 10;cat ~/.cache/ddcutil/dsa 
VCP code 0x10 (Brightness                    ): current value =    43, max value =   100
~/bin/ddcutil --display 3 getvcp 10  0.01s user 0.46s system 8% cpu 5.559 total
FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* L    current lookback
* DEV EC C I L Values
* Values {tries required, step, epoch seconds}
i2c-0 3d 0 3 5 {1,0,1689318932} {1,0,1689318932} {1,0,1689318945} {1,0,1689318945} {1,0,1689318952} {1,0,1689318952} {1,0,1689319024} {1,0,1689319025} {1,0,1689319067} {1,0,1689319067} {1,0,1689319081} {1,0,1689319081} {1,0,1689319113} {1,0,1689319114} {1,0,1689319219} {1,0,1689319220} {1,0,1689319227} {1,0,1689319228} {1,0,1689319249} {1,0,1689319249}
i2c-1 2a 10 3 20 {1,10,1689318936} {1,9,1689318936} {1,10,1689318949} {1,9,1689318949} {1,10,1689318956} {1,9,1689318957} {1,10,1689319029} {1,9,1689319029} {1,10,1689319071} {1,9,1689319071} {1,10,1689319083} {1,9,1689319083} {1,10,1689319117} {1,9,1689319117} {1,10,1689319224} {1,9,1689319224} {1,10,1689319232} {1,9,1689319232} {1,10,1689319253} {1,9,1689319253}
i2c-3 9e 0 3 5 {1,0,1689319072} {1,0,1689319072} {1,0,1689319072} {1,0,1689319083} {1,0,1689319083} {1,0,1689319083} {1,0,1689319092} {1,0,1689319109} {1,0,1689319118} {1,0,1689319118} {1,0,1689319118} {1,0,1689319224} {1,0,1689319224} {1,0,1689319225} {1,0,1689319232} {1,0,1689319232} {1,0,1689319232} {1,0,1689319253} {1,0,1689319253} {1,0,1689319254}

versus

rm ~/.cache/ddcutil/dsa; time ~/bin/ddcutil-2rc1 --display 3 getvcp 10;cat ~/.cache/ddcutil/dsa
VCP code 0x10 (Brightness                    ): current value =    43, max value =   100
~/bin/ddcutil-2rc1 --display 3 getvcp 10  0.01s user 0.27s system 73% cpu 0.379 total
FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* DEV EC C I Values
* Values {tries required, step, epoch seconds}
i2c-0 3d 7 3 5
i2c-1 2a 7 3 5
i2c-3 9e 7 3 5 {1,7,1689319337}

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

Re f7.log:

  1. The monitor is responding to getvcp of feature 0x00 with Null Messages instead of setting the unsupported flag bit in a getvcp reply packet, and consequently setting flag DREF_DDC_USES_NULL_RESPONSE_FOR_UNSUPPORTED instead of DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED. If this is incorrect, it will likely cause Null Messages to be misinterpreted down the line. (It does not affect the capabilities command because I have modified multi_part_read_with_retry() to not check for an unsupported feature when it is called for the capabilities command.)

Does this behaviour persist with option --disable-dynamic-sleep?

  1. The number of tries in the case of repeated Null Responses has been reduced from the maxtries value, normally 10, to 3, greatly reducing the elapsed time in this case. 3 tries is sufficient to determine that the Null Response is not transient.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

Re the elapsed time for getvcp of feature x10:

  1. Once dsa2 has adjusted to a maximal sleep-multiplier it is not adjusting back down. Obviously this needs to be fixed.

  2. I suggest you use option ---bus instead of --display to specify the monitor. as this is easier to correlate with the cache file data. Also, indicate which is the Benq or other monitor in these logs.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Info on connected monitors:

Display 1
   I2C bus:  /dev/i2c-0
   DRM connector:           card0-DP-1
   EDID synopsis:
      Mfg id:               HWP - Hewlett Packard
      Model:                HP ZR24w
      Product code:         10345  (0x2869)
      Serial number:        CNT00811J6
      Binary serial number: 16843009 (0x01010101)
      Manufacture year:     2010,  Week: 8
   VCP version:         2.2

Display 2
   I2C bus:  /dev/i2c-1
   DRM connector:           card0-DP-2
   EDID synopsis:
      Mfg id:               BNQ - UNK
      Model:                BenQ T2200HD
      Product code:         30502  (0x7726)
      Serial number:        2C803527SL0
      Binary serial number: 21573 (0x00005445)
      Manufacture year:     2008,  Week: 51
   VCP version:         2.0

Display 3
   I2C bus:  /dev/i2c-3
   DRM connector:           card0-DP-3
   EDID synopsis:
      Mfg id:               GSM - Goldstar Company Ltd (LG)
      Model:                LG HDR 4K
      Product code:         30471  (0x7707)
      Serial number:        
      Binary serial number: 86395 (0x0001517b)
      Manufacture year:     2019,  Week: 4
   VCP version:         2.1

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Re the elapsed time for getvcp of feature x10:

  1. Once dsa2 has adjusted to a maximal sleep-multiplier it is not adjusting back down. Obviously this needs to be fixed.

So that's why I see the time reduce when using ddcutil-2rc1, but not with ddcutil-dev. But it's not as bad as I previously stated. I forgot I had previously added my own sleep to see if overloading the Beng was the issue, this was affecting results for all monitors. I've removed my hack, now the dev elapsed time fixes to 1.624 seconds (whereas rc1 gets it down to 0.282 seconds).

  1. I suggest you use option ---bus instead of --display to specify the monitor. as this is easier to correlate with the cache file data. Also, indicate which is the Benq or other monitor in these logs.

Will do.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Re f7.log:

  1. The monitor is responding to getvcp of feature 0x00 with Null Messages instead of setting the unsupported flag bit in a getvcp reply packet, and consequently setting flag DREF_DDC_USES_NULL_RESPONSE_FOR_UNSUPPORTED instead of DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED. If this is incorrect, it will likely cause Null Messages to be misinterpreted down the line. (It does not affect the capabilities command because I have modified multi_part_read_with_retry() to not check for an unsupported feature when it is called for the capabilities command.)

Does this behaviour persist with option --disable-dynamic-sleep?

I reran the test script with --disable-dynamic-sleep with no other changes other than using --bus, the command line in the test is as follows:

/home/michael/bin/ddcutil-dev --bus 1 --noconfig --disable-dynamic-sleep --f7 --trcfunc ddc_initial_checks_by_dh --tid --ts --disable-capabilities-cache --enable-dynamic-sleep cap

a log of few iterations is attached.
f7--disable-dynamic-sleep.zip

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

As f7-disable-dynamic-sleep.log shows, the Benq monitor appears to use the Null Message to indicate unsupported features. To confirm, try:

ddcutil --bus 1 --noconfig --disable-dynamic-sleep --f7 --trcfunc ddc_initial_checks_by_dh --trcfunc ddc_get_nontable_vcp_value --trcfunc i2c_ioctl_reader1 getvcp 41

(Feature x41 applies only to CRTs. It should be unsupported.)

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

To confirm, try:

ddcutil --bus 1 --noconfig --disable-dynamic-sleep --f7 --trcfunc ddc_initial_checks_by_dh --trcfunc ddc_get_nontable_vcp_value --trcfunc i2c_ioctl_reader1 getvcp 41

./src/ddcutil --bus 1 --noconfig --disable-dynamic-sleep --f7 --trcfunc ddc_initial_checks_by_dh --trcfunc ddc_get_nontable_vcp_value --trcfunc i2c_ioctl_reader1 getvcp 41
(ddc_initial_checks_by_dh      ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x55a9d709b320]
(ddc_initial_checks_by_dh      )           Initial flags: DREF_DDC_IS_MONITOR_CHECKED, DREF_DDC_IS_MONITOR, DREF_TRANSIENT, DREF_OPEN, DREF_ALIVE
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x55a9d709b320], Reading feature 0x00
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x55a9d709b5d0
   i2c_rdwr_ioctl_data at: 0x7ffd0e8ecda0
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x55a9d709b5d0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(adjust_sleep_time             )           Adding 100 milliseconds for 1 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=150 
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x55a9d709b9d0
   i2c_rdwr_ioctl_data at: 0x7ffd0e8ecda0
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x55a9d709b9d0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(adjust_sleep_time             )           Adding 100 milliseconds for 1 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=150 
(adjust_sleep_time             )           Adding 200 milliseconds for 2 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=250 
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x55a9d709bbe0
   i2c_rdwr_ioctl_data at: 0x7ffd0e8ecda0
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x55a9d709bbe0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(adjust_sleep_time             )           Adding 200 milliseconds for 2 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=250 
(adjust_sleep_time             )           Adding 300 milliseconds for 3 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=350 
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x55a9d709bc70
   i2c_rdwr_ioctl_data at: 0x7ffd0e8ecda0
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x55a9d709bc70 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(adjust_sleep_time             )           Adding 300 milliseconds for 3 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=350 
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE(4)]. 
(ddc_initial_checks_by_dh      )           ddc_get_nontable_vcp_value() for feature 0x00 returned: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE(4)], parsed_response_loc=(nil)
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x55a9d709b320], Reading feature 0x10
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x55a9d709c0d0
   i2c_rdwr_ioctl_data at: 0x7ffd0e8ecda0
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x55a9d709c0d0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 10 00 00 64 00 64 a4 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x10. *ppinterpreted_code=0x55a9d709c0d0
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x64, max value=100, cur value=100
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
(ddc_initial_checks_by_dh      )           ddc_get_nontable_vcp_value() for feature 0x10 returned: NULL
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x55a9d709b320], Reading feature 0xdf
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x55a9d709bbe0
   i2c_rdwr_ioctl_data at: 0x7ffd0e8ecd10
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x55a9d709bbe0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 df 00 ff ff 02 00 69 6e
(ddc_get_nontable_vcp_value    )           Success reading feature xdf. *ppinterpreted_code=0x55a9d709c0d0
(ddc_get_nontable_vcp_value    )           mh=0xff, ml=0xff, sh=0x02, sl=0x00, max value=65535, cur value=512
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
(ddc_initial_checks_by_dh      )           Final flags: DREF_DDC_COMMUNICATION_CHECKED, DREF_DDC_COMMUNICATION_WORKING, DREF_DDC_IS_MONITOR_CHECKED, DREF_DDC_IS_MONITOR, DREF_UNSUPPORTED_CHECKED, DREF_DDC_USES_NULL_RESPONSE_FOR_UNSUPPORTED, DREF_TRANSIENT, DREF_OPEN, DREF_ALIVE
(ddc_initial_checks_by_dh      ) Done      Returning: true. dh=Display_Handle[i2c-1: fd=3 @0x55a9d709b320]
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x55a9d709b320], Reading feature 0x41
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x55a9d709bbe0
   i2c_rdwr_ioctl_data at: 0x7ffd0e8eca90
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x55a9d709bbe0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x41 (Vertical Parallelogram        ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x55a9d709b320]

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

Well, it certainly looks like the monitor is indeed using the Null Response to indicate an unsupported feature. As confirmation of the confirmation, please execute the script again using "getvcp color --verbose" instead of "getvcp 41". Feature group color should have a mix of supported and unsupported features, and option --verbose causes messages to be output for unsupported features.

The conundrum in this situation is how best to handle a Null Response. Does a particular Null Response indicate an unsupported feature or a monitor error. If the former, repeatedly retrying for the latter needlessly increases execution time and can drive up the sleep-multiplier calculated by dynamic sleep.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Confirmation test:

% ddcutil --bus 1 --noconfig --disable-dynamic-sleep --f7 --trcfunc ddc_initial_checks_by_dh --trcfunc ddc_get_nontable_vcp_value --trcfunc i2c_ioctl_reader1 getvcp color --verbose 2>&1 1>test-color.log
(ddc_initial_checks_by_dh      ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750]
(ddc_initial_checks_by_dh      )           Initial flags: DREF_DDC_IS_MONITOR_CHECKED, DREF_DDC_IS_MONITOR, DREF_TRANSIENT, DREF_OPEN, DREF_ALIVE
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x00
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa148a10
   i2c_rdwr_ioctl_data at: 0x7ffc4376a740
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa148a10 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
Extended delay as recovery from DDC Null Response...
(adjust_sleep_time             )           Adding 100 milliseconds for 1 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=150 
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa148e10
   i2c_rdwr_ioctl_data at: 0x7ffc4376a740
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa148e10 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(adjust_sleep_time             )           Adding 100 milliseconds for 1 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=150 
(adjust_sleep_time             )           Adding 200 milliseconds for 2 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=250 
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149020
   i2c_rdwr_ioctl_data at: 0x7ffc4376a740
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149020 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(adjust_sleep_time             )           Adding 200 milliseconds for 2 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=250 
(adjust_sleep_time             )           Adding 300 milliseconds for 3 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=350 
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa1490b0
   i2c_rdwr_ioctl_data at: 0x7ffc4376a740
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa1490b0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(adjust_sleep_time             )           Adding 300 milliseconds for 3 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=350 
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE(4)]. 
(ddc_initial_checks_by_dh      )           ddc_get_nontable_vcp_value() for feature 0x00 returned: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE(4)], parsed_response_loc=(nil)
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x10
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149510
   i2c_rdwr_ioctl_data at: 0x7ffc4376a740
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149510 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 10 00 00 64 00 63 a3 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x10. *ppinterpreted_code=0x557eaa149510
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x63, max value=100, cur value=99
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
(ddc_initial_checks_by_dh      )           ddc_get_nontable_vcp_value() for feature 0x10 returned: NULL
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0xdf
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149020
   i2c_rdwr_ioctl_data at: 0x7ffc4376a6b0
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149020 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 df 00 ff ff 02 00 69 6e
(ddc_get_nontable_vcp_value    )           Success reading feature xdf. *ppinterpreted_code=0x557eaa149510
(ddc_get_nontable_vcp_value    )           mh=0xff, ml=0xff, sh=0x02, sl=0x00, max value=65535, cur value=512
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
(ddc_initial_checks_by_dh      )           Final flags: DREF_DDC_COMMUNICATION_CHECKED, DREF_DDC_COMMUNICATION_WORKING, DREF_DDC_IS_MONITOR_CHECKED, DREF_DDC_IS_MONITOR, DREF_UNSUPPORTED_CHECKED, DREF_DDC_USES_NULL_RESPONSE_FOR_UNSUPPORTED, DREF_TRANSIENT, DREF_OPEN, DREF_ALIVE
(ddc_initial_checks_by_dh      ) Done      Returning: true. dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750]
Feature definition file not found: BNQ-BenQ_T2200HD-30502.mccs
VCP code 0x04 (Restore factory defaults      ): Write-only feature
VCP code 0x05 (Restore factory brightness/contrast defaults): Write-only feature
VCP code 0x08 (Restore color defaults        ): Write-only feature

Getting data for non-table VCP code 0x0b - Color temperature increment:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x0b
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149b80
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149b80 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 0b 00 00 02 00 02 bf 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x0b. *ppinterpreted_code=0x557eaa149b80
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x02, sh=0x00, sl=0x02, max value=2, cur value=2
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x0b, mh=0x00, ml=0x02, sh=0x00, sl=0x02, max_val=2 (0x0002), cur_val=2 (0x0002)
VCP code 0x0b (Color temperature increment   ): 2 degree(s) Kelvin

Getting data for non-table VCP code 0x0c - Color temperature request:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x0c
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 0c 00 00 02 00 02 b8 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x0c. *ppinterpreted_code=0x557eaa149d30
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x02, sh=0x00, sl=0x02, max value=2, cur value=2
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x0c, mh=0x00, ml=0x02, sh=0x00, sl=0x02, max_val=2 (0x0002), cur_val=2 (0x0002)
VCP code 0x0c (Color temperature request     ): 3000 + 2 * (feature 0B color temp increment) degree(s) Kelvin

Getting data for non-table VCP code 0x10 - Brightness:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x10
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 10 00 00 64 00 63 a3 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x10. *ppinterpreted_code=0x557eaa149d10
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x63, max value=100, cur value=99
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x10, mh=0x00, ml=0x64, sh=0x00, sl=0x63, max_val=100 (0x0064), cur_val=99 (0x0063)
VCP code 0x10 (Brightness                    ): current value =    99, max value =   100

Getting data for non-table VCP code 0x11 - Flesh tone enhancement:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x11
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d10
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d10 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x11 (Flesh tone enhancement        ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x12 - Contrast:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x12
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d10
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d10 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 12 00 00 64 00 32 f0 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x12. *ppinterpreted_code=0x557eaa149eb0
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x32, max value=100, cur value=50
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x12, mh=0x00, ml=0x64, sh=0x00, sl=0x32, max_val=100 (0x0064), cur_val=50 (0x0032)
VCP code 0x12 (Contrast                      ): current value =    50, max value =   100

Getting data for non-table VCP code 0x13 - Backlight control:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x13
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149eb0
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149eb0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x13 (Backlight control             ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x14 - Select color preset:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x14
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149eb0
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149eb0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 14 00 00 0b 00 0b a0 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x14. *ppinterpreted_code=0x557eaa149d30
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x0b, sh=0x00, sl=0x0b, max value=11, cur value=11
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x14, mh=0x00, ml=0x0b, sh=0x00, sl=0x0b, max_val=11 (0x000b), cur_val=11 (0x000b)
VCP code 0x14 (Select color preset           ): User 1 (sl=0x0b)

Getting data for non-table VCP code 0x16 - Video gain: Red:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x16
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 16 00 00 64 00 64 a2 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x16. *ppinterpreted_code=0x557eaa149da0
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x64, max value=100, cur value=100
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x16, mh=0x00, ml=0x64, sh=0x00, sl=0x64, max_val=100 (0x0064), cur_val=100 (0x0064)
VCP code 0x16 (Video gain: Red               ): current value =   100, max value =   100

Getting data for non-table VCP code 0x17 - User color vision compensation:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x17
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149da0
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149da0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x17 (User color vision compensation): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x18 - Video gain: Green:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x18
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149da0
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149da0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 18 00 00 64 00 64 ac 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x18. *ppinterpreted_code=0x557eaa149eb0
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x64, max value=100, cur value=100
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x18, mh=0x00, ml=0x64, sh=0x00, sl=0x64, max_val=100 (0x0064), cur_val=100 (0x0064)
VCP code 0x18 (Video gain: Green             ): current value =   100, max value =   100

Getting data for non-table VCP code 0x1a - Video gain: Blue:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x1a
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149eb0
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149eb0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 1a 00 00 64 00 64 ae 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x1a. *ppinterpreted_code=0x557eaa149d10
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x64, max value=100, cur value=100
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x1a, mh=0x00, ml=0x64, sh=0x00, sl=0x64, max_val=100 (0x0064), cur_val=100 (0x0064)
VCP code 0x1a (Video gain: Blue              ): current value =   100, max value =   100

Getting data for non-table VCP code 0x1f - Auto color setup:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x1f
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d10
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d10 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 1f 00 00 ff 00 00 54 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x1f. *ppinterpreted_code=0x557eaa149d30
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0xff, sh=0x00, sl=0x00, max value=255, cur value=0
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x1f, mh=0x00, ml=0xff, sh=0x00, sl=0x00, max_val=255 (0x00ff), cur_val=0 (0x0000)
VCP code 0x1f (Auto color setup              ): Auto setup not active (sl=0x00)

Getting data for non-table VCP code 0x2e - Gray scale expansion:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x2e
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x2e (Gray scale expansion          ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x59 - 6 axis saturation: Red:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x59
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x59 (6 axis saturation: Red        ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x5a - 6 axis saturation: Yellow:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x5a
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x5a (6 axis saturation: Yellow     ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x5b - 6 axis saturation: Green:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x5b
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x5b (6 axis saturation: Green      ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x5c - 6 axis saturation: Cyan:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x5c
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x5c (6 axis saturation: Cyan       ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x5d - 6 axis saturation: Blue:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x5d
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x5d (6 axis saturation: Blue       ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x5e - 6 axis saturation: Magenta:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x5e
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x5e (6 axis saturation: Magenta    ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x6b - Backlight Level: White:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x6b
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x6b (Backlight Level: White        ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x6c - Video black level: Red:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x6c
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 6c 00 00 64 00 32 8e 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x6c. *ppinterpreted_code=0x557eaa149da0
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x32, max value=100, cur value=50
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x6c, mh=0x00, ml=0x64, sh=0x00, sl=0x32, max_val=100 (0x0064), cur_val=50 (0x0032)
VCP code 0x6c (Video black level: Red        ): current value =    50, max value =   100

Getting data for non-table VCP code 0x6d - Backlight Level: Red:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x6d
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149da0
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149da0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x6d (Backlight Level: Red          ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x6e - Video black level: Green:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x6e
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149da0
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149da0 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 6e 00 00 64 00 32 8c 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x6e. *ppinterpreted_code=0x557eaa149d10
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x32, max value=100, cur value=50
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x6e, mh=0x00, ml=0x64, sh=0x00, sl=0x32, max_val=100 (0x0064), cur_val=50 (0x0032)
VCP code 0x6e (Video black level: Green      ): current value =    50, max value =   100

Getting data for non-table VCP code 0x6f - Backlight Level: Green:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x6f
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d10
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d10 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x6f (Backlight Level: Green        ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x70 - Video black level: Blue:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x70
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d10
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d10 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 88 02 00 70 00 00 64 00 32 92 6e
(ddc_get_nontable_vcp_value    )           Success reading feature x70. *ppinterpreted_code=0x557eaa149d30
(ddc_get_nontable_vcp_value    )           mh=0x00, ml=0x64, sh=0x00, sl=0x32, max value=100, cur value=50
(ddc_get_nontable_vcp_value    ) Done      Returning: NULL. 
Raw value: opcode=0x70, mh=0x00, ml=0x64, sh=0x00, sl=0x32, max_val=100 (0x0064), cur_val=50 (0x0032)
VCP code 0x70 (Video black level: Blue       ): current value =    50, max value =   100

Getting data for non-table VCP code 0x71 - Backlight Level: Blue:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x71
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x71 (Backlight Level: Blue         ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x72 - Gamma:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x72
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x72 (Gamma                         ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x8a - TV Color Saturation:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x8a
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x8a (TV Color Saturation           ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x90 - Hue:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x90
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x90 (Hue                           ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x9b - 6 axis hue control: Red:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x9b
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x9b (6 axis hue control: Red       ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x9c - 6 axis hue control: Yellow:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x9c
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x9c (6 axis hue control: Yellow    ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x9d - 6 axis hue control: Green:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x9d
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x9d (6 axis hue control: Green     ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x9e - 6 axis hue control: Cyan:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x9e
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x9e (6 axis hue control: Cyan      ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0x9f - 6 axis hue control: Blue:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0x9f
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0x9f (6 axis hue control: Blue      ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0xa0 - 6 axis hue control: Magenta:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0xa0
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0xa0 (6 axis hue control: Magenta   ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

Getting data for non-table VCP code 0xdc - Display Mode:
(ddc_get_nontable_vcp_value    ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x557eaa147750], Reading feature 0xdc
(i2c_ioctl_reader1             ) Starting  fd=3, fn=/dev/i2c-1, slave_addr=0x37, bytect=12, readbuf=0x557eaa149d30
   i2c_rdwr_ioctl_data at: 0x7ffc4376a380
      nmsgs:    1
      i2c_msg[0]
         addr:     0x0037
         flags:    0x0001
         len:     0x000c (12)
         buf:     0x557eaa149d30 ->  00 00 00 00 00 00 00 00 00 00 00 00
(i2c_ioctl_reader1             ) Done      Returning: OK(0). readbuf: 6e 80 be 6e 80 be 6e 80 be 6e 80 be
(ddc_get_nontable_vcp_value    )           ddc_write_read_with_retry() returned DDCRC_ALL_RESPONSES_NULL(-3011): all tries returned DDC Null Message, response_packet_ptr=(nil)
(ddc_get_nontable_vcp_value    ) Done      Returning: Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE]. 
VCP code 0xdc (Display Mode                  ): Invalid response. status code=DDCRC_ALL_RESPONSES_NULL(-3011), Display_Handle[i2c-1: fd=3 @0x557eaa147750]

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

The conundrum in this situation is how best to handle a Null Response. Does a particular Null Response indicate an unsupported feature or a monitor error. If the former, repeatedly retrying for the latter needlessly increases execution time and can drive up the sleep-multiplier calculated by dynamic sleep.

Could the optimisation of sleep interval be performed only when commands refer to basic-features, such as brightness and contrast, or known-to-be-supported features?

Known-to-be-supported features could be dynamically discovered by accumulating a list of successfully used features over time (as the user issues commands for them). This would build up a list of features eligible to participate in sleep interval optimisation. If it's true that a suitable sleep interval is common to all features, the known-list could determine the default sleep interval for the as yet untried commands, so all commands tried/untried would benefit from the current optimised value.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024
% rm -rf ~/.cache/ddcutil ; ~/bin/ddcutil --bus 1  capabilities
ddcutil: dsa2.c:866: dsa2_record_final: Assertion `( (rtable->cur_retry_loop_null_msg_ct > 0) && (null_adjustment_occurred) ) || ( !(rtable->cur_retry_loop_null_msg_ct > 0) && !(null_adjustment_occurred) )' failed.
[1]    6884 IOT instruction (core dumped)  ~/bin/ddcutil --bus 1 capabilities

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Also fails the same assertion for getvcp 10 if the monitor is connected but powered off. Does successfully do getvcp 10 if it's powered on.

A setvcp 10 100 completes without error no matter whether the power is on or off (which is true for ddcutil 1.4 as well, so it's OK). (In fact, in version 1.4, getvcp 10 returns a value even if the power off).

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

@digitaltrails The most recent commits should fix the assert problem you're seeing. If not, please run with --trcfunc dsa2_record_final --trcfunc adjust_sleep_time. Thanks.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Still asserting:

% rm -rf ~/.cache/ddcutil ; src/ddcutil --trcfunc dsa2_record_final --trcfunc adjust_sleep_time  --bus 1  capabilities 2>&1 | tee assert.log
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(dsa2_record_final             ) Starting  busno=1, rtable=0x5626a51a3e60, ddcrc=OK(0): success, tries=1 dsa2_enabled=true, cur_loop_null_adjustment_occurred=false
(dsa2_record_final             )           cur_step=7, cur_retry_loop_step=7, cur_retry_loop_null_msg_ct=0, null_msg_max_step_for_success=-1
(dsa2_record_final             ) Done      busno=1, cur_step=7, cur_retry_loop_step=7, remaining_interval=3
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             )           Adding 25 milliseconds for 1 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=75 
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=25, Returning: 75, *null_adjustment_added_loc-true
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             )           Adding 25 milliseconds for 1 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=75 
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=25, Returning: 75, *null_adjustment_added_loc-true
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             )           Adding 100 milliseconds for 2 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=150 
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=100, Returning: 150, *null_adjustment_added_loc-true
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             )           Adding 100 milliseconds for 2 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=150 
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=100, Returning: 150, *null_adjustment_added_loc-true
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             )           Adding 200 milliseconds for 3 Null response(s), busno=1, event_type=SE_WRITE_TO_READ, adjusted_sleep_time=250 
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=200, Returning: 250, *null_adjustment_added_loc-true
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             )           Adding 200 milliseconds for 3 Null response(s), busno=1, event_type=SE_POST_READ, adjusted_sleep_time=250 
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=200, Returning: 250, *null_adjustment_added_loc-true
(dsa2_record_final             ) Starting  busno=1, rtable=0x5626a51a3e60, ddcrc=DDCRC_NULL_RESPONSE(-3002): received DDC null response, tries=5 dsa2_enabled=true, cur_loop_null_adjustment_occurred=true
(dsa2_record_final             )           cur_step=7, cur_retry_loop_step=7, cur_retry_loop_null_msg_ct=4, null_msg_max_step_for_success=7
(dsa2_record_final             )           all tries failed. busno=1, New cur_step: 8
(dsa2_record_final             ) Done      busno=1, cur_step=8, cur_retry_loop_step=8, remaining_interval=3
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a3cd0], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(dsa2_record_final             ) Starting  busno=1, rtable=0x5626a51a3e60, ddcrc=OK(0): success, tries=1 dsa2_enabled=true, cur_loop_null_adjustment_occurred=false
(dsa2_record_final             )           cur_step=8, cur_retry_loop_step=8, cur_retry_loop_null_msg_ct=0, null_msg_max_step_for_success=7
(dsa2_record_final             ) Done      busno=1, cur_step=8, cur_retry_loop_step=8, remaining_interval=3
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_PRE_MULTI_PART_READ, spec_sleep_time_millis=200, msg=Before reading capabilities
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 200, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 259, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(dsa2_record_final             ) Starting  busno=1, rtable=0x5626a51a3e60, ddcrc=OK(0): success, tries=1 dsa2_enabled=true, cur_loop_null_adjustment_occurred=false
(dsa2_record_final             )           cur_step=8, cur_retry_loop_step=8, cur_retry_loop_null_msg_ct=0, null_msg_max_step_for_success=7
(dsa2_record_final             ) Done      busno=1, cur_step=8, cur_retry_loop_step=8, remaining_interval=3
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_CAP_TABLE_SEGMENT, spec_sleep_time_millis=50, msg=Called from try_multi_part_read, request_subtype=0x00
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(dsa2_record_final             ) Starting  busno=1, rtable=0x5626a51a3e60, ddcrc=OK(0): success, tries=1 dsa2_enabled=true, cur_loop_null_adjustment_occurred=false
(dsa2_record_final             )           cur_step=8, cur_retry_loop_step=8, cur_retry_loop_null_msg_ct=0, null_msg_max_step_for_success=7
(dsa2_record_final             ) Done      busno=1, cur_step=8, cur_retry_loop_step=8, remaining_interval=3
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_CAP_TABLE_SEGMENT, spec_sleep_time_millis=50, msg=Called from try_multi_part_read, request_subtype=0x00
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.30, null_adjustment_millis=0, Returning: 64, *null_adjustment_added_loc-false
(dsa2_record_final             ) Starting  busno=1, rtable=0x5626a51a3e60, ddcrc=OK(0): success, tries=1 dsa2_enabled=true, cur_loop_null_adjustment_occurred=false
(dsa2_record_final             )           cur_step=8, cur_retry_loop_step=8, cur_retry_loop_null_msg_ct=0, null_msg_max_step_for_success=7
(dsa2_record_final             ) Done      busno=1, cur_step=7, cur_retry_loop_step=7, remaining_interval=3
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_CAP_TABLE_SEGMENT, spec_sleep_time_millis=50, msg=Called from try_multi_part_read, request_subtype=0x00
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 1.00, null_adjustment_millis=0, Returning: 50, *null_adjustment_added_loc-false
(dsa2_record_final             ) Starting  busno=1, rtable=0x5626a51a3e60, ddcrc=OK(0): success, tries=1 dsa2_enabled=true, cur_loop_null_adjustment_occurred=false
(dsa2_record_final             )           cur_step=7, cur_retry_loop_step=7, cur_retry_loop_null_msg_ct=0, null_msg_max_step_for_success=7
(dsa2_record_final             ) Done      busno=1, cur_step=6, cur_retry_loop_step=6, remaining_interval=3
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_CAP_TABLE_SEGMENT, spec_sleep_time_millis=50, msg=Called from try_multi_part_read, request_subtype=0x00
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 0.70, null_adjustment_millis=0, Returning: 34, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_WRITE_TO_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 0.70, null_adjustment_millis=0, Returning: 34, *null_adjustment_added_loc-false
(adjust_sleep_time             ) Starting  dh=Display_Handle[i2c-1: fd=3 @0x5626a51a5c40], event_type=SE_POST_READ, spec_sleep_time_millis=50, msg=(null)
(adjust_sleep_time             ) Done      spec_sleep_time_millis = 50, dsa_multiplier= 0.70, null_adjustment_millis=0, Returning: 34, *null_adjustment_added_loc-false
(dsa2_record_final             ) Starting  busno=1, rtable=0x5626a51a3e60, ddcrc=DDCRC_NULL_RESPONSE(-3002): received DDC null response, tries=1 dsa2_enabled=true, cur_loop_null_adjustment_occurred=false
(dsa2_record_final             )           cur_step=6, cur_retry_loop_step=6, cur_retry_loop_null_msg_ct=1, null_msg_max_step_for_success=7
ddcutil: dsa2.c:873: dsa2_record_final: Assertion `( (rtable->cur_retry_loop_null_msg_ct > 0) && (cur_loop_null_adjustment_occurred) ) || ( !(rtable->cur_retry_loop_null_msg_ct > 0) && !(cur_loop_null_adjustment_occurred) )' failed.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

@digitaltrails Another large set of changes in 2.0.0-dev for testing. It fixes the assertion error you noted, and also makes extensive changes to the dynamic sleep code.

I've added code that converts getvcp reply messages with the Unsupported Feature bit set to DDC Null Messages for simulating monitors that use the Null Message to indicate an unsupported feature, allowing me to test for this monitor behaviour. (FWIW, it's controlled by the godawfully named hidden option --force-null-msg-for-unsupported.) There's some more checking to better handle the Null Msg response in this ambiguous case. Hopefully it better handles your Benq.

Current relevant experimental options:

  • --f10 - Extended sleep following Null Message - adds an additional 25, 100, or 200 ms to subsequent sleeps (independent of dynamic sleep, but more useful when dynamic sleep disabled)
  • --i2 Sleep for this number of millseconds between multi-part-read loops that attempt to assemble the entire capabilities string if a Null Message occurs

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I rescued the Beng, my sister-in-law was taking to the dump for recycling. Maybe recycling would have been for the best. But there has been some progress:

The capabilities command now works out of the box, nothing special required, and repeats fine too:

rm -rf ~/.cache/ddcutil; ~/bin/ddcutil --bus 1 capabilities; ~/bin/ddcutil --bus 1 capabilities

I also looped 50 setvcp/getvcp 10 commands, with no issues, no error messages, and nothing logged. Plus vdu_controls seems to working fine with it.

I've only been given a brief shake out, but it's looking good so far.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

--f10 makes the Beng much more laggy (when dynamic sleep is enabled). The Beng is mostly OK without it. I'm getting the odd error when dragging the brightness slider, but strangely, not with the looping getvcp/setvcp bash-script.

The errors might have something to do with background threads also accessing ddcutil - vdu_controls uses a lock to prevent concurrent use of ddcutil, perhaps it's rapid sequential use (perhaps its more rapid than a script). It's very rare, the Beng is a bit of a clunker, perhaps that's just the way things are.

09:45:14 DEBUG: subprocess result: error  Display-2 ddcutil --enable-dynamic-sleep --force setvcp 10 90 --edid 00ffffffffffff0009d12677455400... stderr='Verification failed for feature 10
', exception=Command '['ddcutil', '--enable-dynamic-sleep', '--force', 'setvcp', '10', '90', '--edid', '00ffffffffffff0009d12677455400003312010380301b782e3581a656489a24125054a54b00714f8180d1c001010101010101010101023a801871382d40582c4500dd0c1100001e000000ff003243383033353237534c300a0a000000fd00384c1e5311000a202020202020000000fc0042656e5120543232303048440a002a']' returned non-zero exit status 1.
09:45:14 DEBUG: TRACEBACK:   File "/home/michael/Projects/vdu_controls/vdu_controls.py", line 7495, in <module>

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

@digitaltrails I'm so glad you rescued the Benq from the dump. It's really helpful (for me at least) that you have a reliably unreliable monitor to test against. I should think that's helpful for vdu_controls as well.

Have you tested trying to getvcp unsupported feature codes on this monitor.?

I'm not surprised that the --f10 option makes ddcutil perceptibly slower. It uses a few extremely long sleeps attempting to recover from a Null Message. It's a vestige of an early dynamic sleep implementation

Concurrency is a nasty problem. libddcutil allows only one of its threads to "open" a /dev/i2c device. However, there's no concurrency checking across multiple libddcutil and ddcutil instances, let alone versus other applications. Down the line I'd like to create a daemon version of libddcutil, but that's way down the line.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I'm seeing a lot of these in the systemd journal from when my monitors are suspended:

busno=3, Testing for unsupported feature 0x41 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]

By suspended I mean from doing:

loginctl lock-session
xset dpms force suspend

The light metering and sun-angle scheduling in vdu_controls continues running during "suspend".

My LG 4K is on bus-3 (if that's USB bus), so it's not really Beng related.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

@digitaltrails I'm so glad you rescued the Benq from the dump. It's really helpful (for me at least) that you have a reliably unreliable monitor to test against. I should think that's helpful for vdu_controls as well.

Yes, it turned out to be a good last minute intervention.

Have you tested trying to getvcp unsupported feature codes on this monitor.?

I just did a getvcp 22, it reported

VCP code 0x22 (Horizontal Size               ): Unsupported feature code ((null))

I'm not surprised that the --f10 option makes ddcutil perceptibly slower. It uses a few extremely long sleeps attempting to recover from a Null Message. It's a vestige of an early dynamic sleep implementation

Fortunately it doesn't appear to be needed. The number of errors from the Beng has dropped to quite infrequent - as least as far as using vdu_controls is concerned. The current dsa file, in case it's of interest (the beng is i2c-1):

FORMAT 2
* DEV  /dev/i2c device
* EC   EDID check sum byte
* C    current step
* I    interval remaining
* L    current lookback
* DEV EC C I L Values
* Values {tries required, step, epoch seconds}
i2c-0 3d 0 3 5 {1,0,1689902541} {1,0,1689902541} {1,0,1689902541} {1,0,1689902542} {1,0,1689902542} {1,0,1689902542} {1,0,1689902542} {1,0,1689902543} {1,0,1689902543} {1,0,1689902543} {1,0,1689902609} {1,0,1689902609} {1,0,1689902609} {1,0,1689902610} {1,0,1689902610} {1,0,1689902610} {1,0,1689902610} {1,0,1689902611} {1,0,1689902611} {1,0,1689902611}
i2c-1 2a 6 3 20 {1,7,1689902474} {1,6,1689902474} {1,7,1689902475} {1,6,1689902475} {1,5,1689902475} {1,7,1689902476} {1,6,1689902541} {1,7,1689902542} {1,6,1689902542} {1,7,1689902543} {1,6,1689902543} {1,5,1689902543} {1,7,1689902544} {1,6,1689902609} {1,7,1689902610} {1,6,1689902610} {1,7,1689902611} {1,6,1689902611} {1,5,1689902611} {1,7,1689902612}
i2c-3 9e 0 3 5 {1,0,1689902542} {1,0,1689902542} {1,0,1689902542} {1,0,1689902543} {1,0,1689902543} {1,0,1689902543} {1,0,1689902544} {1,0,1689902544} {1,0,1689902544} {1,0,1689902544} {1,0,1689902610} {1,0,1689902610} {1,0,1689902610} {1,0,1689902611} {1,0,1689902611} {1,0,1689902611} {1,0,1689902612} {1,0,1689902612} {1,0,1689902612} {1,0,1689902612}

Concurrency is a nasty problem. libddcutil allows only one of its threads to "open" a /dev/i2c device. However, there's no concurrency checking across multiple libddcutil and ddcutil instances, let alone versus other applications. Down the line I'd like to create a daemon version of libddcutil, but that's way down the line.

If it was just a Linux oriented daemon, a dbus based daemon might fit in.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

The x41 error is perplexing. We know the LG monitor properly reports unsupported features. We only test for unsupported features after an always good feature (x10) is checked. So it surprises me that the x10 check apparently produced a valid response, but the x41 test did not. The error should be benign. ddcutil sets the normal flag DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED in this situation.

The next batch of changes will include additional syslog messages for the relevant sections of code. For now, what happens if you disable dynamic sleep and instead set a relatively high (1.0ish) sleep-multiplier value? Do you still see the messages?

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

The x41 error is perplexing. We know the LG monitor properly reports unsupported features. We only test for unsupported features after an always good feature (x10) is checked. So it surprises me that the x10 check apparently produced a valid response, but the x41 test did not. The error should be benign. ddcutil sets the normal flag DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED in this situation.

The next batch of changes will include additional syslog messages for the relevant sections of code. For now, what happens if you disable dynamic sleep and instead set a relatively high (1.0ish) sleep-multiplier value? Do you still see the messages?

I've seen my HP monitor (bus-0) report a few of these today, not as many as the LG. As you suggest, I will disable dynamic sleep and see if the errors go away.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

The x41 error is perplexing. We know the LG monitor properly reports unsupported features. We only test for unsupported features after an always good feature (x10) is checked. So it surprises me that the x10 check apparently produced a valid response, but the x41 test did not. The error should be benign. ddcutil sets the normal flag DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED in this situation.
The next batch of changes will include additional syslog messages for the relevant sections of code. For now, what happens if you disable dynamic sleep and instead set a relatively high (1.0ish) sleep-multiplier value? Do you still see the messages?

I've seen my HP monitor (bus-0) report a few of these today, not as many as the LG. As you suggest, I will disable dynamic sleep and see if the errors go away.

These errors are still happening with dynamic sleep disabled, but as I mentioned before, I think it's when the LG is asleep (xset dpms force suspend).

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

That's useful to know. It strongly suggests the problem is associated with the monitor being suspended.

I've added more syslog messages in the monitor detection code to better understand what is going on. Be sure to run with option --syslog debug to ensure that all possible syslog messages are emitted.

I've also added another pair of experimental options to dynamic sleep. Option --i1 specifies the minimum multiplier step allowed. Option --fl1 specifies a minimum multiplier value, which is converted to a step. By default, the minimum multiplier step is 0. The intent is twofold. First, reduce jitter in the multiplier step. The second is to reduce the (very unlikely) possibility of maximum retries for DDC Null Message being exceeded when in fact it is recoverable.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

I put the HP and LG monitors into dpms force suspend at around 3pm and went away for a cup of tea. The log accumulated the following in repeats until I returned (this would be with dynamic sleep enabled):

Jul 23 15:03:46  ddcutil[32544]: busno=3, sleep-multiplier =  2.00. Testing for supported feature 0x10 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:03:48  ddcutil[32544]: busno=3, sleep-multiplier= 1.00. Retesting for supported feature 0x10 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:03:49  ddcutil[32544]: busno=3, sleep-multiplier= 1.00, Testing for unsupported feature 0x41 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:03:51  ddcutil[32544]: busno=3, sleep-multiplier= 1.00, Testing for unsupported feature 0xdd returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:03:52  ddcutil[32544]: busno=3, sleep-multiplier= 1.00, Testing for unsupported feature 0x00 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:03:52  ddcutil[32544]: busno=3, DDCRC_RETRIES failure reading all unsupported features. Setting DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED
Jul 23 15:03:56  ddcutil[32567]: busno=3, sleep-multiplier =  2.00. Testing for supported feature 0x10 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:03:58  ddcutil[32567]: busno=3, sleep-multiplier= 1.00. Retesting for supported feature 0x10 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:03:59  ddcutil[32567]: busno=3, sleep-multiplier= 1.00, Testing for unsupported feature 0x41 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:04:00  ddcutil[32567]: busno=3, sleep-multiplier= 1.00, Testing for unsupported feature 0xdd returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:04:02  ddcutil[32567]: busno=3, sleep-multiplier= 1.00, Testing for unsupported feature 0x00 returned Error_Info[DDCRC_RETRIES in ddc_write_read_with_retry, causes: DDCRC_DDC_DATA(10)]
Jul 23 15:04:02  ddcutil[32567]: busno=3, DDCRC_RETRIES failure reading all unsupported features. Setting DREF_DDC_USES_DDC_FLAG_FOR_UNSUPPORTED``

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

That's actually a relief to know that a supported feature is failing similarly to the unsupported ones. But it looks like only one of the monitors was generating errors. From prior logs I assume that /dev/i2c-3 is the Benq.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

That's actually a relief to know that a supported feature is failing similarly to the unsupported ones. But it looks like only one of the monitors was generating errors. From prior logs I assume that /dev/i2c-3 is the Benq.

The Beng is i2c-3 on my old test machine. I added the Beng it to my main desktop to see if the GPU/GPU-driver change would make any difference (plus I needed to test vdu_controls with more than two monitors). On my main desktop, the LG is i2c-3, HP i2c-0, and Beng i2c-1. The errors only occur with the LG and only when in the state xset dpms force suspend. The ports on the GPU seem arbitrarily named because the BIOS chooses to use display i2c-3 which I presume is the first. Full ID details below.

Display 1
   I2C bus:  /dev/i2c-0
   DRM connector:           card0-DP-1
   EDID synopsis:
      Mfg id:               HWP - Hewlett Packard
      Model:                HP ZR24w
      Product code:         10345  (0x2869)
      Serial number:        CNT00811J6
      Binary serial number: 16843009 (0x01010101)
      Manufacture year:     2010,  Week: 8
   VCP version:         2.2

Display 2
   I2C bus:  /dev/i2c-1
   DRM connector:           card0-DP-2
   EDID synopsis:
      Mfg id:               BNQ - UNK
      Model:                BenQ T2200HD
      Product code:         30502  (0x7726)
      Serial number:        2C803527SL0
      Binary serial number: 21573 (0x00005445)
      Manufacture year:     2008,  Week: 51
   VCP version:         2.0

Display 3
   I2C bus:  /dev/i2c-3
   DRM connector:           card0-DP-3
   EDID synopsis:
      Mfg id:               GSM - Goldstar Company Ltd (LG)
      Model:                LG HDR 4K
      Product code:         30471  (0x7707)
      Serial number:        
      Binary serial number: 86395 (0x0001517b)
      Manufacture year:     2019,  Week: 4
   VCP version:         2.1

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

The LG is still getting the odd error from time to time when it isn't in power saving.

It might be happening when the desktop is a big bogged down with other stuff. I have a python script that raises selected syslog messages as KDE notifications. At the moment multiple notifications appear to slow the desktop (and also sometimes crash KWin - KDE bug?). Given ddcutil and vdu_controls are both logging to the journal at around the same time, that might be the trigger. In normal circumstances (no errors, less logging) this might not be an issue, but I'll note it here for completeness.

Journal Entry 2023-07-31 13:33:10.741768+12:00

MESSAGE                  : busno=3, sleep-multiplier =  0.30. Testing for supported feature 0x10 returned Error_Info[DDCRC_ALL_RESPONSES_NULL in ddc_write_read_with_retry, causes: DDCRC_NULL_RESPONSE(4)]
PRIORITY                 : 3
SYSLOG_FACILITY          : 1
SYSLOG_IDENTIFIER        : ddcutil
SYSLOG_PID               : 24636
SYSLOG_TIMESTAMP         : Jul 31 13:33:10 
_CMDLINE                 : ddcutil --enable-dynamic-sleep --force --brief getvcp 10 --edid 00ffffffffffff0022f069280101010108140104a53623782efc81a4554d9d25125054210800814081809500a940b300d1c001010101283c80a070b023403020360022602100001a000000fd003b3d185011000a202020202020000000fc004850205a523234770a20202020000000ff00434e5430303831314a360a2020003d
_COMM                    : ddcutil
_EXE                     : /home/michael/bin/ddcutil.latest

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

Hi Michael,

Not sure what to make of your report, but I appreciate your bringing it up. Hard to believe that it's a syslog issue - that's a mature, battle-hardened subsystem. Since only vdu_controls is reading the journalctl output I don't see that it and ddcutil are conflicting. Keep me posted.

On the off-chance there's some interaction between ddcutil's and vdu_control's use of the system log, I've added yet another option that has not yet been pushed to github, --pid/--process-id prepends messages written using syslog with the process id enclosed in curly braces. I believe both programs are executing in the same process, but you may want to check.

There is a very large accumulation of changes that have not yet been pushed to github. I'm still struggling with how to reliably detect dpms sleep mode, display connection/disconnection, and non-standard ways of reporting unsupported features, with variation in monitors, video cards, drivers (Nvidia vs open-source DRM vs non-DRM), display manager (X11 vs Wayland vs none) . Whenever I come up with an algorithm to make a determination, there always seems to be some monitor/video card/driver/display manager combination that breaks the rule. Hopefully things will sort out soon and I'll have something for you to test against.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

Hi Michael,

Not sure what to make of your report, but I appreciate your bringing it up. Hard to believe that it's a syslog issue - that's a mature, battle-hardened subsystem. Since only vdu_controls is reading the journalctl output I don't see that it and ddcutil are conflicting. Keep me posted.

It's more that I suspect that KDE's handling of message popups with timeouts is possibly bogging down my system (or at least X-Windows/interrupts/...). So the journal is not the problem. This problem is triggered because I wrote a program to forward selected journal messages as KDE Plasma popups with timeouts (these timeout popups have been buggy/slow/cpu-burning in the past, but I thought they'd got past that).

The takeaway is that sometimes ddcutil might error due to delays from other things going on, possibly delaying handling of messages on i2c.

On the off-chance there's some interaction between ddcutil's and vdu_control's use of the system log, I've added yet another option that has not yet been pushed to github, --pid/--process-id prepends messages written using syslog with the process id enclosed in curly braces. I believe both programs are executing in the same process, but you may want to check.

So I don't mean that you needed to specifically address this issue. Just that, more generally, a bogged down system might cause ddcutil issues when trying to talk to a monitor (if timings of responses are important to the exchange).

There is a very large accumulation of changes that have not yet been pushed to github. I'm still struggling with how to reliably detect dpms sleep mode, display connection/disconnection, and non-standard ways of reporting unsupported features, with variation in monitors, video cards, drivers (Nvidia vs open-source DRM vs non-DRM), display manager (X11 vs Wayland vs none) . Whenever I come up with an algorithm to make a determination, there always seems to be some monitor/video card/driver/display manager combination that breaks the rule. Hopefully things will sort out soon and I've something for you to test against.

Generally what's in place now works. When not in dpms, I'm only seeing the odd rare error. Presumably a bad luck timing issue caused by some issue such as I've described above. vdu_controls generally tries a few times and backs off, either giving up or retrying every minute.

If you want to eliminate these normal non-dpms odd-errors, the sleep time might have to hold back a little from the optimum. But perhaps it's the nature of DDC to get the odd error. I may have been getting the odd error before, but because they weren't appearing in the journal, I would not have noticed.

Bottom line:

  • When not in dpms sleep, there's nothing to address if the odd error is acceptable/normal.
  • When in dpms sleep, monitors behave very differently, so I'm not sure you can reliably deal with that. I guess you might cache some record of what is normal for a given monitor when it is awake, and when you get "abnormal" response assume it is sleeping. For example if a monitor ever properly handles testing for supported/unsupported features, cache that it responds properly, then assume future errors are due to it being in a non-awake state.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

First, a couple of quick comments on your detailed message:

As DDC communication errors are expected, the extent to which errors are reported in the journal is controlled by syslog level.

Re DPMS sleep, for X11 the check is simple. There's an X11 API call (the equivalent of xset q) to check for sleep mode.
In Wayland, it's more complicated. Querying that information for individual displays is non-trivial. For example, KWwin and Gnome each have their code to perform the task. Writing my own code for this would be a non-trivial project.

So for Wayland, or if there's no display manager, and assuming a DRM video driver, I look in syssfs using the individual monitor's connector, e.g. card0-DP-1. For amdgpu, i915, and I assume other DRM video drivers in the open source tree,
attribute dpms can be relied on. However, the Nvidia driver does not use this attribute in the same way, so (at least at this point) DPMS detection for does not work in the Nvidia/Wayland or Nvidia/no-display-manager cases. Nor does it work for the various no-display-manager/non-standard-drm cases. But these are rare.

Handling monitor detedtion where the monitor video cable is connected but the monitor's power button is turned off or the monitor is even unplugged is nasty. In general monitors always return the EDID in these cases - the EDID PROM is powered from the cable. However, for some monitors and depending on the plugged-in/power- button-on, plugged-in/power-button-off, and not-plugged-in. the monitor may or may not respond to DDC requests. This complicates (future) hot-plug handling, which is important for the shared library.

I have pushed a large collection of changes that address these and other situations. In particular:

  • For testing purposes, --f12 controls whether X11 DPMS checking is enabled. If not, the more complicated non-X11 logic is used.
  • Option --fl1 sets a value below which dynamic sleep will not set the sleep-multiplier value. If it proves useful, this will become option --sleep-multiplier-floor. In particular, this is intended to address the jitter where after a string of successes dsa tries setting a lower sleep-multiplier value, causing enough errors for the sleep-multiplier value to jump, only to slowly be adjusted back down again. Unfortunately, there's no universal sleep-multiplier floor value that can be hardcoded - it's monitor dependant.
  • --enable-dsa is now a synonym for --enable-dynamic-sleep.
  • --discard-cache [capabilities|dsa|all] discards cached data at the start of command execution. There's also command discard [capabilities|dsa|all] cache[s], but unless it is particularly useful it will eliminated in favour of the option.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

First, a couple of quick comments on your detailed message:

As DDC communication errors are expected, the extent to which errors are reported in the journal is controlled by syslog level.

What I may do is pass --syslog NEVER unless debug is enabled in vdu_controls.

Re DPMS sleep, for X11 the check is simple. There's an X11 API call (the equivalent of xset q) to check for sleep mode. In Wayland, it's more complicated. Querying that information for individual displays is non-trivial. For example, KWwin and Gnome each have their code to perform the task. Writing my own code for this would be a non-trivial project.

Practically speaking, from the point of view of a vdu_controls user, the only fallout from continuing to issue ddcutil commands when a monitor is asleep/powered-off/unplugged is that extra messages are logged. So disabling logging when no debugging would deal with those.

So for Wayland, or if there's no display manager, and assuming a DRM video driver, I look in syssfs using the individual monitor's connector, e.g. card0-DP-1. For amdgpu, i915, and I assume other DRM video drivers in the open source tree, attribute dpms can be relied on. However, the Nvidia driver does not use this attribute in the same way, so (at least at this point) DPMS detection for does not work in the Nvidia/Wayland or Nvidia/no-display-manager cases. Nor does it work for the various no-display-manager/non-standard-drm cases. But these are rare.

Handling monitor detedtion where the monitor video cable is connected but the monitor's power button is turned off or the monitor is even unplugged is nasty. In general monitors always return the EDID in these cases - the EDID PROM is powered from the cable. However, for some monitors and depending on the plugged-in/power- button-on, plugged-in/power-button-off, and not-plugged-in. the monitor may or may not respond to DDC requests. This complicates (future) hot-plug handling, which is important for the shared library.

Yes, I'm seeing quite varied behaviour from the LG, HP, and Beng. I haven't had any issues raised due these kinds of issues. So correct detection is these situations is a nice to have, but users seem to be coping OK with things the way they are.

I guess errors in these situations raises the dynamic sleep multiplier? I can't say I've been noticed any lack of responsiveness after any monitor dpms or power-off downtime.

I have pushed a large collection of changes that address these and other situations. In particular:

  • For testing purposes, --f12 controls whether X11 DPMS checking is enabled. If not, the more complicated non-X11 logic is used.

I'll have a play with it on/off.

  • Option --fl1 sets a value below which dynamic sleep will not set the sleep-multiplier value. If it proves useful, this will become option --sleep-multiplier-floor. In particular, this is intended to address the jitter where after a string of successes dsa tries setting a lower sleep-multiplier value, causing enough errors for the sleep-multiplier value to jump, only to slowly be adjusted back down again. Unfortunately, there's no universal sleep-multiplier floor value that can be hardcoded - it's monitor dependant.

This might be a parameter I could use. Currently if dynamic sleep is enabled, I disable passing any vdu_control sleep-multiplier settings. It's possible I could use the existing vdu_controls multipliers setting as a floor. However, on detecting ddcutil 2.0, ignoring the current multipliers has the major advantage than when a user will get improved response without having to change any setting in vdu_controls.

I do have a setting prefer-dynamic-sleep, it's True by default. Currently, if prefer-dynamic-sleep is set to False and a vdu has a non-zero sleep-multiplier, then vdu_controls passes ddcutil --disable-dynamic-sleep --sleep-multiplier val. Instead of disabling dynamic sleep I could pass ddcutil --enable-dynamic-sleep and --fl1 val.

I'd be prepared to accept jitter is the price to pay for faster performance. I've been using ddcutil 2.0-dev as my daily-driver, and it's not causing me any issues. But people who have written ddcutil based scripts might need something like --fl1

  • --enable-dsa is now a synonym for --enable-dynamic-sleep.
  • --discard-cache [capabilities|dsa|all] discards cached data at the start of command execution. There's also command discard [capabilities|dsa|all] cache[s], but unless it is particularly useful it will eliminated in favour of the option.

Discard cache is going to be handy for testing. Plus it's easier to instruct a user to pass --discard-cache than to describe how to do it manually.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

One further note. Would a ddcutil --calibrate command be a way to set a lower bound on dynamic sleep and perhaps also to discover how a monitor responds to feature requests? It would have an advantage of being something that can be run in stable circumstances.

from ddcutil.

rockowitz avatar rockowitz commented on June 25, 2024

I don't quite see what a calibrate command would do that's fundamentally different from the kind of computations that dsa currently performs, checking back over recent operations to pick a multiplier that results in no more than a maximum number of errors or more than a certain average. What I can see is maintaining meta statistics relating to jitter. For example, if reducing the sleep multiplier past a certain level "immediately" causes another change to increase the multiplier value, then that becomes a floor. The problem is that it needs to be a soft floor. Otherwise, over time the minimum sleep-multiplier can only increase.

I've made another small change to the detect command. If dsa is enabled, verbose output reports the current sleep-multiplier.

from ddcutil.

digitaltrails avatar digitaltrails commented on June 25, 2024

from ddcutil.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.