已修改6个文件
151 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CCjPage2.cpp 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.cpp 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/PortConfigurationDlg.cpp 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CCjPage2.cpp
@@ -13,6 +13,40 @@
    IDC_BUTTON_PORT3_PROCESS_START,
    IDC_BUTTON_PORT4_PROCESS_START };
namespace {
    void BuildCassetteCtrlMaps(SERVO::CLoadPort* pPort, short (&jobExistence)[12], short& slotProcess)
    {
        slotProcess = 0;
        bool anyScheduled = false;
        // Prefer hardware scan map for job existence (first 16 slots).
        const short scanMap = pPort->getScanCassetteMap();
        if (scanMap != 0) {
            jobExistence[0] = scanMap;
        }
        const int maxSlots = 12 * 16;
        const int totalSlots = (SLOT_MAX < maxSlots) ? SLOT_MAX : maxSlots;
        for (int slot = 1; slot <= totalSlots; ++slot) {
            SERVO::CGlass* pGlass = pPort->getGlassFromSlot(slot);
            if (pGlass == nullptr) continue;
            const int wordIndex = (slot - 1) / 16;
            const int bitIndex = (slot - 1) % 16;
            jobExistence[wordIndex] = (short)(jobExistence[wordIndex] | (1 << bitIndex));
            if (slot <= 16 && pGlass->isScheduledForProcessing()) {
                slotProcess = (short)(slotProcess | (1 << bitIndex));
                anyScheduled = true;
            }
        }
        if (!anyScheduled) {
            slotProcess = jobExistence[0];
        }
    }
}
// CPjPage1 对话框
IMPLEMENT_DYNAMIC(CCjPage2, CCjPageBase)
@@ -452,7 +486,11 @@
{
    auto& master = theApp.m_model.getMaster();
    auto port = (SERVO::CLoadPort*)master.getEquipment(EQ_ID_LOADPORT1);
    port->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
    if (port == nullptr) return;
    short jobExistence[12] = { 0 };
    short slotProcess = 0;
    BuildCassetteCtrlMaps(port, jobExistence, slotProcess);
    port->sendCassetteCtrlCmd(CCC_PROCESS_START, jobExistence, 12, slotProcess, 0, nullptr, nullptr);
}
@@ -460,21 +498,33 @@
{
    auto& master = theApp.m_model.getMaster();
    auto port = (SERVO::CLoadPort*)master.getEquipment(EQ_ID_LOADPORT2);
    port->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
    if (port == nullptr) return;
    short jobExistence[12] = { 0 };
    short slotProcess = 0;
    BuildCassetteCtrlMaps(port, jobExistence, slotProcess);
    port->sendCassetteCtrlCmd(CCC_PROCESS_START, jobExistence, 12, slotProcess, 0, nullptr, nullptr);
}
void CCjPage2::OnBnClickedButtonPort3ProcessStart()
{
    auto& master = theApp.m_model.getMaster();
    auto port = (SERVO::CLoadPort*)master.getEquipment(EQ_ID_LOADPORT3);
    port->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
    if (port == nullptr) return;
    short jobExistence[12] = { 0 };
    short slotProcess = 0;
    BuildCassetteCtrlMaps(port, jobExistence, slotProcess);
    port->sendCassetteCtrlCmd(CCC_PROCESS_START, jobExistence, 12, slotProcess, 0, nullptr, nullptr);
}
void CCjPage2::OnBnClickedButtonPort4ProcessStart()
{
    auto& master = theApp.m_model.getMaster();
    auto port = (SERVO::CLoadPort*)master.getEquipment(EQ_ID_LOADPORT4);
    port->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
    if (port == nullptr) return;
    short jobExistence[12] = { 0 };
    short slotProcess = 0;
    BuildCassetteCtrlMaps(port, jobExistence, slotProcess);
    port->sendCassetteCtrlCmd(CCC_PROCESS_START, jobExistence, 12, slotProcess, 0, nullptr, nullptr);
}
SourceCode/Bond/Servo/CEFEM.cpp
@@ -713,14 +713,27 @@
                        // Reserved                    15W
                        short ack = (short)JobDataRequestAck::NG;        // 不存在jobData
                        char szBuffer[1024] = { 0 };
                        LOGI("<CEFEM-%s>JobDataRequest received (code=%d, size=%zu)", m_strName.c_str(), code, size);
                        if (m_pActiveContext != nullptr) {
                            CJobDataS* pJobDataS = ((CGlass*)m_pActiveContext)->getJobDataS();
                            LOGI("<CEFEM-%s>JobDataRequest GlassID=%s", m_strName.c_str(), ((CGlass*)m_pActiveContext)->getID().c_str());
                            if (pJobDataS != nullptr) {
                                pJobDataS->serialize(szBuffer, 1024);
                                ack = (short)JobDataRequestAck::OK;
                                LOGI("<CEFEM-%s>JobDataRequest OK (CassetteSeq=%d, JobSeq=%d)",
                                    m_strName.c_str(),
                                    pJobDataS->getCassetteSequenceNo(),
                                    pJobDataS->getJobSequenceNo());
                            }
                            else {
                                LOGW("<CEFEM-%s>JobDataRequest NG (JobDataS is null)", m_strName.c_str());
                            }
                        }
                        else {
                            LOGW("<CEFEM-%s>JobDataRequest NG (ActiveContext is null)", m_strName.c_str());
                        }
                        memcpy(&szBuffer[320 * 2], &ack, sizeof(short));
                        LOGI("<CEFEM-%s>JobDataRequest response ack=%d", m_strName.c_str(), (int)ack);
                        ((CEqReadStep*)pFrom)->setReturnData(szBuffer, 336 * 2);
                    }
                    return -1;
