diff --git a/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/FormISP_MSI.cs b/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/FormISP_MSI.cs index 64b9f1b..0562dd6 100644 --- a/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/FormISP_MSI.cs +++ b/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/FormISP_MSI.cs @@ -520,85 +520,89 @@ namespace WinISP private void QueryConnectedMonitorInfo() { - // 读取显示器端信息(芯片名、面板名、板卡名、型号名) try { + bool isAmdOrIntel = IsAmdOrIntelPath(); bool legacyRemapped = false; // 型号名 { - 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; + if (isAmdOrIntel) + rawModelName = ReadMonitorFieldRobust(CmdGetModelName, MonitorModelNameLength); // >>> A/I 走稳健版 + else { - string rawModelName = Encoding.ASCII.GetString(recv, 2, MonitorModelNameLength).TrimEnd('\0'); - 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"); - } - else - { - _monitorModelName = NormalizeMonitorModelName(rawModelName); - } + // 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); + 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 ...", "debug"); } else - _monitorModelName = string.Empty; + { + _monitorModelName = NormalizeMonitorModelName(rawModelName); + } } - // 芯片名 + // 芯片名 / 面板名 / 板卡名: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"); } } + /// + /// AMD/Intel 友好的型号读取:带响应有效性校验 + 多轮重试。 + /// AMD ADL DDC 读命中率低(约 4 错 1 对),需要足够重试次数才能读到完整字符串。 + /// + 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 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++) { + 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("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()) - 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; } diff --git a/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/frmISP.cs b/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/frmISP.cs index f611b73..c30a2c9 100644 --- a/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/frmISP.cs +++ b/WIN10_WinISP_SrcCode_For_MOKA_20250416_1/WinISP/frmISP.cs @@ -1859,21 +1859,38 @@ 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) { - if (!System.IO.Directory.Exists(resultFolder)) - System.IO.Directory.CreateDirectory(resultFolder); - - string path = resultFolder + (fileName == "" ? "" : fileName + "_") + DateTime.Now.ToString("yyyy-MM-dd") + ".log"; - if (_logWriter == null || _logPath != path) + try { - if (_logWriter != null) { _logWriter.Flush(); _logWriter.Close(); } - _logPath = path; - _logWriter = new System.IO.StreamWriter(path, append: true); + if (!System.IO.Directory.Exists(resultFolder)) + System.IO.Directory.CreateDirectory(resultFolder); + + string path = resultFolder + (level == "" ? "" : level + "_") + DateTime.Now.ToString("yyyy-MM-dd") + ".log"; + + lock (_logLock) // >>> 新增:同进程内串行化,避免自家多线程争用 + { + if (_logWriter == null || _logPath != path) + { + if (_logWriter != null) + { + try { _logWriter.Flush(); _logWriter.Close(); } catch { } + } + _logPath = path; + 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 { } } - _logWriter.WriteLine(DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss.fff: ") + str); - _logWriter.Flush(); } private void cboConnectedMonitor_SelectedIndexChanged(object sender, EventArgs e)