1.Check SlotMap,ProceedWithSlotMap,SlotMap Verify OK上报实现,但某些数据需要和客户协商。已写入注释
已修改7个文件
90 ■■■■ 文件已修改
SourceCode/Bond/Servo/CLoadPort.cpp 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/HsmsPassive.cpp 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/HsmsPassive.h 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/x64/Debug/CollectionEventList.txt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/x64/Debug/VariableList.txt 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.cpp
@@ -937,25 +937,13 @@
        // 当port状态为InUse, 比较map
        if (m_portStatusReport.getPortStatus() == PORT_INUSE) {
            if (m_isCompareMapsBeforeProceeding) {
                short scanMap = getScanCassetteMap();
                short downloadMap = getDownloadCassetteMap();
                if (scanMap == downloadMap) {
                    generateGlassList(scanMap);
                    this->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
                }
                else {
                    this->sendCassetteCtrlCmd(CCC_PROCESS_CANCEL, nullptr, 0, 0, 0, nullptr, nullptr);
            // 生成玻璃列表:来自 EFEM 扫描到的 map
            generateGlassList(getScanCassetteMap());
                    // 抛出到应用层做提示
                    if (m_listener.onMapMismatch != nullptr) {
                        m_listener.onMapMismatch(this, scanMap, downloadMap);
                    }
                }
            }
            else {
                // 抛出到应用层做选择要加工的片子
                generateGlassList(getScanCassetteMap());
            // CompareMapsBeforeProceeding:不在此处自动 Start/Cancel,改为等待 Host 决策(ProceedWithCarrier/ProceedWithSlotMap/CarrierRelease)
            // Host 决策入口:S3F17 CarrierAction -> listener.onCarrierAction -> CMaster::proceedWithCarrier()/carrierRelease()
            if (m_isCompareMapsBeforeProceeding) {
                // 这里仅等待,具体上报由上层在 PORT_INUSE 事件中触发(S6F11 CheckSlotMap)
            }
        }
        if (m_listener.onPortStatusChanged != nullptr) {
@@ -1324,4 +1312,9 @@
    {
        m_isCompareMapsBeforeProceeding = bCompare;
    }
    BOOL CLoadPort::isCompareMapsBeforeProceeding() const
    {
        return m_isCompareMapsBeforeProceeding;
    }
}
SourceCode/Bond/Servo/CLoadPort.h
@@ -86,6 +86,7 @@
            ONWRITED onWritedBlock);
        CStep* getCassetteCtrlCmdStep();
        void setCompareMapsBeforeProceeding(BOOL bCompare);
        BOOL isCompareMapsBeforeProceeding() const;
    private:
        int decodePortStatusReport(CStep* pStep, const char* pszData, size_t size);
SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -2523,6 +2523,21 @@
    return requestEventReportSend("CarrierID_Readed");
}
int CHsmsPassive::requestEventReportSend_CheckSlotMap()
{
    return requestEventReportSend("CheckSlotMap");
}
int CHsmsPassive::requestEventReportSend_SlotMapVerificationOK()
{
    return requestEventReportSend("SlotMapVerificationOK");
}
int CHsmsPassive::requestEventReportSend_SlotMapVerificationNG()
{
    return requestEventReportSend("SlotMapVerificationNG");
}
int CHsmsPassive::requestEventReportSend_Port_Unload_Ready()
{
    return requestEventReportSend("Port_Unload_Ready");
SourceCode/Bond/Servo/HsmsPassive.h
@@ -203,6 +203,9 @@
    int requestEventReportSend(unsigned int CEID);
    int requestEventReportSend(const char* pszEventName);
    int requestEventReportSend_CarrierID_Readed();
    int requestEventReportSend_CheckSlotMap();
    int requestEventReportSend_SlotMapVerificationOK();
    int requestEventReportSend_SlotMapVerificationNG();
    int requestEventReportSend_Port_Unload_Ready();
    int requestEventReportSend_Port_Load_Ready();
    int requestEventReportSend_Port_Ready_To_Release();
SourceCode/Bond/Servo/Model.cpp
@@ -173,12 +173,39 @@
                return CAACK_3;
            }
            const unsigned int portIndex = PTN - 1;
            SERVO::CLoadPort* pLoadPort = (SERVO::CLoadPort*)m_master.getEquipment(EQ_ID_LOADPORT1 + portIndex);
            if (_strcmpi(pszCarrierAction, "ProceedWithCarrier") == 0) {
                m_master.proceedWithCarrier(PTN);
                // 文档流程:ProceedWithCarrier 之后设备进入 Check SlotMap(WFH),
                // 真正的“开始”由 ProceedWithSlotMap 决策触发。
                // 仅当未开启 CompareMapsBeforeProceeding 时,才沿用旧逻辑直接 Start。
                if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) {
                    m_master.proceedWithCarrier(portIndex);
                }
                return CAACK_0;
            }
            else if (_strcmpi(pszCarrierAction, "ProceedWithSlotMap") == 0) {
                // TODO(Host协商):
                // 文档中 ProceedWithSlotMap 可能会携带 LotID / PanelIDList / SlotMap 等数据(最多13片)用于格式校验与绑定。
                // 当前 S3F17 解析结构仅支持 {DATAID, CarrierAction, CarrierID, PTN},尚未实现上述扩展字段的解析/校验。
                // 未来若客户确认 SECS-II 结构,需要在 CHsmsPassive::replyCarrierAction() 扩展解析并在此处落库/校验。
                // 仅在 CompareMapsBeforeProceeding 启用(Host 模式)下允许此动作
                if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) {
                    strErrorTxt = "rejected - SlotMap check disabled";
                    return CAACK_5;
                }
                m_hsmsPassive.setVariableValue("SlotMapScan", pLoadPort->getScanCassetteMap());
                m_hsmsPassive.setVariableValue("SlotMapDownload", pLoadPort->getDownloadCassetteMap());
                m_hsmsPassive.requestEventReportSend_SlotMapVerificationOK();
                // Host 确认 SlotMap 后再开始加工/流程
                m_master.proceedWithCarrier(portIndex);
                return CAACK_0;
            }
            else if (_strcmpi(pszCarrierAction, "CarrierRelease") == 0) {
                m_master.carrierRelease(PTN);
                m_master.carrierRelease(portIndex);
                return CAACK_0;
            }
@@ -410,6 +437,12 @@
            SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment);
            if (pLoadPort != nullptr) {
                m_hsmsPassive.setVariableValue("CarrierID", pLoadPort->getCassetteId().c_str());
                if (prevStatus != PORT_INUSE && pLoadPort->isCompareMapsBeforeProceeding()) {
                    // TODO(Host协商):
                    // 文档中标明:1-Empty,3-Exist,因此我们可能需要将uint的map转换为list上传
                    m_hsmsPassive.setVariableValue("SlotMap", pLoadPort->getScanCassetteMap());
                    m_hsmsPassive.requestEventReportSend_CheckSlotMap();
                }
            }
            m_hsmsPassive.requestEventReportSend_CarrierID_Readed();
        }
SourceCode/Bond/x64/Debug/CollectionEventList.txt
@@ -11,7 +11,7 @@
10051,CarrierIDWaitingForHost,,(10051)
10052,CarrierIDVerificationOK,,(10052)
10053,CarrierIDVerificationNG,,(10052)
10061,SlotMapWaitingForHost,,(10061)
10061,CheckSlotMap,,(10061)
10062,SlotMapVerificationOK,,(10062)
10063,SlotMapVerificationNG,,(10062)
10071,GlassIDReadWaitingForHost,,(10071)
SourceCode/Bond/x64/Debug/VariableList.txt
@@ -50,3 +50,6 @@
5013,TestVID,U1,测试添加变量55
5014,VCRPanelID,A20,Panel id,来自读码器
5015,ReadyToReleasePortId,U1,"Port ID"
10200,SlotMap,U2,SlotMap(Scan)
10201,SlotMapScan,U2,SlotMap(Scan)
10202,SlotMapDownload,U2,SlotMap(Download)