SourceCode/Bond/Servo/CMaster.cpp
@@ -2907,7 +2907,40 @@
        static int pid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4};
        CLoadPort* pPort = (CLoadPort*)getEquipment(pid[port]);
        pPort->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
        if (pPort == nullptr) return -1;
        short jobExistence[12] = { 0 };
        short slotProcess = 0;
        short jobCount = 0; // 0 = Process All Glass
        bool anyScheduled = false;
        // Prefer hardware scan map for job existence (first 16 slots).
        const short scanMap = pPort->getScanCassetteMap();
        if (scanMap != 0) {
            jobExistence[0] = scanMap;
        }
        const int maxSlots = 12 * 16;
        const int totalSlots = (SLOT_MAX < maxSlots) ? SLOT_MAX : maxSlots;
        for (int slot = 1; slot <= totalSlots; ++slot) {
            CGlass* pGlass = pPort->getGlassFromSlot(slot);
            if (pGlass == nullptr) continue;
            const int wordIndex = (slot - 1) / 16;
            const int bitIndex = (slot - 1) % 16;
            jobExistence[wordIndex] = (short)(jobExistence[wordIndex] | (1 << bitIndex));
            if (slot <= 16 && pGlass->isScheduledForProcessing()) {
                slotProcess = (short)(slotProcess | (1 << bitIndex));
                anyScheduled = true;
            }
        }
        if (!anyScheduled) {
            slotProcess = jobExistence[0];
        }
        pPort->sendCassetteCtrlCmd(CCC_PROCESS_START, jobExistence, 12, slotProcess, jobCount, nullptr, nullptr);
        return 0;
    }
SourceCode/Bond/Servo/CMaster.h
@@ -72,7 +72,7 @@
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, const std::vector<CParam>& params)> ONSVDATAREPORT;
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int port, CJobDataS* pJobDataS)> ONJOBRECEIVED;
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int port, CJobDataS* pJobDataS)> ONJOBSENTOUT;
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int unitId, int status, int reason)> ONEQSTATUSCHANGED;
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int unitId, int status, int reason)> ONEQSTATUSCHANGEDEX;
    typedef std::function<void(void* pMaster, int round)> ONCTROUNDEND;
    typedef std::function<void(void* pMaster, void* pj)> ONPJSTART;
    typedef std::function<void(void* pMaster)> ONCONTROLJOBCHANGED;
