Use at your own risk. This worked on my monitor, but there is no guarantee it works on yours. It writes to the monitor's settings EEPROM. See the disclaimer at the bottom.
- Pressing the joystick to open the on-screen menu (OSD) turns the screen black for ~2 seconds. Then the picture comes back, but no menu.
- Happens on every input (DP, HDMI) and every source device.
- It typically starts after a DDC/CI tool was used, for example a brightness app like Monitorian, Twinkle Tray, ClickMonitorDDC,
ddcutil, or anything with a "turn display off" function. - Factory reset isn't possible because you can't reach the menu. Power-cycling doesn't help.
Tested on: EDID XMI "Mi Monitor", product code 0x3444, MStar MST9U scaler, built 2020. Other Mi monitors with the same MStar firmware might be affected. The script checks before it changes anything.
The monitor firmware has a bug in its handler for the DDC/CI power mode command (VCP 0xD6):
- When the monitor receives
D6with almost any value while it's on (includingD6 01= "on" andD6 04= "off", which DDC tools send), it sets a "power-down requested via DDC" flag. That's bit0x10of settings byte0x43. The value check is broken: it accepts everything except 5. - The flag is saved to the settings EEPROM, so it survives power-cycles.
- While the flag is set, the menu code doesn't open the OSD on a joystick press. It re-syncs the current input instead. That's the 2-second black screen.
- No reachable code ever clears the flag.
D6 05, the DDC factory reset (VCP04) and power-cycling don't touch it.
The fix is to clear that one bit in the EEPROM. The monitor itself provides vendor DDC commands to read and write its settings EEPROM (7B 99 22 read, 7B 99 55 write, 16 bytes at a time), so no hardware is needed.
You need a Linux machine (a live USB works) with the monitor connected by HDMI or DisplayPort directly to the GPU. Docks and adapters often don't pass DDC through. You also need Python 3 and ddcutil.
sudo modprobe i2c-dev
sudo ddcutil detectNote the I2C bus: /dev/i2c-N line of the "Mi Monitor" entry. N is your bus number.
If ddcutil reports "DDC communication failed", power-cycle the monitor and try again.
Download mi_monitor_osd_fix.py and run:
sudo python3 mi_monitor_osd_fix.py NThe script:
- reads the monitor's EDID and checks that bus
Nis the Mi Monitor (vendorXMI, product code0x3444). On any other monitor it prints a warning and aborts without sending any DDC command, - verifies it is talking to the expected firmware (EEPROM byte
0x00must be0x74; it aborts otherwise), - saves a backup of EEPROM
0x00–0xFFtomi_monitor_eeprom_0000-00ff_<timestamp>.bin, - reports byte
0x43.
If it says "bit 0x10 is NOT set", your problem is something else. Stop here.
Read this first: the monitor periodically saves its in-RAM settings back to the EEPROM. RAM still holds the old value until the next reboot. If you wait after writing, the periodic save will undo the fix. That happened during testing. So have the power cable within reach.
sudo python3 mi_monitor_osd_fix.py N --writeIt reads the 16-byte block at 0x40, clears only bit 0x10 of byte 0x43, writes the block back and reads it again to verify. When it prints OK:
- Immediately pull the monitor's power cable. Don't use the power button.
- Wait ~10 seconds, plug it back in.
- Press the joystick. The OSD should open.
If the OSD still goes black, run step 2 again. If byte 0x43 has 0x10 set again, you were too slow: repeat step 3.
Don't let DDC tools send VCP 0xD6 (power mode) to this monitor. Brightness, contrast and the other VCP codes are fine. In tools with a "turn off display via DDC" feature, disable that for this monitor.
| DDC read command | 51 86 03 7B 99 22 HH LL <chk> → reply 6E 92 <16 bytes> … |
| DDC write command | 51 96 03 7B 99 55 HH LL <16 bytes> <chk> |
| Address mapping | EEPROM address = (HH << 8) + LL + 0xAA4 (16-bit wrap, LL unsigned) |
| EEPROM layout | 0x000–0x03E factory/calibration, 0x03F–0x0E3 user settings, 0x0E4–… per-mode tables. Copied 1:1 into the firmware's settings struct |
| Bad flag | 0x43 bit 0x10, set in the VCP D6 handler, tested in the OSD key handler (keys 0–3 → input re-sync instead of menu), never cleared |
| Periodic save | the whole user block 0x3F–0xE3 is rewritten every 900 ticks of the power-on counter at 0x9E–0xA1 |
Found by dumping the SPI flash (read-only, via flashrom -p mstarddc_spi), decompressing the MStar main application (mstar_extract_decompress) and decompiling it with Ghidra and ghidra-aeon.
Disclaimer: this writes to your monitor's settings EEPROM. It worked on my unit, but there is no guarantee it will work on yours, and I can't promise it won't cause problems. The script refuses to write if anything looks unexpected and saves a backup first, but you use it entirely at your own risk. I'm not responsible for any damage to your monitor or data.
YOOOOOOO!!! I wonder if it will work with my 27 2k mi gaming monitor!!