LAPTOP-SNT8I5JK\Boounion
2025-05-09 1e7d3ca649456469440d74fabfc16e191433f9b4
1.实现FetchOut Job功能;
已添加5个文件
已修改35个文件
已删除1个文件
1081 ■■■■■ 文件已修改
Document/2860MES交握表.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.2.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.5(5).xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.5.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Document/ESWIN_EAS_Equipment_Communication_Specification(CC-LINK)_v3.1(翻译结果).docx 补丁 | 查看 | 原始文档 | blame | 历史
Document/~$WIN_EAS_Equipment_Communication_Specification(CC-LINK)_v3.1(翻译结果).docx 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CArm.cpp 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CArm.h 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CArmTray.cpp 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CArmTray.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBonder.cpp 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.cpp 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.h 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqJobEventStep.cpp 113 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqJobEventStep.h 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqReadStep.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqReadStep.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqStatusStep.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataA.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataA.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataB.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataB.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataS.cpp 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataS.h 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph1.cpp 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph2.cpp 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph2.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CStep.cpp 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CStep.h 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Common.h 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/EqsGraphWnd.cpp 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/EqsGraphWnd.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.user 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Document/2860MES½»ÎÕ±í.xlsx
Binary files differ
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.2.xlsx
Binary files differ
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.5(5).xlsx
Binary files differ
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.5.xlsx
Binary files differ
Document/ESWIN_EAS_Equipment_Communication_Specification(CC-LINK)_v3.1(·­Òë½á¹û).docx
Binary files differ
Document/~$WIN_EAS_Equipment_Communication_Specification(CC-LINK)_v3.1(·­Òë½á¹û).docx
Binary files differ
SourceCode/Bond/Servo/CArm.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,97 @@
#include "stdafx.h"
#include "CArm.h"
namespace SERVO {
    CArm::CArm() : CEquipment()
    {
    }
    CArm::~CArm()
    {
    }
    const char* CArm::getClassName()
    {
        static char* pszName = "CArm";
        return pszName;
    }
    void CArm::init()
    {
        CEquipment::init();
    }
    void CArm::term()
    {
        CEquipment::term();
    }
    // å¿…须要实现的虚函数,在此初始化Pin列表
    void CArm::initPins()
    {
    }
    void CArm::onTimer(UINT nTimerid)
    {
        CEquipment::onTimer(nTimerid);
    }
    void CArm::serialize(CArchive& ar)
    {
        CEquipment::serialize(ar);
    }
    void CArm::getAttributeVector(CAttributeVector& attrubutes)
    {
        __super::getAttributeVector(attrubutes);
    }
    int CArm::recvIntent(CPin* pPin, CIntent* pIntent)
    {
        return __super::recvIntent(pPin, pIntent);
    }
    int CArm::tempStore(CGlass* pGlass)
    {
        // ä¿è¯åˆ—表中只存储一个物料
        Lock();
        for (auto item : m_glassList) {
            item->release();
        }
        m_glassList.clear();
        addGlassToList(pGlass);
        Unlock();
        if (m_listener.onDataChanged != nullptr) {
            m_listener.onDataChanged(this, 0);
        }
        return 0;
    }
    int CArm::tempFetchOut(OUT CGlass*& pGlass)
    {
        Lock();
        if (m_glassList.empty()) {
            Unlock();
            return -1;
        }
        pGlass = m_glassList.front();
        pGlass->addRef();
        for (auto item : m_glassList) {
            item->release();
        }
        m_glassList.clear();
        Unlock();
        if (m_listener.onDataChanged != nullptr) {
            m_listener.onDataChanged(this, 0);
        }
        return 0;
    }
}
SourceCode/Bond/Servo/CArm.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
#pragma once
#include "CEquipment.h"
namespace SERVO {
    class CArm : public CEquipment
    {
    public:
        CArm();
        virtual ~CArm();
    public:
        virtual const char* getClassName();
        virtual BOOL isArm() { return TRUE; };
        virtual void init();
        virtual void term();
        virtual void initPins();
        virtual void onTimer(UINT nTimerid);
        virtual void serialize(CArchive& ar);
        virtual void getAttributeVector(CAttributeVector& attrubutes);
        virtual int recvIntent(CPin* pPin, CIntent* pIntent);
    public:
        int tempStore(CGlass* pGlass);
        // è°ƒç”¨tempFetchOut后,pGlass必须release一次
        int tempFetchOut(OUT CGlass*& pGlass);
    };
}
SourceCode/Bond/Servo/CArmTray.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
#include "stdafx.h"
#include "CArmTray.h"
namespace SERVO {
    CArmTray::CArmTray() : CEquipment()
    {
    }
    CArmTray::~CArmTray()
    {
    }
    const char* CArmTray::getClassName()
    {
        static char* pszName = "CArmTray";
        return pszName;
    }
    void CArmTray::init()
    {
        CEquipment::init();
    }
    void CArmTray::term()
    {
        CEquipment::term();
    }
    // å¿…须要实现的虚函数,在此初始化Pin列表
    void CArmTray::initPins()
    {
    }
    void CArmTray::onTimer(UINT nTimerid)
    {
        CEquipment::onTimer(nTimerid);
    }
    void CArmTray::serialize(CArchive& ar)
    {
        CEquipment::serialize(ar);
    }
    void CArmTray::getAttributeVector(CAttributeVector& attrubutes)
    {
        __super::getAttributeVector(attrubutes);
    }
    int CArmTray::recvIntent(CPin* pPin, CIntent* pIntent)
    {
        return __super::recvIntent(pPin, pIntent);
    }
}
SourceCode/Bond/Servo/CArmTray.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
#pragma once
#include "CEquipment.h"
namespace SERVO {
    class CArmTray : public CEquipment
    {
    public:
        CArmTray();
        virtual ~CArmTray();
    public:
        virtual const char* getClassName();
        virtual void init();
        virtual void term();
        virtual void initPins();
        virtual void onTimer(UINT nTimerid);
        virtual void serialize(CArchive& ar);
        virtual void getAttributeVector(CAttributeVector& attrubutes);
        virtual int recvIntent(CPin* pPin, CIntent* pIntent);
    };
}
SourceCode/Bond/Servo/CBonder.cpp
@@ -113,7 +113,7 @@
            CEqCimMessageCmdStep* pStep = new CEqCimMessageCmdStep();
            pStep->setName(STEP_CIM_MESSAGE_CMD);
            pStep->setWriteSignalDev(m_nIndex == 0 ? 0x361 : 0x661);
            pStep->setCimMessageDev(m_nIndex == 0 ? 0x963 : 0x12b3);
            pStep->setCimMessageDev(m_nIndex == 0 ? 0x950 : 0x12a0);
            if (addStep(STEP_ID_CIM_MSG_SET_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
@@ -132,6 +132,8 @@
        {
            // CIM Message Confirm
            // è¦å°†int32的值拆分为两个short, åˆ†åˆ«ä¸ºmsg id和panel id
            // 65538, 2Ϊmsg id, 1Ϊpanel id
            CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, m_nIndex == 0 ? 0x9d80 : 0xdd80);
            pStep->setName(STEP_EQ_CIM_MESSAGE_CONFIRM);
            pStep->setWriteSignalDev(m_nIndex == 0 ? 0x349 : 0x649);
@@ -185,7 +187,7 @@
        {
            // master recipe list report
            CEqReadStep* pStep = new CEqReadStep(m_nIndex == 0 ? 0xa955 : 0xe955, 255 * 2,
                [&](int code, const char* pszData, size_t size) -> int {
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        // æ­¤å¤„解释配方数据
                        short ret = decodeRecipeListReport(pszData, size);
@@ -216,7 +218,7 @@
        {
            // recipe parameter report
            CEqReadStep* pStep = new CEqReadStep(m_nIndex == 0 ? 0xaa54 : 0xea54, 257 * 2,
                [&](int code, const char* pszData, size_t size) -> int {
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        // æ­¤å¤„解释配方数据
                        short ret = decodeRecipeParameterReport(pszData, size);
SourceCode/Bond/Servo/CEFEM.cpp
@@ -19,6 +19,8 @@
        m_pPort[1] = nullptr;
        m_pPort[2] = nullptr;
        m_pPort[3] = nullptr;
        m_pAligner = nullptr;
        m_pFliper = nullptr;
    }
    CEFEM::~CEFEM()
@@ -36,6 +38,23 @@
    {
        if (index < 4) {
            m_pPort[index] = pPort;
        }
    }
    void CEFEM::setAligner(CAligner* pAligner)
    {
        m_pAligner = pAligner;
    }
    void CEFEM::setFliper(CFliper* pFliper)
    {
        m_pFliper = pFliper;
    }
    void CEFEM::setArmTray(unsigned int index, CArmTray* pArmTray)
    {
        if (index < 2) {
            m_pArmTray[index] = pArmTray;
        }
    }
@@ -213,7 +232,6 @@
            }
        }
        {
            // è¯·æ±‚主配方列表的step
            CEqWriteStep* pStep = new CEqWriteStep();
@@ -274,6 +292,30 @@
            STEP_ID_PORT4_CASSETTIE_UNLOAD_READY, 0x60b0);
        ADD_EQ_CASSETTE_TRANSFER_STATE_STEP(STEP_EQ_P4_CASSETTE_BLOCKED, 0x103,
            STEP_ID_PORT4_CASSETTIE_BLOCKED, 0x60b0);
        {
            // Fetched Out Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 15; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x5c31 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeFetchedOutJobReport(port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_FETCHED_OUT_JOBn, i+1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x023 + i);
                if (addStep(STEP_ID_FETCHED_OUT_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
    }
    int CEFEM::onStepEvent(CStep* pStep, int code)
@@ -335,4 +377,34 @@
            }
        }
    }
    int CEFEM::onFetchedOut(int port, const char* pszGlassId)
    {
        if (port == 1) {
            return m_pPort[0]->fetchedOut(pszGlassId);
        }
        if (port == 2) {
            return m_pPort[1]->fetchedOut(pszGlassId);
        }
        if (port == 3) {
            return m_pPort[2]->fetchedOut(pszGlassId);
        }
        if (port == 4) {
            return m_pPort[3]->fetchedOut(pszGlassId);
        }
        if (port == 5) {
            return m_pArmTray[0]->fetchedOut(pszGlassId);
        }
        if (port == 6) {
            return m_pArmTray[1]->fetchedOut(pszGlassId);
        }
        if (port == 7) {
            return m_pAligner->fetchedOut(pszGlassId);
        }
        if (port == 8) {
            return m_pFliper->fetchedOut(pszGlassId);
        }
        return -1;
    }
}
SourceCode/Bond/Servo/CEFEM.h
@@ -1,6 +1,9 @@
#pragma once
#include "CEquipment.h"
#include "CLoadPort.h"
#include "CAligner.h"
#include "CFliper.h"
#include "CArmTray.h"
namespace SERVO {
@@ -24,13 +27,19 @@
        virtual int recvIntent(CPin* pPin, CIntent* pIntent);
        virtual BOOL glassWillArrive(CGlass* pGlass);
        virtual void onReceiveLBData(const char* pszData, size_t size);
        virtual int onFetchedOut(int port, const char* pszGlassId);
    public:
        void setPort(unsigned int index, CLoadPort* pPort);
        void setAligner(CAligner* pAligner);
        void setFliper(CFliper* pFliper);
        void setArmTray(unsigned int index, CArmTray* pArmTray);
    private:
        CLoadPort* m_pPort[4];
        CAligner* m_pAligner;
        CFliper* m_pFliper;
        CArmTray* m_pArmTray[2];
    };
}
SourceCode/Bond/Servo/CEqJobEventStep.cpp
@@ -26,23 +26,96 @@
        std::string strTemp;
        attrubutes.addAttribute(new CAttribute("Dev",
            ("W" + CToolUnits::toHexString(m_nJobDataADev, strTemp)).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("PortNo",
            std::to_string(m_jobDataA.getPortNo()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("CarrierId",
            m_jobDataA.getCarrierId().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("PruductId",
            m_jobDataA.getPruductId().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("CarrierState",
            m_jobDataA.getCarrierStateDescription(strTemp).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("SlotMapping",
            std::to_string(m_jobDataA.getSlotMapping()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("SlotSelectedFlag",
            std::to_string(m_jobDataA.getSlotSelectedFlag()).c_str(), ""));
        std::vector<std::string>& ids = m_jobDataA.getGlassIds();
        for (int i = 0; i < ids.size(); i++) {
            attrubutes.addAttribute(new CAttribute((std::string("GlassId") + std::to_string(i+1)).c_str(),
                ids[i].c_str(), ""));
        }
        attrubutes.addAttribute(new CAttribute("CassetteSequenceNo",
            std::to_string(m_jobDataS.getCassetteSequenceNo()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("JobSequenceNo",
            std::to_string(m_jobDataS.getJobSequenceNo()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("LotId",
            m_jobDataS.getLotId().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("ProductId",
            m_jobDataS.getProductId().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("OperationId",
            m_jobDataS.getOperationId().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("Glass1Id",
            m_jobDataS.getGlass1Id().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("Glass2Id",
            m_jobDataS.getGlass2Id().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("JobType",
            std::to_string(m_jobDataS.getJobType()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("MaterialsType",
            std::to_string(m_jobDataS.getMaterialsType()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("ProductType",
            std::to_string(m_jobDataS.getProductType()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("DummyType",
            std::to_string(m_jobDataS.getDummyType()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("SkipFlag",
            std::to_string(m_jobDataS.getSkipFlag()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("ProcessFlag",
            std::to_string(m_jobDataS.getProcessFlag()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("ProcessResonCode",
            std::to_string(m_jobDataS.getProcessResonCode()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("LastGlassFlag",
            std::to_string(m_jobDataS.getLastGlassFlag()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("FirstGlassFlag",
            std::to_string(m_jobDataS.getFirstGlassFlag()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("QTime1",
            std::to_string(m_jobDataS.getQTime(0)).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("QTime2",
            std::to_string(m_jobDataS.getQTime(1)).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("QTime3",
            std::to_string(m_jobDataS.getQTime(2)).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("QTimeOverFlag",
            std::to_string(m_jobDataS.getQTimeOverFlag()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("MasterRecipe",
            std::to_string(m_jobDataS.getMasterRecipe()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("ProductRecipeId",
            m_jobDataS.getProductRecipeId().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("PCode",
            m_jobDataS.getPCode().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("UseType",
            m_jobDataS.getUseType().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("PanelMeasure",
            m_jobDataS.getPanelMeasure().c_str(), ""));
        attrubutes.addAttribute(new CAttribute("SlotUnitSelectFlag",
            std::to_string(m_jobDataS.getSlotUnitSelectFlag()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("SourcePortNo",
            std::to_string(m_jobDataS.getSourcePortNo()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("SourceSlotNo",
            std::to_string(m_jobDataS.getSourceSlotNo()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("TargetPortNo",
            std::to_string(m_jobDataS.getTargetPortNo()).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("TargetSlotNo",
            std::to_string(m_jobDataS.getTargetSlotNo()).c_str(), ""));
    }
    int CEqJobEventStep::onReadData()
@@ -57,7 +130,7 @@
            return -1;
        }
        m_jobDataA.unserialize(szBuffer, 640);
        m_jobDataS.unserialize(szBuffer, 640);
        LOGI("<CEqJobEventStep-%s>Read JobDataA\n", m_strName.c_str());
        return 0;
@@ -79,8 +152,8 @@
        return 0;
    }
    CJobDataA* CEqJobEventStep::getJobDataA()
    CJobDataS* CEqJobEventStep::getJobDataS()
    {
        return &m_jobDataA;
        return &m_jobDataS;
    }
}
SourceCode/Bond/Servo/CEqJobEventStep.h
@@ -1,6 +1,6 @@
#pragma once
#include "CReadStep.h"
#include "CJobDataA.h"
#include "CJobDataS.h"
namespace SERVO {
@@ -16,11 +16,11 @@
        virtual int onComplete();
        virtual int onTimeout();
        void setJobDataDev(int nDev);
        CJobDataA* getJobDataA();
        CJobDataS* getJobDataS();
    private:
        int m_nJobDataADev;
        CJobDataA m_jobDataA;
        CJobDataS m_jobDataS;
    };
}
SourceCode/Bond/Servo/CEqReadStep.cpp
@@ -43,14 +43,14 @@
        if (0 != nRet) {
            LOGI("<CEqReadStep>Read data error.");
            if (m_onReadBlock != nullptr) {
                m_onReadBlock(RERROR, nullptr, 0);
                m_onReadBlock(this, RERROR, nullptr, 0);
            }
            return -1;
        }
        LOGI("<CEqReadStep>read data succeed.");
        if (m_onReadBlock != nullptr) {
            m_onReadBlock(ROK, szBuffer, m_nReadSize);
            m_onReadBlock(this, ROK, szBuffer, m_nReadSize);
        }
@@ -62,7 +62,7 @@
        CReadStep::onComplete();
        LOGI("<CEqReadStep> onComplete.");
        if (m_onReadBlock != nullptr) {
            m_onReadBlock(RCOMPLETE, nullptr, 0);
            m_onReadBlock(this, RCOMPLETE, nullptr, 0);
        }
        return 0;
@@ -73,7 +73,7 @@
        CReadStep::onTimeout();
        LOGI("<CEqReadStep> onTimeout.");
        if (m_onReadBlock != nullptr) {
            m_onReadBlock(RTIMEOUT, nullptr, 0);
            m_onReadBlock(this, RTIMEOUT, nullptr, 0);
        }
        return 0;
SourceCode/Bond/Servo/CEqReadStep.h
@@ -11,7 +11,7 @@
#define RCOMPLETE        1                    /* è¯»æ•°æ®æµç¨‹å®Œæˆ */
namespace SERVO {
    typedef std::function<int(int code, const char* pszData, size_t size)> ONREAD;
    typedef std::function<int(void* pFrom, int code, const char* pszData, size_t size)> ONREAD;
    class CEqReadStep : public CReadStep
    {
SourceCode/Bond/Servo/CEqStatusStep.cpp
@@ -9,7 +9,7 @@
    {
        m_nStatusDev = 0;
        for (int i = 0; i < STATUS_MAX; i++) {
            m_nStatus[i] = 7;
            m_nStatus[i] = 0;
            m_nReasonCode[i] = 0;
        }
    
SourceCode/Bond/Servo/CEquipment.cpp
@@ -2,6 +2,7 @@
#include "CEquipment.h"
#include "ToolUnits.h"
#include <regex>
#include "CArm.h"
#define CHECK_READ_STEP_SIGNAL(addr, data, size) {                            \
@@ -34,6 +35,7 @@
        m_bVCREnable[0] = FALSE;
        m_pCclink = nullptr;
        m_nBaseAlarmId = 0;
        m_pArm = nullptr;
        InitializeCriticalSection(&m_criticalSection);
    }
@@ -74,6 +76,13 @@
    void CEquipment::setCcLink(CCCLinkIEControl* pCcLink)
    {
        m_pCclink = pCcLink;
    }
    void CEquipment::setArm(CEquipment* pEquipment)
    {
        ASSERT(pEquipment->isArm());
        ASSERT(!this->isArm());
        m_pArm = pEquipment;
    }
    void CEquipment::setBaseAlarmId(int nBaseId)
@@ -382,6 +391,14 @@
            CHECK_READ_STEP_SIGNAL(STEP_ID_EQMODE_CHANGED + i, pszData, size);
        }
        // process data report
        CHECK_READ_STEP_SIGNAL(STEP_ID_PROCESS_DATA_REPORT, pszData, size);
        // é…æ–¹æ”¹å˜
        CHECK_READ_STEP_SIGNAL(STEP_ID_CURRENT_RECIPE_CHANGE_REPORT, pszData, size);
        // ä¸»é…æ–¹ä¸ŠæŠ¥
        CHECK_READ_STEP_SIGNAL(STEP_ID_MASTER_RECIPE_LIST_REPORT, pszData, size);
        // CIM Mode
        CHECK_WRITE_STEP_SIGNAL(STEP_ID_CIMMODE_CHANGED_CMD_REPLY, pszData, size);
@@ -769,6 +786,75 @@
        return pGlass;
    }
    int CEquipment::fetchedOut(const char* pszGlassId)
    {
        if (m_pArm == nullptr) {
            return -1;
        }
        // æ‰¾åˆ°æŒ‡å®šçš„glass id,
        Lock();
        if (m_glassList.empty()) {
            Unlock();
            return -2;
        }
        CGlass* pContext = nullptr;
        for (auto iter = m_glassList.begin(); iter != m_glassList.end(); iter++) {
            if ((*iter)->getID().compare(pszGlassId) == 0) {
                pContext = (*iter);
                m_glassList.erase(iter);
                break;
            }
        }
        if (pContext == nullptr) {
            Unlock();
            return -3;
        }
        ((CArm*)m_pArm)->tempStore(pContext);
        pContext->release();
        Unlock();
        if (m_listener.onDataChanged != nullptr) {
            m_listener.onDataChanged(this, 0);
        }
        return 0;
    }
    int CEquipment::storeJob(const char* pszGlassId)
    {
        if (m_pArm == nullptr) {
            return -1;
        }
        CGlass* pGlass = nullptr;
        if (((CArm*)m_pArm)->tempFetchOut(pGlass) != 0) {
            return -2;
        }
        ASSERT(pGlass);
        Lock();
        pGlass->addPath(m_nID);
        pGlass->addRef();                    // åŠ å…¥list,addRef
        m_glassList.push_back(pGlass);
        pGlass->release();                // tempFetchOut需要调用一次release
        Unlock();
        if (m_listener.onDataChanged != nullptr) {
            m_listener.onDataChanged(this, 0);
        }
        return 0;
    }
    BOOL CEquipment::isGlassListEmpty()
    {
        return m_glassList.empty();
    }
    bool CEquipment::isAlarmStep(SERVO::CStep* pStep)
    {
        return CToolUnits::startsWith(pStep->getName(), STEP_ALARM_START);
@@ -938,4 +1024,32 @@
    {
        return m_recipesManager.decodeRecipeParameterReport(pszData, size);
    }
    int CEquipment::decodeFetchedOutJobReport(int port, const char* pszData, size_t size)
    {
        int index = 0;
        short unitOrPort, unitOrPortNo, subUnitNo, subSlotNo;
        CJobDataB jobDataB;
        int nRet = jobDataB.unserialize(&pszData[index], size);
        if (nRet < 0) return nRet;
        index += nRet;
        memcpy(&unitOrPort, &pszData[index], sizeof(short));
        index += sizeof(short);
        memcpy(&unitOrPortNo, &pszData[index], sizeof(short));
        index += sizeof(short);
        memcpy(&subUnitNo, &pszData[index], sizeof(short));
        index += sizeof(short);
        memcpy(&subSlotNo, &pszData[index], sizeof(short));
        index += sizeof(short);
        onFetchedOut(port, jobDataB.getGlassId().c_str());
        return index;
    }
    int CEquipment::onFetchedOut(int port, const char* pszGlassId)
    {
        return fetchedOut(pszGlassId);
    }
}
SourceCode/Bond/Servo/CEquipment.h
@@ -27,6 +27,10 @@
#include <list>
#include "CGlass.h"
#include "CRecipesManager.h"
#include "CJobDataA.h"
#include "CJobDataB.h"
#include "CJobDataC.h"
#include "CJobDataS.h"
namespace SERVO {
@@ -74,6 +78,8 @@
        virtual const char* getClassName() = 0;
        virtual void setListener(EquipmentListener listener);
        void setCcLink(CCCLinkIEControl* pCcLink);
        virtual BOOL isArm() { return FALSE; };
        void setArm(CEquipment* pEquipment);
        void setBaseAlarmId(int nBaseId);
        int getBaseAlarmId();
        void setID(int nID);
@@ -139,6 +145,11 @@
        // unitNo: 0:local; Others:unit No
        int recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo);
    public:
        int fetchedOut(const char* pszGlassId);
        int storeJob(const char* pszGlassId);
        BOOL isGlassListEmpty();
    // ä»¥ä¸‹ä¸ºä»ŽCC-Link读取到的Bit标志位检测函数
    public:
@@ -158,6 +169,8 @@
        void addGlassToList(CGlass* pGlass);
        short decodeRecipeListReport(const char* pszData, size_t size);
        short decodeRecipeParameterReport(const char* pszData, size_t size);
        int decodeFetchedOutJobReport(int port, const char* pszData, size_t size);
        int onFetchedOut(int port, const char* pszGlassId);
    protected:
        EquipmentListener m_listener;
@@ -188,6 +201,9 @@
        std::map<unsigned int, CStep*> m_mapStep;
        int m_nBaseAlarmId;
        CRecipesManager m_recipesManager;
    private:
        CEquipment* m_pArm;
    };
}
SourceCode/Bond/Servo/CJobDataA.cpp
@@ -64,7 +64,7 @@
        return 320 * 2;
    }
    int CJobDataA::unserialize(char* pszBuffer, int nBufferSize)
    int CJobDataA::unserialize(const char* pszBuffer, int nBufferSize)
    {
        if (nBufferSize < 640) return -1;
SourceCode/Bond/Servo/CJobDataA.h
@@ -20,7 +20,7 @@
        int getSlotSelectedFlag();
        std::vector<std::string>& getGlassIds();
        int serialize(char* pszBuffer, int nBufferSize);
        int unserialize(char* pszBuffer, int nBufferSize);
        int unserialize(const char* pszBuffer, int nBufferSize);
    private:
        short m_nPortNo;
SourceCode/Bond/Servo/CJobDataB.cpp
@@ -63,7 +63,7 @@
        return 14 * 2;
    }
    int CJobDataB::unserialize(char* pszBuffer, int nBufferSize)
    int CJobDataB::unserialize(const char* pszBuffer, int nBufferSize)
    {
        if (nBufferSize < 14) return -1;
SourceCode/Bond/Servo/CJobDataB.h
@@ -16,7 +16,7 @@
        std::string& getGlassId();
        void setGlassId(const char* pszGlassId);
        int serialize(char* pszBuffer, int nBufferSize);
        int unserialize(char* pszBuffer, int nBufferSize);
        int unserialize(const char* pszBuffer, int nBufferSize);
    private:
        int m_nCassetteSequenceNo;
SourceCode/Bond/Servo/CJobDataS.cpp
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "CJobDataS.h"
#include "ToolUnits.h"
namespace SERVO {
@@ -94,7 +95,7 @@
    std::string& CJobDataS::getGlass2Id()
    {
        return m_strGlass1Id;
        return m_strGlass2Id;
    }
    void CJobDataS::setGlass2Id(const char* pszId)
@@ -327,4 +328,219 @@
    {
        m_nTargetSlotNo = no;
    }
    int CJobDataS::serialize(char* pszBuffer, int nBufferSize)
    {
        if (nBufferSize < 256 * 2) return -1;
        int index = 0;
        memcpy(&pszBuffer[index], &m_nCassetteSequenceNo, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nJobSequenceNo, sizeof(short));
        index += sizeof(short);
        int strLen = min(40, m_strLotId.size());
        memcpy(&pszBuffer[index], m_strLotId.c_str(), strLen);
        index += 40;
        strLen = min(20, m_strProductId.size());
        memcpy(&pszBuffer[index], m_strProductId.c_str(), strLen);
        index += 20;
        strLen = min(20, m_strOperationId.size());
        memcpy(&pszBuffer[index], m_strOperationId.c_str(), strLen);
        index += 20;
        strLen = min(20, m_strGlass1Id.size());
        memcpy(&pszBuffer[index], m_strGlass1Id.c_str(), strLen);
        index += 20;
        strLen = min(20, m_strGlass2Id.size());
        memcpy(&pszBuffer[index], m_strGlass2Id.c_str(), strLen);
        index += 20;
        memcpy(&pszBuffer[index], &m_nJobType, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nMaterialsType, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nProductType, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nDummyType, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nSkipFlag, sizeof(int));
        index += sizeof(int);
        memcpy(&pszBuffer[index], &m_nProcessFlag, sizeof(int));
        index += sizeof(int);
        memcpy(&pszBuffer[index], &m_nProcessResonCode, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nLastGlassFlag, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nFirstGlassFlag, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nLastGlassFlag, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nQTime[0], sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nQTime[1], sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nQTime[2], sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nQTimeOverFlag, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nMasterRecipe, sizeof(short));
        index += sizeof(short);
        strLen = min(10, m_strProductRecipeId.size());
        memcpy(&pszBuffer[index], m_strProductRecipeId.c_str(), strLen);
        index += 10;
        strLen = min(10, m_strPCode.size());
        memcpy(&pszBuffer[index], m_strPCode.c_str(), strLen);
        index += 10;
        strLen = min(10, m_strUseType.size());
        memcpy(&pszBuffer[index], m_strUseType.c_str(), strLen);
        index += 10;
        strLen = min(80, m_strPanelMeasure.size());
        memcpy(&pszBuffer[index], m_strPanelMeasure.c_str(), strLen);
        index += 80;
        memcpy(&pszBuffer[index], &m_nMode, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nSlotUnitSelectFlag, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nSourcePortNo, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nSourceSlotNo, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nTargetPortNo, sizeof(short));
        index += sizeof(short);
        memcpy(&pszBuffer[index], &m_nTargetSlotNo, sizeof(short));
        index += sizeof(short);
        return 256 * 2;
    }
    int CJobDataS::unserialize(const char* pszBuffer, int nBufferSize)
    {
        if (nBufferSize < 256 * 2) return -1;
        int index = 0;
        memcpy(&m_nCassetteSequenceNo, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nJobSequenceNo, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        CToolUnits::convertString(&pszBuffer[index], 40, m_strLotId);
        index += 40;
        CToolUnits::convertString(&pszBuffer[index], 20, m_strProductId);
        index += 20;
        CToolUnits::convertString(&pszBuffer[index], 20, m_strOperationId);
        index += 20;
        CToolUnits::convertString(&pszBuffer[index], 20, m_strGlass1Id);
        index += 20;
        CToolUnits::convertString(&pszBuffer[index], 20, m_strGlass2Id);
        index += 20;
        memcpy(&m_nJobType, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nMaterialsType, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nProductType, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nDummyType, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nSkipFlag, &pszBuffer[index], sizeof(int));
        index += sizeof(int);
        memcpy(&m_nProcessFlag, &pszBuffer[index], sizeof(int));
        index += sizeof(int);
        memcpy(&m_nProcessResonCode, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nLastGlassFlag, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nFirstGlassFlag, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nQTime[0], &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nQTime[1], &pszBuffer[index], sizeof(short));
        index += sizeof(int);
        memcpy(&m_nQTime[2], &pszBuffer[index], sizeof(int));
        index += sizeof(short);
        memcpy(&m_nQTimeOverFlag, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nMasterRecipe, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        CToolUnits::convertString(&pszBuffer[index], 10, m_strProductRecipeId);
        index += 10;
        CToolUnits::convertString(&pszBuffer[index], 10, m_strProductRecipeId);
        index += 10;
        CToolUnits::convertString(&pszBuffer[index], 10, m_strProductRecipeId);
        index += 10;
        CToolUnits::convertString(&pszBuffer[index], 80, m_strProductRecipeId);
        index += 80;
        memcpy(&m_nMode, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nSlotUnitSelectFlag, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nSourcePortNo, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nSourceSlotNo, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nTargetPortNo, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        memcpy(&m_nTargetSlotNo, &pszBuffer[index], sizeof(short));
        index += sizeof(short);
        return 256 * 2;
    }
}
SourceCode/Bond/Servo/CJobDataS.h
@@ -67,6 +67,9 @@
        void setTargetPortNo(int no);
        int getTargetSlotNo();
        void setTargetSlotNo(int no);
        int serialize(char* pszBuffer, int nBufferSize);
        int unserialize(const char* pszBuffer, int nBufferSize);
    private:
        int m_nCassetteSequenceNo;
SourceCode/Bond/Servo/CMaster.cpp
@@ -24,7 +24,7 @@
    CMaster::CMaster()
    {
        m_listener = {nullptr, nullptr, nullptr, nullptr};
        m_listener = {nullptr, nullptr, nullptr, nullptr, nullptr};
        m_bDataModify = FALSE;
        m_hEventReadBitsThreadExit[0] = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hEventReadBitsThreadExit[1] = ::CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -56,6 +56,7 @@
        m_listener.onEqCimStateChanged = listener.onEqCimStateChanged;
        m_listener.onEqAlarm = listener.onEqAlarm;
        m_listener.onEqVcrEventReport = listener.onEqVcrEventReport;
        m_listener.onEqDataChanged = listener.onEqDataChanged;
    }
    int CMaster::init()
@@ -91,24 +92,63 @@
        // åˆå§‹åŒ–添加各子设备
        CLoadPort* pPort1, * pPort2, * pPort3, * pPort4;
        CBonder* pBonder1, * pBonder2;
        CEFEM* pEfem;
        CArm* pArm;
        CArmTray* pArmTray1, * pArmTray2;
        CFliper* pFliper;
        CVacuumBake* pVacuumBake;
        CAligner* pAligner;
        CBakeCooling* pBakeCooling;
        pPort1 = addLoadPort(0);
        pPort2 = addLoadPort(1);
        pPort3 = addLoadPort(2);
        pPort4 = addLoadPort(3);
        pEfem = addEFEM();
        pArm = addArm();
        pArmTray1 = addArmTray(0);
        pArmTray2 = addArmTray(1);
        pFliper = addFliper();
        pVacuumBake = addVacuumBake();
        pAligner = addAligner();
        pBonder1 = addBonder(0);
        pBonder2 = addBonder(1);
        pBakeCooling = addBakeCooling();
        ASSERT(pEfem);
        ASSERT(pFliper);
        ASSERT(pVacuumBake);
        ASSERT(pAligner);
        ASSERT(pBonder1);
        ASSERT(pBonder2);
        ASSERT(pBakeCooling);
        pEfem->setPort(0, pPort1);
        pEfem->setPort(1, pPort1);
        pEfem->setPort(2, pPort1);
        pEfem->setPort(3, pPort1);
        pEfem->setFliper(pFliper);
        pEfem->setAligner(pAligner);
        pEfem->setArmTray(0, pArmTray1);
        pEfem->setArmTray(1, pArmTray2);
        pPort1->setArm(pArm);
        pPort2->setArm(pArm);
        pPort3->setArm(pArm);
        pPort4->setArm(pArm);
        pArmTray1->setArm(pArm);
        pArmTray2->setArm(pArm);
        pFliper->setArm(pArm);
        pVacuumBake->setArm(pArm);
        pAligner->setArm(pArm);
        pBonder1->setArm(pArm);
        pBonder2->setArm(pArm);
        pBakeCooling->setArm(pArm);
        addFliper();
        addVacuumBake();
        addAligner();
        addBonder(0);
        addBonder(1);
        addBakeCooling();
        connectEquipments();
        
        // è¯»ç¼“存数据
@@ -206,6 +246,10 @@
        };
        listener.onDataChanged = [&](void* pEquipment, int code) -> void {
            m_bDataModify = TRUE;
            CEquipment* p = (CEquipment*)pEquipment;
            if (m_listener.onEqDataChanged != nullptr) {
                m_listener.onEqDataChanged(this, p, 0);
            }
        };
        pEquipment->setListener(listener);
@@ -255,7 +299,7 @@
        return pEquipment;
    }
    int CMaster::addFliper()
    CFliper* CMaster::addFliper()
    {
        CFliper* pEquipment = new CFliper();
        pEquipment->setID(EQ_ID_FLIPER);
@@ -269,10 +313,10 @@
        pEquipment->init();
        LOGE("已添加“Fliper”.");
        return 0;
        return pEquipment;
    }
    int CMaster::addVacuumBake()
    CVacuumBake* CMaster::addVacuumBake()
    {
        CVacuumBake* pEquipment = new CVacuumBake();
        pEquipment->setID(EQ_ID_VACUUMBAKE);
@@ -286,10 +330,11 @@
        pEquipment->init();
        LOGE("已添加“VacuumBake”.");
        return 0;
        return pEquipment;
    }
    int CMaster::addAligner()
    CAligner* CMaster::addAligner()
    {
        CAligner* pEquipment = new CAligner();
        pEquipment->setID(EQ_ID_ALIGNER);
@@ -303,7 +348,8 @@
        pEquipment->init();
        LOGE("已添加“Aligner”.");
        return 0;
        return pEquipment;
    }
    CEFEM* CMaster::addEFEM()
@@ -324,11 +370,43 @@
        return pEquipment;
    }
    CArm* CMaster::addArm()
    {
        CArm* pEquipment = new CArm();
        pEquipment->setID(EQ_ID_ARM);
        pEquipment->setBaseAlarmId(BASE_ALARM_EFEM);
        pEquipment->setName("ARM");
        pEquipment->setDescription("ARM.");
        addToEquipmentList(pEquipment);
        pEquipment->init();
        LOGE("已添加“ARM”.");
        return pEquipment;
    }
    CArmTray* CMaster::addArmTray(int index)
    {
        CArmTray* pEquipment = new CArmTray();
        pEquipment->setID(index == 0 ? EQ_ID_ARM_TRAY1 : EQ_ID_ARM_TRAY2);
        pEquipment->setBaseAlarmId(BASE_ALARM_EFEM);
        pEquipment->setName(index == 0 ? "Arm Tray1" : "Arm Tray2");
        pEquipment->setDescription(index == 0 ? "Arm Tray1." : "Arm Tray2.");
        addToEquipmentList(pEquipment);
        pEquipment->init();
        LOGE("已添加“%s”.", pEquipment->getName().c_str());
        return pEquipment;
    }
    /* æ·»åŠ bonder1 æˆ– bonder2 
     * index -- 0, bonder1
     * index -- 1, bonder2
     */
    int CMaster::addBonder(int index)
    CBonder* CMaster::addBonder(int index)
    {
        ASSERT(index == 0 || index == 1);
        CBonder* pEquipment = new CBonder();
@@ -346,10 +424,10 @@
        LOGE("已添加“%s”.", pEquipment->getName().c_str());
        return 0;
        return pEquipment;
    }
    int CMaster::addBakeCooling()
    CBakeCooling* CMaster::addBakeCooling()
    {
        CBakeCooling* pEquipment = new CBakeCooling();
        pEquipment->setID(EQ_ID_BAKE_COOLING);
@@ -360,10 +438,10 @@
        pEquipment->setStation(0, 255);
        addToEquipmentList(pEquipment);
        pEquipment->init();
        LOGE("已添加“Aligner”.");
        return 0;
        return pEquipment;
    }
    void CMaster::onTimer(UINT nTimerid)
SourceCode/Bond/Servo/CMaster.h
@@ -8,6 +8,8 @@
#include "CAligner.h"
#include "CVacuumBake.h"
#include "CBakeCooling.h"
#include "CArm.h"
#include "CArmTray.h"
#include "CCLinkIEControl.h"
@@ -16,12 +18,14 @@
    typedef std::function<void(CStep* pStep, int code, void* pData)> ONEQSTEPEVENT;
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int state, int alarmId, int unitId, int level)> ONEQALARM;
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, CVcrEventReport* pReport)> ONEQVCREVENTREPORT;
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int code)> ONEQDATACHANGED;
    typedef struct _MasterListener
    {
        ONEQALIVE                onEqAlive;
        ONEQALIVE                onEqCimStateChanged;
        ONEQALARM               onEqAlarm;
        ONEQVCREVENTREPORT        onEqVcrEventReport;
        ONEQDATACHANGED         onEqDataChanged;
    } MasterListener;
    class CMaster
@@ -44,12 +48,14 @@
    private:
        int addToEquipmentList(CEquipment* pEquipment);
        CLoadPort* addLoadPort(int index);
        int addFliper();
        int addVacuumBake();
        int addAligner();
        CFliper* addFliper();
        CVacuumBake* addVacuumBake();
        CAligner* addAligner();
        CEFEM* addEFEM();
        int addBonder(int index);
        int addBakeCooling();
        CArm* addArm();
        CArmTray* addArmTray(int index);
        CBonder* addBonder(int index);
        CBakeCooling* addBakeCooling();
        void connectEquipments();
        int saveCache();
        int saveCacheAndBackups();
SourceCode/Bond/Servo/CPageGraph1.cpp
@@ -276,6 +276,11 @@
    if (m_hbrBkgnd != nullptr) {
        ::DeleteObject(m_hbrBkgnd);
    }
    if (m_pObserver != nullptr) {
        m_pObserver->unsubscribe();
        m_pObserver = NULL;
    }
}
void CPageGraph1::OnSize(UINT nType, int cx, int cy)
SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -22,6 +22,7 @@
    m_pEqsGraphWnd = nullptr;
    m_crBkgnd = PAGE_GRPAH2_BACKGROUND_COLOR;
    m_hbrBkgnd = nullptr;
    m_pObserver = nullptr;
}
CPageGraph2::~CPageGraph2()
@@ -44,6 +45,40 @@
// CPageGraph2 æ¶ˆæ¯å¤„理程序
void CPageGraph2::InitRxWindows()
{
    /* code */
    // è®¢é˜…数据
    IRxWindows* pRxWindows = RX_GetRxWindows();
    pRxWindows->enableLog(5);
    if (m_pObserver == NULL) {
        m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
            // onNext
            pAny->addRef();
            int code = pAny->getCode();
            if (RX_CODE_EQ_DATA_CHANGED == code) {
                // é€šçŸ¥è®¾å¤‡çŠ¶æ€
                SERVO::CEquipment* pEquipment = nullptr;
                if (pAny->getPtrValue("ptr", (void*&)pEquipment)) {
                    if (pEquipment != nullptr) {
                        m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, !pEquipment->isGlassListEmpty());
                    }
                }
            }
            pAny->release();
            }, [&]() -> void {
                // onComplete
            }, [&](IThrowable* pThrowable) -> void {
                // onErrorm
                pThrowable->printf();
            });
        theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
            ->subscribe(m_pObserver);
    }
}
BOOL CPageGraph2::OnInitDialog()
{
@@ -154,11 +189,14 @@
        // æµ‹è¯•
        else if (nCmd == ID_EQSGRAPHITEM_TEST1) {
            SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
            pEquipment->outputGlass(0);
            if (pEquipment->getID() == EQ_ID_LOADPORT1) {
                pEquipment->outputGlass(1);
            }
            pEquipment->fetchedOut("P20250320A1A2");
        }
        else if (nCmd == ID_EQSGRAPHITEM_TEST2) {
            SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
            pEquipment->outputGlass(1);
            pEquipment->storeJob("P20250320A1A2");
        }
        else if (nCmd == ID_EQSGRAPHITEM_TEST3) {
            SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
@@ -216,13 +254,13 @@
            }
            */
            
            /*
            if (pEquipment->getID() == EQ_ID_Bonder1
                || pEquipment->getID() == EQ_ID_Bonder2) {
                static int ii = 0; ii++;
                pEquipment->setEqMode((ii % 5) + 1);
            }
            */
            /*
            SERVO::CGlass* pGlass = pEquipment->getFrontGlass();
@@ -290,6 +328,11 @@
    if (m_hbrBkgnd != nullptr) {
        ::DeleteObject(m_hbrBkgnd);
    }
    if (m_pObserver != nullptr) {
        m_pObserver->unsubscribe();
        m_pObserver = NULL;
    }
}
@@ -325,11 +368,14 @@
    for (auto outPin : outPins) {
        m_pEqsGraphWnd->AddPin(pItem, OUTPIN, outPin->getName().c_str(), (DWORD_PTR)outPin);
    }
    m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, !pEquipment->isGlassListEmpty());
}
void CPageGraph2::OnTimer(UINT_PTR nIDEvent)
{
    if (1 == nIDEvent) {
        InitRxWindows();
        KillTimer(1);
        std::list<SERVO::CEquipment*>& eqs = theApp.m_model.m_master.getEquipmentList();
        for (auto eq : eqs) {
SourceCode/Bond/Servo/CPageGraph2.h
@@ -14,11 +14,13 @@
private:
    void InitRxWindows();
    void AddEqToGraphWnd(SERVO::CEquipment* pEquipment);
    void SaveEqsGraphData();
    void GetItemDataFormIni(const char* pszItemName, int& left, int& top);
private:
    IObserver* m_pObserver;
    CEqsGraphWnd* m_pEqsGraphWnd;
    COLORREF m_crBkgnd;
    HBRUSH m_hbrBkgnd;
SourceCode/Bond/Servo/CStep.cpp
@@ -70,6 +70,18 @@
    }
    void CStep::setProp(const char* pszKey, void* pValue)
    {
        m_mapProp[pszKey] = pValue;
    }
    void* CStep::getProp(const char* pszKey)
    {
        auto iter = m_mapProp.find(pszKey);
        if (iter == m_mapProp.end()) return nullptr;
        return iter->second;
    }
    void CStep::convertString(const char* pszBuffer, int size, std::string& strOut)
    {
        strOut.clear();
SourceCode/Bond/Servo/CStep.h
@@ -2,6 +2,7 @@
#include "CCLinkIEControl.h"
#include "CAttributeVector.h"
#include "ToolUnits.h"
#include <map>
namespace SERVO {
@@ -26,7 +27,8 @@
        virtual void getAttributeVector(CAttributeVector& attrubutes);
        virtual void init();
        virtual void term();
        void setProp(const char* pszKey, void* pValue);
        void* getProp(const char* pszKey);
    protected:
        inline void Lock() { EnterCriticalSection(&m_criticalSection); }
@@ -40,6 +42,7 @@
        CEquipment* m_pEquipment;
        CCCLinkIEControl* m_pCclink;
        CRITICAL_SECTION m_criticalSection;
        std::map<std::string, void*> m_mapProp;
    };
}
SourceCode/Bond/Servo/Common.h
@@ -13,6 +13,7 @@
#define RX_CODE_SELECT_STEP                1007
#define RX_CODE_ALARM_SET                1008
#define RX_CODE_ALARM_CLEAR                1009
#define RX_CODE_EQ_DATA_CHANGED            1010
/* Channel Name */
@@ -61,6 +62,9 @@
#define EQ_ID_VACUUMBAKE        9
#define EQ_ID_ALIGNER            10
#define EQ_ID_BAKE_COOLING        11
#define EQ_ID_ARM                12
#define EQ_ID_ARM_TRAY1            13
#define EQ_ID_ARM_TRAY2            14
#define EQ_ID_OPERATOR_REMOVE    999
@@ -143,6 +147,22 @@
#define STEP_EQ_MASTER_RECIPE_LIST        _T("EQMasterRecipeListReport")
#define STEP_EQ_RECIPE_PARAMETER_REQ    _T("EQRecipeParameterReq")
#define STEP_EQ_RECIPE_PARAMETER        _T("EQRecipeParameterReport")
#define STEP_EQ_FETCHED_OUT_JOBn        _T("EQFetchedOutJobReport")
#define STEP_EQ_FETCHED_OUT_JOB1        _T("EQFetchedOutJobReport1")
#define STEP_EQ_FETCHED_OUT_JOB2        _T("EQFetchedOutJobReport2")
#define STEP_EQ_FETCHED_OUT_JOB3        _T("EQFetchedOutJobReport3")
#define STEP_EQ_FETCHED_OUT_JOB4        _T("EQFetchedOutJobReport4")
#define STEP_EQ_FETCHED_OUT_JOB5        _T("EQFetchedOutJobReport5")
#define STEP_EQ_FETCHED_OUT_JOB6        _T("EQFetchedOutJobReport6")
#define STEP_EQ_FETCHED_OUT_JOB7        _T("EQFetchedOutJobReport7")
#define STEP_EQ_FETCHED_OUT_JOB8        _T("EQFetchedOutJobReport8")
#define STEP_EQ_FETCHED_OUT_JOB9        _T("EQFetchedOutJobReport9")
#define STEP_EQ_FETCHED_OUT_JOB10        _T("EQFetchedOutJobReport10")
#define STEP_EQ_FETCHED_OUT_JOB11        _T("EQFetchedOutJobReport11")
#define STEP_EQ_FETCHED_OUT_JOB12        _T("EQFetchedOutJobReport12")
#define STEP_EQ_FETCHED_OUT_JOB13        _T("EQFetchedOutJobReport13")
#define STEP_EQ_FETCHED_OUT_JOB14        _T("EQFetchedOutJobReport14")
#define STEP_EQ_FETCHED_OUT_JOB15        _T("EQFetchedOutJobReport15")
/* Step ID */
@@ -171,6 +191,21 @@
#define STEP_ID_RECIVE_JOB_UPS2                    0x581
#define STEP_ID_SENT_OUT_JOB_DOWNS1                0x590
#define STEP_ID_SENT_OUT_JOB_DOWNS2                0x591
#define STEP_ID_FETCHED_OUT_JOB_REPORT1            0x5AF
#define STEP_ID_FETCHED_OUT_JOB_REPORT2            0x5B0
#define STEP_ID_FETCHED_OUT_JOB_REPORT3            0x5B1
#define STEP_ID_FETCHED_OUT_JOB_REPORT4            0x5B2
#define STEP_ID_FETCHED_OUT_JOB_REPORT5            0x5B3
#define STEP_ID_FETCHED_OUT_JOB_REPORT6            0x5B4
#define STEP_ID_FETCHED_OUT_JOB_REPORT7            0x5B5
#define STEP_ID_FETCHED_OUT_JOB_REPORT8            0x5B6
#define STEP_ID_FETCHED_OUT_JOB_REPORT9            0x5B7
#define STEP_ID_FETCHED_OUT_JOB_REPORT10        0x5B8
#define STEP_ID_FETCHED_OUT_JOB_REPORT11        0x5B9
#define STEP_ID_FETCHED_OUT_JOB_REPORT12        0x5BA
#define STEP_ID_FETCHED_OUT_JOB_REPORT13        0x5BB
#define STEP_ID_FETCHED_OUT_JOB_REPORT14        0x5BC
#define STEP_ID_FETCHED_OUT_JOB_REPORT15        0x5BD
#define STEP_ID_PORT1_TYPE_CHANGE                0x600
#define STEP_ID_PORT2_TYPE_CHANGE                0x601
#define STEP_ID_PORT3_TYPE_CHANGE                0x602
SourceCode/Bond/Servo/EqsGraphWnd.cpp
@@ -1911,10 +1911,12 @@
    HBRUSH hbrItemBackground[2];
    HBRUSH hbrItemFrame[2];
    HBRUSH hbrPinBackground[3];
    HBRUSH hbrIndicator;
    hbrItemBackground[0] = CreateSolidBrush(m_crItemBackground[0]);
    hbrItemBackground[1] = CreateSolidBrush(m_crItemBackground[1]);
    hbrItemFrame[0] = CreateSolidBrush(m_crItemFrame[0]);
    hbrItemFrame[1] = CreateSolidBrush(m_crItemFrame[1]);
    hbrIndicator = CreateSolidBrush(RGB(34, 177, 76));
    for (int i = 0; i < 3; i++) {
        hbrPinBackground[i] = CreateSolidBrush(m_crPinBkgnd[i]);
    }
@@ -1960,6 +1962,21 @@
            HFONT hFontOld = (HFONT)::SelectObject(hMemDC, m_hFontName);
            ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemNameText[1] : m_crItemNameText[0]);
            ::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
            // æ·»åŠ ä¸€ä¸ªå°ç»¿ç‚¹æŒ‡ç¤ºå™¨
            if(pItem->bShowIndicator[0]){
                RECT rcIndicator;
                rcIndicator.left = rcItem.left + 5;
                rcIndicator.top = rcItem.top + 5;
                rcIndicator.right = rcIndicator.left + 12;
                rcIndicator.bottom = rcIndicator.top + 12;
                HRGN hRgn = CreateRoundRectRgn(rcIndicator.left, rcIndicator.top, rcIndicator.right, rcIndicator.bottom, 2, 2);
                ::FillRgn(hMemDC, hRgn, hbrIndicator);
                ::FrameRgn(hMemDC, hRgn, hbrItemFrame[0], 1, 1);
                ::DeleteObject(hRgn);
            }
            if (pItem->nShowType != ITEM_SMALL) {
                RECT rcId = rcItem;
@@ -2074,6 +2091,7 @@
        ::DeleteObject(hbrItemBackground[1]);
        ::DeleteObject(hbrItemFrame[0]);
        ::DeleteObject(hbrItemFrame[1]);
        ::DeleteObject(hbrIndicator);
    }
@@ -2390,6 +2408,15 @@
    SetTimer(m_hWnd, TIMER_ANIMATION_RECT, uElpase, NULL);
}
void CEqsGraphWnd::ShowItemIndicator(DWORD_PTR dwItemData, BOOL bShow)
{
    EQITEM* pItem = GetItem(dwItemData);
    if (pItem != nullptr) {
        pItem->bShowIndicator[0] = bShow;
        ::InvalidateRect(m_hWnd, nullptr, TRUE);
    }
}
double CEqsGraphWnd::PointToSegDist(double x, double y, double x1, double y1, double x2, double y2)
{
    double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
SourceCode/Bond/Servo/EqsGraphWnd.h
@@ -54,6 +54,7 @@
    DWORD_PTR pInPins;
    DWORD_PTR pOutPins;
    int nFlashFlag;
    BOOL bShowIndicator[2];
} EQITEM;
typedef struct tagPIN
@@ -143,6 +144,7 @@
    void SetItemPos(EQITEM* pItem, int x, int y);
    void FlashItem(EQITEM* pItem);
    void AnimationItem(EQITEM*pItem);
    void ShowItemIndicator(DWORD_PTR dwItemData, BOOL bShow);
private:
    void Init();
SourceCode/Bond/Servo/Model.cpp
@@ -152,6 +152,10 @@
    masterListener.onEqVcrEventReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, SERVO::CVcrEventReport* pReport) {
        LOGE("<CModel>onEqVcrEventReport.");
    };
    masterListener.onEqDataChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, int code) {
        LOGE("<CModel>onEqDataChanged.");
        notifyPtr(RX_CODE_EQ_DATA_CHANGED, pEquipment);
    };
    m_master.setListener(masterListener);
SourceCode/Bond/Servo/Servo.rc
Binary files differ
SourceCode/Bond/Servo/Servo.vcxproj
@@ -133,7 +133,7 @@
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
    <PostBuildEvent>
      <Command>copy "$(TargetDir)$(ProjectName).exe" "\\Boounion-0106\Servo\\$(ProjectName).exe"</Command>
      <Command>copy "$(TargetDir)$(ProjectName).exe" "\\DESKTOP-IODBVIQ\Servo\Debug\$(ProjectName).exe"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -200,6 +200,8 @@
    <ClInclude Include="ApredTreeCtrl2.h" />
    <ClInclude Include="BlButton.h" />
    <ClInclude Include="CAligner.h" />
    <ClInclude Include="CArm.h" />
    <ClInclude Include="CArmTray.h" />
    <ClInclude Include="CAttribute.h" />
    <ClInclude Include="CAttributeVector.h" />
    <ClInclude Include="CBakeCooling.h" />
@@ -291,6 +293,8 @@
    <ClCompile Include="ApredTreeCtrl2.cpp" />
    <ClCompile Include="BlButton.cpp" />
    <ClCompile Include="CAligner.cpp" />
    <ClCompile Include="CArm.cpp" />
    <ClCompile Include="CArmTray.cpp" />
    <ClCompile Include="CAttribute.cpp" />
    <ClCompile Include="CAttributeVector.cpp" />
    <ClCompile Include="CBakeCooling.cpp" />
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -97,6 +97,8 @@
    <ClCompile Include="CEqReadStep.cpp" />
    <ClCompile Include="CRecipesManager.cpp" />
    <ClCompile Include="CRecipeList.cpp" />
    <ClCompile Include="CArm.cpp" />
    <ClCompile Include="CArmTray.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AlarmManager.h" />
@@ -192,6 +194,8 @@
    <ClInclude Include="CEqReadStep.h" />
    <ClInclude Include="CRecipesManager.h" />
    <ClInclude Include="CRecipeList.h" />
    <ClInclude Include="CArm.h" />
    <ClInclude Include="CArmTray.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc" />
SourceCode/Bond/Servo/Servo.vcxproj.user
@@ -4,9 +4,9 @@
    <RESOURCE_FILE>Servo.rc</RESOURCE_FILE>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <RemoteDebuggerCommand>D:\CLH\Servo\Servo.exe</RemoteDebuggerCommand>
    <RemoteDebuggerWorkingDirectory>D:\CLH\Servo\</RemoteDebuggerWorkingDirectory>
    <RemoteDebuggerServerName>Boounion-0106</RemoteDebuggerServerName>
    <RemoteDebuggerCommand>D:\Servo\Debug\Servo.exe</RemoteDebuggerCommand>
    <RemoteDebuggerWorkingDirectory>D:\Servo\Debug\</RemoteDebuggerWorkingDirectory>
    <RemoteDebuggerServerName>DESKTOP-IODBVIQ</RemoteDebuggerServerName>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
</Project>