@@ -91,7 +91,7 @@
        ONPROCESSDATAREPORTEX   onProcessDataReport;
        ONJOBRECEIVED           onJobReceived;
        ONJOBSENTOUT            onJobSentOut;
        ONEQSTATUSCHANGED       onEqStatusChanged;
        ONEQSTATUSCHANGEDEX       onEqStatusChanged;
        ONCTROUNDEND            onCTRoundEnd;
        ONPJSTART               onCjStart;
        ONPJSTART               onCjEnd;
SourceCode/Bond/Servo/Model.cpp
@@ -975,7 +975,7 @@
        if (pEquipment == nullptr) return;
        m_hsmsPassive.withVariableLock([&] {
            m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str());
            m_hsmsPassive.setVariableValue("SubEqpSlot", unitId);
            m_hsmsPassive.setVariableValue("SubEqpSlot", (__int64)unitId);
            m_hsmsPassive.setVariableValue("EquipmentStatus", (__int64)status);
            m_hsmsPassive.requestEventReportSend("SubEqpStateChange");
        });
@@ -990,7 +990,7 @@
                if (pEquipment != nullptr) {
                    m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str());
                }
                m_hsmsPassive.setVariableValue("SubEqpSlot", 0);
                m_hsmsPassive.setVariableValue("SubEqpSlot", (__int64)0);
                m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str());
                for (size_t idx = 0; idx < count; ++idx) {
                    const std::string val = formatParamValue(params[idx]);
@@ -1036,7 +1036,7 @@
                if (pEquipment != nullptr) {
                    m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str());
                }
                m_hsmsPassive.setVariableValue("SubEqpSlot", 0);
                m_hsmsPassive.setVariableValue("SubEqpSlot", (__int64)0);
                m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str());
                for (size_t idx = 0; idx < count; ++idx) {
                    const std::string val = formatParamValue(params[idx]);
SourceCode/Bond/Servo/PortConfigurationDlg.cpp
@@ -451,7 +451,40 @@
    constexpr short cmd = CCC_PROCESS_START;
    LOGI("ProcessStart request: port=%d, cmd=%d", selPort + 1, cmd);
    int ret = pPort->sendCassetteCtrlCmd(cmd, nullptr, 0, 0, 0, nullptr,
    short jobExistence[12] = { 0 };
    short slotProcess = 0;
    short jobCount = 0; // 0 = Process All Glass (per spec)
    bool anyScheduled = false;
    // Prefer hardware scan map for job existence (first 16 slots).
    const short scanMap = pPort->getScanCassetteMap();
    if (scanMap != 0) {
        jobExistence[0] = scanMap;
    }
    // Build existence/selected maps from current glass list (up to 192 slots).
    const int maxSlots = 12 * 16;
    const int totalSlots = (SLOT_MAX < maxSlots) ? SLOT_MAX : maxSlots;
    for (int slot = 1; slot <= totalSlots; ++slot) {
        SERVO::CGlass* pGlass = pPort->getGlassFromSlot(slot);
        if (pGlass == nullptr) continue;
        const int wordIndex = (slot - 1) / 16;
        const int bitIndex = (slot - 1) % 16;
        jobExistence[wordIndex] = (short)(jobExistence[wordIndex] | (1 << bitIndex));
        if (slot <= 16 && pGlass->isScheduledForProcessing()) {
            slotProcess = (short)(slotProcess | (1 << bitIndex));
            anyScheduled = true;
        }
    }
    // If no slot explicitly selected, default to all existing in the first word.
    if (!anyScheduled) {
        slotProcess = jobExistence[0];
    }
    int ret = pPort->sendCassetteCtrlCmd(cmd, jobExistence, 12, slotProcess, jobCount, nullptr,
        [selPort](int code) -> int {
            if (code == WOK) {
                LOGI("ProcessStart write complete: port=%d, code=WOK", selPort + 1);