加强一部分逻辑

This commit is contained in:
chenjiangqun
2026-06-30 18:59:22 +08:00
parent 6042411a01
commit 370ab2ea7c
2 changed files with 154 additions and 109 deletions

View File

@@ -520,85 +520,89 @@ namespace WinISP
private void QueryConnectedMonitorInfo()
{
// 读取显示器端信息(芯片名、面板名、板卡名、型号名)
try
{
bool isAmdOrIntel = IsAmdOrIntelPath();
bool legacyRemapped = false;
// 型号名
{
string rawModelName;
if (isAmdOrIntel)
rawModelName = ReadMonitorFieldRobust(CmdGetModelName, MonitorModelNameLength); // >>> A/I 走稳健版
else
{
// N 卡保持原逻辑
Byte[] cmd = { MStarCommand, CmdGetModelName };
Byte[] recv = MTKDebugCmd.DDC_Read(cmd, MonitorModelNameLength + 2, 500)
?? MTKDebugCmd.DDC_Read(cmd, MonitorModelNameLength + 2, 2000)
?? MTKDebugCmd.DDC_Read(cmd, MonitorModelNameLength + 2, 5000);
if (recv != null && recv.Length >= MonitorModelNameLength + 2)
{
string rawModelName = Encoding.ASCII.GetString(recv, 2, MonitorModelNameLength).TrimEnd('\0');
rawModelName = (recv != null && recv.Length >= MonitorModelNameLength + 2)
? Encoding.ASCII.GetString(recv, 2, MonitorModelNameLength).TrimEnd('\0')
: string.Empty;
}
if (string.Equals(rawModelName.Trim(), PlaceholderMonitorModelName, StringComparison.OrdinalIgnoreCase))
{
legacyRemapped = true;
_monitorModelName = LegacyMonitorModelName;
_monitorChipName = "MST9U";
_monitorPanelName = "Panel_SG315GD01_2_eDP";
WriteLog("Placeholder model detected, legacy remapping: " + rawModelName + " -> " + _monitorModelName + ", Chip=MST9U, Panel=Panel_SG315GD01_2_eDP", "debug");
WriteLog("Placeholder model detected, legacy remapping ...", "debug");
}
else
{
_monitorModelName = NormalizeMonitorModelName(rawModelName);
}
}
else
_monitorModelName = string.Empty;
}
// 芯片名
// 芯片名 / 面板名 / 板卡名A/I 卡同样走稳健版
if (!legacyRemapped)
{
Byte[] cmd = { MStarCommand, CmdGetChipName };
Byte[] recv = MTKDebugCmd.DDC_Read(cmd, MonitorChipNameLength + 2, 500)
?? MTKDebugCmd.DDC_Read(cmd, MonitorChipNameLength + 2, 2000)
?? MTKDebugCmd.DDC_Read(cmd, MonitorChipNameLength + 2, 5000);
if (recv != null && recv.Length >= MonitorChipNameLength + 2)
_monitorChipName = Encoding.ASCII.GetString(recv, 2, MonitorChipNameLength).TrimEnd('\0');
else
_monitorChipName = string.Empty;
}
// 面板名
if (!legacyRemapped)
{
Byte[] cmd = { MStarCommand, CmdGetPanelName };
Byte[] recv = MTKDebugCmd.DDC_Read(cmd, MonitorPanelNameLength + 2, 500)
?? MTKDebugCmd.DDC_Read(cmd, MonitorPanelNameLength + 2, 2000)
?? MTKDebugCmd.DDC_Read(cmd, MonitorPanelNameLength + 2, 5000);
if (recv != null && recv.Length >= MonitorPanelNameLength + 2)
_monitorPanelName = Encoding.ASCII.GetString(recv, 2, MonitorPanelNameLength).TrimEnd('\0');
else
_monitorPanelName = string.Empty;
}
// 板卡名
{
Byte[] cmd = { MStarCommand, CmdGetBoardName };
Byte[] recv = MTKDebugCmd.DDC_Read(cmd, MonitorBoardNameLength + 2, 500)
?? MTKDebugCmd.DDC_Read(cmd, MonitorBoardNameLength + 2, 2000)
?? MTKDebugCmd.DDC_Read(cmd, MonitorBoardNameLength + 2, 5000);
if (recv != null && recv.Length >= MonitorBoardNameLength + 2)
_monitorBoardName = Encoding.ASCII.GetString(recv, 2, MonitorBoardNameLength).TrimEnd('\0');
else
_monitorBoardName = string.Empty;
_monitorChipName = isAmdOrIntel ? ReadMonitorFieldRobust(CmdGetChipName, MonitorChipNameLength) : /* N卡原逻辑 */ _monitorChipName;
_monitorPanelName = isAmdOrIntel ? ReadMonitorFieldRobust(CmdGetPanelName, MonitorPanelNameLength) : /* N卡原逻辑 */ _monitorPanelName;
}
_monitorBoardName = isAmdOrIntel ? ReadMonitorFieldRobust(CmdGetBoardName, MonitorBoardNameLength) : /* N卡原逻辑 */ _monitorBoardName;
// 日志打印
WriteLog("MonitorModelName=" + _monitorModelName, "debug");
WriteLog("MonitorChipName=" + _monitorChipName, "debug");
WriteLog("MonitorPanelName=" + _monitorPanelName, "debug");
WriteLog("MonitorBoardName=" + _monitorBoardName, "debug");
WriteLog("MonitorModelName=" + _monitorModelName, "info");
WriteLog("MonitorChipName=" + _monitorChipName, "info");
WriteLog("MonitorPanelName=" + _monitorPanelName, "info");
WriteLog("MonitorBoardName=" + _monitorBoardName, "info");
}
catch (Exception ex)
{
WriteLog("QueryConnectedMonitorInfo Exception: " + ex.Message, "debug");
WriteLog("QueryConnectedMonitorInfo Exception: " + ex.Message, "error");
}
}
/// <summary>
/// AMD/Intel 友好的型号读取:带响应有效性校验 + 多轮重试。
/// AMD ADL DDC 读命中率低(约 4 错 1 对),需要足够重试次数才能读到完整字符串。
/// </summary>
private string ReadMonitorFieldRobust(byte subCmd, int expectLen, int maxRounds = 30)
{
string best = string.Empty;
for (int round = 0; round < maxRounds; round++)
{
// DDC_GetMonitorName 内部已做 recv[1]==0x80 过滤 + 找 \0 结束符
string v = DDC_GetMonitorName(subCmd, 300);
if (!string.IsNullOrWhiteSpace(v))
{
// 记录最长的结果AMD 可能先读到残片 "MA",后读到完整 "MAG 322URD16"
if (v.Length > best.Length)
{
best = v;
frmISP.WriteLog($"[AMD-Identity] cmd=0x{subCmd:X2} round#{round} got='{v}' (len={v.Length})", "debug");
}
// 完整性判断:读到的长度接近期望值,认为读全了,提前退出
if (v.Length >= expectLen - 2 || v.Length >= 6)
break;
}
WinIOLib.DelayMs(50); // AMD 通道恢复间隔
}
return best;
}
private void ClearConnectedMonitorInfo()
{
_monitorModelName = string.Empty;
@@ -618,13 +622,20 @@ namespace WinISP
if (_simI2cCtrl.Init() == true)
{
frmISP.WriteLog("simI2cCtrl.Init() = true", "debug");
switch (((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType)
// >>> 改动:缓存卡类型,避免反复强转 + 反复 DllGetGraphicCardType 调用
GraphicCardI2CCtrl.GRAPHIC_CARD cardType = ((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType;
bool isAmd = (cardType == GraphicCardI2CCtrl.GRAPHIC_CARD.AMD);
bool isIntel = (cardType == GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL)
|| (cardType == GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL_IGCL);
switch (cardType)
{
case GraphicCardI2CCtrl.GRAPHIC_CARD.AMD: { frmISP.WriteLog("GraphicCard=AMD", "debug"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL: { frmISP.WriteLog("GraphicCard=INTEL", "debug"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.NVIDIA: { frmISP.WriteLog("GraphicCard=NVIDIA", "debug"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL_IGCL: { frmISP.WriteLog("GraphicCard=INTEL-IGCL", "debug"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.NA: { frmISP.WriteLog("GraphicCard=UNKNOWN", "debug"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.AMD: { frmISP.WriteLog("GraphicCard=AMD", "info"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL: { frmISP.WriteLog("GraphicCard=INTEL", "info"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.NVIDIA: { frmISP.WriteLog("GraphicCard=NVIDIA", "info"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL_IGCL: { frmISP.WriteLog("GraphicCard=INTEL-IGCL", "info"); } break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.NA: { frmISP.WriteLog("GraphicCard=UNKNOWN", "warn"); } break;
}
if (((GraphicCardI2CCtrl)_simI2cCtrl).GetConnectedPortType == GraphicCardI2CCtrl.PortTypes.HDMI)
@@ -658,28 +669,24 @@ namespace WinISP
List<String> list = ((GraphicCardI2CCtrl)_simI2cCtrl).InitConnectedMonitor;
frmISP.WriteLog("InitConnectedMonitor count = " + list.Count, "debug");
if (list.Count == 0 && ((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType == GraphicCardI2CCtrl.GRAPHIC_CARD.AMD)
// >>> 改动AMD count=0 时不再切去 NVIDIA而是在 AMD 控制器上"等待+重新枚举"
// 原因:经日志确认本机就是 AMD 且 DDC 读写功能正常count=0 的真因是通道未就绪,
// 切换控制器是误诊,反复重建句柄反而引入不稳定。
if (list.Count == 0 && isAmd)
{
frmISP.WriteLog("InitConnectedMonitor = 0 on AMD auto-detect, trying forced NVIDIA controller ...", "debug");
((GraphicCardI2CCtrl)_simI2cCtrl).ReCreateGraphicCardCtrl(GraphicCardI2CCtrl.GPUTypes.NVIDIA);
WinIOLib.DelayMs(300);
if (_simI2cCtrl.Init())
const int MaxEnumRetry = 8;
const int EnumRetryDelayMs = 400;
for (int i = 0; i < MaxEnumRetry && list.Count == 0; i++)
{
list = ((GraphicCardI2CCtrl)_simI2cCtrl).InitConnectedMonitor;
frmISP.WriteLog("InitConnectedMonitor after forced NVIDIA count = " + list.Count, "debug");
}
if (list.Count == 0)
{
frmISP.WriteLog("Forced NVIDIA controller did not find monitors, restoring auto-detect controller ...", "debug");
((GraphicCardI2CCtrl)_simI2cCtrl).ReCreateGraphicCardCtrl();
WinIOLib.DelayMs(300);
if (_simI2cCtrl.Init())
frmISP.WriteLog($"[AMD-Enum] count=0, wait {EnumRetryDelayMs}ms then retry #{i + 1} (channel may not be ready)", "debug");
WinIOLib.DelayMs(EnumRetryDelayMs);
list = ((GraphicCardI2CCtrl)_simI2cCtrl).InitConnectedMonitor;
}
frmISP.WriteLog($"[AMD-Enum] final count = {list.Count} after retries", list.Count > 0 ? "info" : "error");
}
// NVIDIA DP AUX channel may not be ready on first launch retry with delay.
// (NVIDIA/其它卡路径保持原逻辑不变)
{
int mntRetry = 0;
while (list.Count == 0 && mntRetry++ < 3)
@@ -692,11 +699,11 @@ namespace WinISP
// If all retries exhausted and still no monitor, recreate the GPU control and try once more.
if (list.Count == 0)
{
frmISP.WriteLog("InitConnectedMonitor still 0 calling ReCreateGraphicCardCtrl ...", "debug");
frmISP.WriteLog("InitConnectedMonitor still 0 calling ReCreateGraphicCardCtrl ...", "warn");
((GraphicCardI2CCtrl)_simI2cCtrl).ReCreateGraphicCardCtrl();
WinIOLib.DelayMs(1500);
list = ((GraphicCardI2CCtrl)_simI2cCtrl).InitConnectedMonitor;
frmISP.WriteLog("InitConnectedMonitor after ReCreate count = " + list.Count, "debug");
frmISP.WriteLog("InitConnectedMonitor after ReCreate count = " + list.Count, "warn");
}
}
@@ -708,34 +715,55 @@ namespace WinISP
_selectedMonitorIndex = idxDisp;
((GraphicCardI2CCtrl)_simI2cCtrl).SetConnectedMonitorIndex((Byte)idxDisp);
// >>> 改动握手重试循环。关键修复——AMD 路径在每次失败后加延时,
// 给 DDC 通道就绪时间;其它卡保持原"快速 30 连试"行为不变。
while ((IsConnect == false) && (retry++ < 30))
{
IsConnect = DDC_CheckMTKDevice(ref chipType);
if (IsConnect)
break;
if (isAmd)
{
// AMD: 通道刚枚举出可能未就绪,慢节奏重试(前几次短,逐步拉长)
int wait = (retry < 5) ? 150 : 300;
frmISP.WriteLog($"[AMD-Ready] DDC_CheckMTKDevice not ready, retry#{retry}, wait {wait}ms", "debug");
WinIOLib.DelayMs(wait);
}
frmISP.WriteLog("idxDisp=" + idxDisp + " IsConnect=" + IsConnect + " chipType=" + chipType, "debug");
}
frmISP.WriteLog("idxDisp=" + idxDisp + " IsConnect=" + IsConnect + " chipType=" + chipType
+ " retryUsed=" + retry, IsConnect ? "info" : "warn"); // >>> 改动:成功/失败分级 + 记录用了几次重试
if (IsConnect == true)
{
break;
}
}
// >>> 改动AMD/Intel 路径若最终仍未连上,明确记一条 error便于现场区分
if (!IsConnect && (isAmd || isIntel))
{
frmISP.WriteLog("[Connect] AMD/Intel handshake FAILED on all monitors. "
+ "DDC channel likely not ready or wrong adapter/display index.", "error");
}
// Intel IGCL and AMD can complete the FE handshake but still time out on optional
// identity queries during connect. Skip those reads here so connect stays usable.
if ((((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType != GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL)
&& (((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType != GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL_IGCL)
&& (((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType != GraphicCardI2CCtrl.GRAPHIC_CARD.AMD))
if (!isIntel && !isAmd) // >>> 改动:用缓存的 isIntel/isAmd 替换原三段强转判断(逻辑等价)
{
QueryConnectedMonitorInfo();
}
else
{
ClearConnectedMonitorInfo();
//ClearConnectedMonitorInfo();
QueryConnectedMonitorInfo();
frmISP.WriteLog("Skip optional monitor identity query on AMD/Intel path.", "debug");
}
}
if (IsConnect == false)
{
frmISP.WriteLog("IsConnect = false", "debug");
frmISP.WriteLog("IsConnect = false", "error"); // >>> 改动:升级为 error
btnAuto.Enabled = false;
ClearConnectedMonitorInfo();
SetStatusMsg("Current F/W version is not compatible with this tool.", true);
@@ -743,25 +771,24 @@ namespace WinISP
_chipType = chipType;
switch (chipType)
{
case 0: { frmISP.WriteLog("MTKChipType=Not Defined", "debug"); } break;
case 1: { frmISP.WriteLog("MTKChipType=TSUM", "debug"); } break;
case 2: { frmISP.WriteLog("MTKChipType=MST9U", "debug"); } break;
case 0: { frmISP.WriteLog("MTKChipType=Not Defined", "warn"); } break; // >>> 改动:未识别提为 warn
case 1: { frmISP.WriteLog("MTKChipType=TSUM", "info"); } break;
case 2: { frmISP.WriteLog("MTKChipType=MST9U", "info"); } break;
}
Application.DoEvents();
if ((((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType != GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL)
&& (((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType != GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL_IGCL)
&& (((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType != GraphicCardI2CCtrl.GRAPHIC_CARD.AMD))
if (!isIntel && !isAmd) // >>> 改动:等价替换
{
DDC_GetVersion();
}
else
{
DDC_GetVersion();
frmISP.WriteLog("Skip optional firmware version query on AMD/Intel path.", "debug");
}
DDC_SetToolFlag(false);
int pktDelayTime = 0;
switch (((GraphicCardI2CCtrl)_simI2cCtrl).GetGraphicCardType)
switch (cardType) // >>> 改动:用缓存的 cardType
{
case GraphicCardI2CCtrl.GRAPHIC_CARD.AMD:
{
@@ -775,7 +802,7 @@ namespace WinISP
//TSUMxxG : 當maxPktLen=59時低於1000時SendDataToDram會失敗。
pktDelayTime = 1500;
}
frmISP.WriteLog("GRAPHIC_CARD.AMD", "debug");
frmISP.WriteLog("GRAPHIC_CARD.AMD", "info");
}
break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.NVIDIA:
@@ -790,7 +817,7 @@ namespace WinISP
//TSUMxxG : 當maxPktLen=59時低於1000時SendDataToDram會失敗。
pktDelayTime = 1000;
}
frmISP.WriteLog("GRAPHIC_CARD.NVIDIA", "debug");
frmISP.WriteLog("GRAPHIC_CARD.NVIDIA", "info");
}
break;
case GraphicCardI2CCtrl.GRAPHIC_CARD.INTEL:
@@ -816,7 +843,7 @@ namespace WinISP
pktDelayTime = 0;
}
}
frmISP.WriteLog("GRAPHIC_CARD.INTEL/INTEL_IGCL", "debug");
frmISP.WriteLog("GRAPHIC_CARD.INTEL/INTEL_IGCL", "info");
}
break;
}
@@ -825,7 +852,7 @@ namespace WinISP
else
{
// GPU DDC init failed driver not installed, GPU not supported, or monitor not connected.
frmISP.WriteLog("simI2cCtrl.Init() = false: GPU DDC init failed. Check GPU driver and monitor connection.", "debug");
frmISP.WriteLog("simI2cCtrl.Init() = false: GPU DDC init failed. Check GPU driver and monitor connection.", "error"); // >>> 改动:升级为 error
btnAuto.Enabled = false;
SetStatusMsg("GPU DDC init failed. Check driver and monitor cable.");
return;
@@ -1576,6 +1603,7 @@ namespace WinISP
string binTrim = (_u8ModelName ?? string.Empty).Trim();
if (fwTrim.Length < 6 || !binTrim.StartsWith(fwTrim, StringComparison.Ordinal))
{
frmISP.WriteLog($"FW:{fwTrim},Bin:{binTrim}","debug");
errMsg = "Model not match.";
return false;
}

View File

@@ -1859,22 +1859,39 @@ namespace WinISP
private static string resultFolder = System.IO.Directory.GetCurrentDirectory() + "\\";
private static System.IO.StreamWriter _logWriter = null;
private static string _logPath = null;
private static readonly object _logLock = new object();
[Conditional("DEBUG")]
public static void WriteLog(string str, string fileName)
public static void WriteLog(string str, string level)
{
try
{
if (!System.IO.Directory.Exists(resultFolder))
System.IO.Directory.CreateDirectory(resultFolder);
string path = resultFolder + (fileName == "" ? "" : fileName + "_") + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
string path = resultFolder + (level == "" ? "" : level + "_") + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
lock (_logLock) // >>> 新增:同进程内串行化,避免自家多线程争用
{
if (_logWriter == null || _logPath != path)
{
if (_logWriter != null) { _logWriter.Flush(); _logWriter.Close(); }
if (_logWriter != null)
{
try { _logWriter.Flush(); _logWriter.Close(); } catch { }
}
_logPath = path;
_logWriter = new System.IO.StreamWriter(path, append: true);
var stream = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
_logWriter = new System.IO.StreamWriter(stream);
}
_logWriter.WriteLine(DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss.fff: ") + str);
_logWriter.Flush();
}
}
catch (Exception) // >>> 改动IOException → Exception吞掉一切日志异常
{
// 日志写入失败绝不能影响主流程。可选:降级写到 Debug 输出
try { System.Diagnostics.Debug.WriteLine("[LOG-FALLBACK] " + str); } catch { }
}
}
private void cboConnectedMonitor_SelectedIndexChanged(object sender, EventArgs e)
{