| | |
| | | CGlass* pGlass = this->getGlassWithCassette(processData.getCassetteSequenceNo(), |
| | | processData.getJobSequenceNo()); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>æ¾ä¸å°å¯¹åºGlass, å
³èå·¥èºåæ°å¤±è´¥ã", this->getName().c_str(), |
| | | LOGE("<CEquipment-%s>æ¾ä¸å°å¯¹åºGlass, å
³èå·¥èºåæ°å¤±è´¥ãCassetteSequenceNo:%d/%d", |
| | | this->getName().c_str(), |
| | | processData.getCassetteSequenceNo(), |
| | | processData.getJobSequenceNo()); |
| | | return -1; |
| | |
| | | getName().c_str(), cassetteNo, jobSequenceNo); |
| | | return -1; |
| | | } |
| | | pGlass->setInspResult(m_nID, 0, judgeStringToInspResult(strPanelJudgeData)); |
| | | auto result = judgeStringToInspResult(strPanelJudgeData); |
| | | pGlass->setInspResult(m_nID, 0, result); |
| | | |
| | | if (m_listener.onPanelDataReport != nullptr) { |
| | | m_listener.onPanelDataReport(this, pGlass); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | |
| | | ONMAPMISMATCH onMapMismatch; |
| | | ONPORTSTATUSCHANGED onPortStatusChanged; |
| | | ONVCREVENTREPORT onSVDataReport; |
| | | ONVCREVENTREPORT onPanelDataReport; |
| | | } EquipmentListener; |
| | | |
| | | |
| | |
| | | return (m_nIndex + 1) * 1000 + m_nNextCassetteSequenceNo; |
| | | } |
| | | |
| | | int CLoadPort::getPortCassetteSnSeed() |
| | | { |
| | | return m_nNextCassetteSequenceNo; |
| | | } |
| | | |
| | | void CLoadPort::setPortCassetteSnSeed(int seed) |
| | | { |
| | | m_nNextCassetteSequenceNo = seed; |
| | | if (m_nNextCassetteSequenceNo >= 1000) { |
| | | m_nNextCassetteSequenceNo = 0; |
| | | } |
| | | } |
| | | |
| | | void CLoadPort::setIndex(unsigned int index) |
| | | { |
| | | m_nIndex = index; |
| | |
| | | |
| | | public: |
| | | short getNextCassetteSequenceNo(); |
| | | int getPortCassetteSnSeed(); |
| | | void setPortCassetteSnSeed(int seed); |
| | | void setIndex(unsigned int index); |
| | | unsigned int getIndex(); |
| | | BOOL isEnable(); |
| | |
| | | m_ullRunTime = 0; |
| | | m_state = MASTERSTATE::READY; |
| | | m_pActiveRobotTask = nullptr; |
| | | m_nLastError = 0; |
| | | m_nLastError = ER_CODE_NOERROR; |
| | | m_isCompareMapsBeforeProceeding = FALSE; |
| | | m_bJobMode = FALSE; |
| | | m_bEnableEventReport = true; |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CMaster::stop() |
| | | int CMaster::stop(int nErCode/* = ER_CODE_NOERROR*/) |
| | | { |
| | | // è¿è¡æ¶é´ä¸ºç´¯å ç»æï¼æ¬æ¬¡åæ¢æ¶å·æ°ï¼ |
| | | lock(); |
| | |
| | | |
| | | |
| | | // æ´æ°ç¶æ |
| | | m_nLastError = nErCode; |
| | | setState(MASTERSTATE::STOPPING); |
| | | |
| | | |
| | |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>EFEM忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = "EFEM忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>Bonder1忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_BONDER_OPERATION_MODE_FAIL; |
| | | m_strLastError = "Bonder1忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>Bonder2忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_BONDER_OPERATION_MODE_FAIL; |
| | | m_strLastError = "Bonder2忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>BakeCooling忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = "BakeCooling忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>VacuumBake忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = "VacuumBake忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>Measurement忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = "Measurement忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>%s忢Stopç¶æåé失败", pEq[i]->getName().c_str()); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = pEq[i]->getName() + "忢Stopç¶æåé失败."; |
| | | bIomcOk[i] = FALSE; |
| | | promises[i].set_value(); // é¿å
wait é»å¡ |
| | |
| | | } |
| | | |
| | | LOGI("<Master>ææè®¾å¤æååæ¢å° Stop 模å¼"); |
| | | setState(MASTERSTATE::READY); |
| | | if(m_nLastError == ER_CODE_NOERROR) |
| | | setState(MASTERSTATE::READY); |
| | | else |
| | | setState(MASTERSTATE::ATHERERROR); |
| | | |
| | | continue; |
| | | } |
| | | |
| | |
| | | continue; |
| | | } |
| | | |
| | | pGlass->queue(); |
| | | pGlass->start(); |
| | | pEFEM->setContext(m_pActiveRobotTask->getContext()); |
| | | goto PORT_GET; |
| | |
| | | if (m_pActiveRobotTask->getSrcPosition() == EQ_ID_MEASUREMENT) { |
| | | CGlass* pGlass = (CGlass*)m_pActiveRobotTask->getContext(); |
| | | pGlass->complete(); |
| | | CGlass* pBuddy = pGlass->getBuddy(); |
| | | if (pBuddy != nullptr) pBuddy->complete(); |
| | | this->saveState(); |
| | | bool bMoved = glassFromInPorcessToComplete(pGlass); |
| | | if (bMoved) { |
| | |
| | | strOut.append(szBuffer); |
| | | } |
| | | LOGD("<CMaster-%s>SVDataReport:%s", ((CEquipment*)pEquipment)->getName().c_str(), strOut.c_str()); |
| | | }; |
| | | listener.onPanelDataReport = [&](void* pEquipment, void* pContext) { |
| | | LOGD("<CMaster-%s>onPanelDataReport", ((CEquipment*)pEquipment)->getName().c_str()); |
| | | |
| | | CEquipment* pEq = (CEquipment*)pEquipment; |
| | | CGlass* pGlass = (CGlass*)pContext; |
| | | |
| | | // 妿AOIæ£æµå¤±è´¥ï¼è¦åæº |
| | | if (pEq->getID() == EQ_ID_MEASUREMENT) { |
| | | LOGD("<CMaster-%s>onPanelDataReport 01", ((CEquipment*)pEquipment)->getName().c_str()); |
| | | if (pGlass->getAOIInspResult() == InspResult::Fail) { |
| | | LOGD("<CMaster-%s>onPanelDataReport 02", ((CEquipment*)pEquipment)->getName().c_str()); |
| | | if (stop() == 0) { |
| | | m_nLastError = ER_CODE_AOI_NG; |
| | | m_strLastError = "AOIæ£æµæªéè¿."; |
| | | } |
| | | } |
| | | } |
| | | |
| | | }; |
| | | pEquipment->setListener(listener); |
| | | pEquipment->setCcLink(&m_cclink); |
| | |
| | | if (!m_inProcesGlasses.empty()) { |
| | | CGlass* pGlass = m_inProcesGlasses.front(); |
| | | pGlass->complete(); |
| | | CGlass* pBuddy = pGlass->getBuddy(); |
| | | if (pBuddy != nullptr) pBuddy->complete(); |
| | | glassFromInPorcessToComplete(pGlass); |
| | | this->saveState(); |
| | | |
| | |
| | | pPort->localEanblePort(bEnable); |
| | | } |
| | | |
| | | int CMaster::getPortCassetteSnSeed(int port) |
| | | { |
| | | ASSERT(1 <= port && port <= 4); |
| | | int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 }; |
| | | CLoadPort* pPort = (CLoadPort*)getEquipment(eqid[port - 1]); |
| | | return pPort->getPortCassetteSnSeed(); |
| | | } |
| | | |
| | | void CMaster::setPortCassetteSnSeed(int port, int seed) |
| | | { |
| | | ASSERT(1 <= port && port <= 4); |
| | | int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 }; |
| | | CLoadPort* pPort = (CLoadPort*)getEquipment(eqid[port - 1]); |
| | | return pPort->setPortCassetteSnSeed(seed); |
| | | } |
| | | |
| | | void CMaster::setCompareMapsBeforeProceeding(BOOL bCompare) |
| | | { |
| | | m_isCompareMapsBeforeProceeding = bCompare; |
| | |
| | | |
| | | return (int)glasses.size(); |
| | | } |
| | | |
| | | int CMaster::getLastError() |
| | | { |
| | | return m_nLastError; |
| | | } |
| | | |
| | | std::string& CMaster::getLastErrorText() |
| | | { |
| | | return m_strLastError; |
| | | } |
| | | |
| | | void CMaster::test() |
| | | { |
| | | if (stop() == 0) { |
| | | m_nLastError = ER_CODE_AOI_NG; |
| | | m_strLastError = "AOIæ£æµæªéè¿."; |
| | | } |
| | | } |
| | | } |
| | |
| | | #define CTStep_begin CTStep_LoadPort_Aligner |
| | | #define CTStep_end CTStep_Measurement_LoadPort |
| | | |
| | | #define ER_CODE_NOERROR 0 |
| | | #define ER_CODE_OPERATION_MODE_FAIL -1 |
| | | #define ER_CODE_AOI_NG -2 |
| | | |
| | | namespace SERVO { |
| | | enum class MASTERSTATE { |
| | | READY = 0, |
| | |
| | | RUNNING_CONTINUOUS_TRANSFER, |
| | | RUNNING_BATCH, |
| | | STOPPING, |
| | | MSERROR |
| | | MSERROR, |
| | | ATHERERROR |
| | | }; |
| | | |
| | | typedef std::function<void(void* pMaster, MASTERSTATE state)> ONMASTERSTATECHANGED; |
| | |
| | | int start(); |
| | | int startContinuousTransfer(); |
| | | int startBatch(); |
| | | int stop(); |
| | | int stop(int nErCode = ER_CODE_NOERROR); |
| | | void clearError(); |
| | | ULONGLONG getRunTime(); |
| | | MASTERSTATE getState(); |
| | |
| | | bool saveState() const; |
| | | bool loadState(const std::string& path); |
| | | int getWipGlasses(std::vector<CGlass*>& glasses); |
| | | void test(); |
| | | int getPortCassetteSnSeed(int port); |
| | | void setPortCassetteSnSeed(int port, int seed); |
| | | |
| | | private: |
| | | inline void lock() { EnterCriticalSection(&m_criticalSection); } |
| | |
| | | bool ceidDefined(uint32_t ceid) const override; |
| | | |
| | | public: |
| | | int getLastError(); |
| | | std::string& getLastErrorText(); |
| | | |
| | | public: |
| | | // æ°å¢å½æ° |
| | | CProcessJob* acquireNextProcessJob(); |
| | | CGlass* acquireNextGlass(); |
| | |
| | | params.push_back(CParam("æ£æµé度", "", this->getName().c_str(), v * 0.001)); |
| | | i += 4; |
| | | |
| | | // 3.æ£æµé度 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("æ£æµé度", "", this->getName().c_str(), v * 0.001)); |
| | | i += 4; |
| | | |
| | | // 4.æ£æµ2æ°æ® |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("æ£æµé度", "", this->getName().c_str(), v * 0.001)); |
| | | i += 4; |
| | | |
| | | return (int)params.size(); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | bool CopyUtf8ToClipboard(const std::string& utf8) |
| | | { |
| | | // 1) UTF-8 -> UTF-16 é¿åº¦ï¼å«ç»å°¾ '\0'ï¼ |
| | | int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, nullptr, 0); |
| | | if (wlen <= 0) return false; |
| | | |
| | | // 2) 为åªè´´æ¿åé
å
¨å±å¯ç§»å¨å
åï¼å¿
é¡» GMEM_MOVEABLEï¼ |
| | | SIZE_T bytes = static_cast<SIZE_T>(wlen) * sizeof(wchar_t); |
| | | HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, bytes); |
| | | if (!hMem) return false; |
| | | |
| | | // 3) å¡«å
UTF-16 ææ¬ |
| | | wchar_t* wbuf = static_cast<wchar_t*>(GlobalLock(hMem)); |
| | | if (!wbuf) { GlobalFree(hMem); return false; } |
| | | MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, wbuf, wlen); |
| | | GlobalUnlock(hMem); |
| | | |
| | | // 4) æå¼åªè´´æ¿å¹¶è®¾ç½®æ°æ®ï¼CF_UNICODETEXTï¼ |
| | | if (!OpenClipboard(nullptr)) { GlobalFree(hMem); return false; } |
| | | if (!EmptyClipboard()) { CloseClipboard(); GlobalFree(hMem); return false; } |
| | | |
| | | // æååï¼å
åæææäº¤ç»åªè´´æ¿ï¼ä¸è½å GlobalFree |
| | | if (!SetClipboardData(CF_UNICODETEXT, hMem)) { |
| | | CloseClipboard(); |
| | | GlobalFree(hMem); |
| | | return false; |
| | | } |
| | | |
| | | CloseClipboard(); |
| | | return true; |
| | | } |
| | | |
| | | |
| | | // CPageGlassList å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CPageGlassList, CDialogEx) |
| | |
| | | } |
| | | |
| | | // ==================== 2) DB å½å页ï¼ä¸¤é¶æ®µæå»ºï¼å¤çåå buddyï¼ ==================== |
| | | const int rawLimit = PAGE_SIZE + 1; |
| | | const int rawOffset = PAGE_SIZE * (m_nCurPage - 1); |
| | | #if USE_FAKE_DB_DEMO |
| | | auto page = _make_page_fake(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1)); |
| | | auto page = _make_page_fake(m_filters, rawLimit, rawOffset); |
| | | #else |
| | | auto& db = GlassLogDb::Instance(); |
| | | auto page = db.queryPaged(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1)); |
| | | auto pageFull = db.queryPaged(m_filters, rawLimit, rawOffset); |
| | | #endif |
| | | |
| | | // 妿å¤åºä¸æ¡ï¼çç宿¯å¦æ¯âæ¬é¡µæå䏿¡âç buddy |
| | | std::optional<decltype(pageFull.items)::value_type> lookahead; // é¢è¯»è®°å½ï¼è¥ä¸æå䏿¡é
å¯¹ï¼ |
| | | auto iEquals = [](const std::string& a, const std::string& b) { |
| | | #ifdef _WIN32 |
| | | return _stricmp(a.c_str(), b.c_str()) == 0; |
| | | #else |
| | | return strcasecmp(a.c_str(), b.c_str()) == 0; |
| | | #endif |
| | | }; |
| | | |
| | | if (pageFull.items.size() == rawLimit) { |
| | | const auto& last = pageFull.items[PAGE_SIZE - 1]; |
| | | const auto& extra = pageFull.items[PAGE_SIZE]; |
| | | |
| | | bool pair = |
| | | (!last.buddyId.empty() && iEquals(last.buddyId, extra.classId)) || |
| | | (!extra.buddyId.empty() && iEquals(extra.buddyId, last.classId)); |
| | | |
| | | if (pair) { |
| | | lookahead = extra; // æé¢è¯»ä¿å䏿¥ï¼ç¨åè¡¥æåè¡ |
| | | } |
| | | // æ 论æ¯å¦é
对ï¼å表é½ç¼©å PAGE_SIZE æ¡ï¼é¢è¯»ä¸ç®å
¥æ¬é¡µæ°æ®éï¼ |
| | | pageFull.items.pop_back(); |
| | | } |
| | | |
| | | // ä¹åæ£å¸¸æ page æå»º |
| | | auto& page = pageFull; // 为äºå¤ç¨ä½ åæåéå |
| | | |
| | | // 建索å¼ï¼classId -> index |
| | | std::unordered_map<std::string, size_t> idxById; |
| | |
| | | // -------- Phase 1: å
å¤çâæ buddyId çè®°å½âï¼è½é
å°±é
ï¼ååä¹é
ï¼ ---------- |
| | | for (size_t i = 0; i < page.items.size(); ++i) { |
| | | const auto& r = page.items[i]; |
| | | // CopyUtf8ToClipboard(r.pretty); |
| | | |
| | | if (consumed.count(r.classId)) continue; |
| | | if (r.buddyId.empty()) continue; |
| | | |
| | |
| | | CString headers[] = { |
| | | _T(""), |
| | | _T("id"), |
| | | _T("Cassette Sequence No"), |
| | | _T("Job Sequence No"), |
| | | _T("Cassette SN"), |
| | | _T("Job SN"), |
| | | _T("Class ID"), |
| | | _T("ç©æç±»å"), |
| | | _T("ç¶æ"), |
| | |
| | | return GetPrivateProfileInt(_T("Master"), _T("CTRound"), 0, m_strFilepath); |
| | | } |
| | | |
| | | char* pszPortSection[] = { "Port1", "Port2", "Port3", "Port4" }; |
| | | int CConfiguration::getPortCassetteSnSeed(int port) |
| | | { |
| | | ASSERT(1 <= port && port <= 4); |
| | | return GetPrivateProfileInt(pszPortSection[port-1], _T("CassetteSnSeed"), 0, m_strFilepath); |
| | | } |
| | | |
| | | void CConfiguration::setPortCassetteSnSeed(int port, int seed) |
| | | { |
| | | ASSERT(1 <= port && port <= 4); |
| | | WritePrivateProfileString(pszPortSection[port - 1], _T("CassetteSnSeed"), |
| | | std::to_string(seed).c_str(), m_strFilepath); |
| | | } |
| | | |
| | |
| | | BOOL isJobMode(); |
| | | void setContinuousTransferCount(int round); |
| | | int getContinuousTransferCount(); |
| | | int getPortCassetteSnSeed(int port); |
| | | void setPortCassetteSnSeed(int port, int seed); |
| | | |
| | | public: |
| | | void setP2RemoteEqReconnectInterval(int second); |
| | |
| | | cassetteType, transferMode, autoChangeEnable); |
| | | m_master.setPortType(i, portEnable, portType, portMode, cassetteType, |
| | | transferMode, autoChangeEnable); |
| | | |
| | | int seed = m_configuration.getPortCassetteSnSeed(i + 1); |
| | | m_master.setPortCassetteSnSeed(i + 1, seed); |
| | | } |
| | | } |
| | | |
| | |
| | | m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_ALARM); |
| | | m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0)); |
| | | m_pMyStatusbar->setRunTimeText("å¯å¨å¤±è´¥."); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)->EnableWindow(TRUE); |
| | | } |
| | | else if (state == SERVO::MASTERSTATE::ATHERERROR) { |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(TRUE); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(TRUE); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE); |
| | | m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_ALARM); |
| | | m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0)); |
| | | m_pMyStatusbar->setRunTimeText(theApp.m_model.getMaster().getLastErrorText().c_str()); |
| | | if (theApp.m_model.getMaster().getLastError() == ER_CODE_AOI_NG) { |
| | | AfxMessageBox(_T("AOIæ£æµå¤±è´¥ï¼è¯·æä½åä»å
¥è§£å³é®é¢ï¼")); |
| | | } |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)->EnableWindow(TRUE); |
| | | } |
| | | else if (state == SERVO::MASTERSTATE::RUNNING || state == SERVO::MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER |
| | | || state == SERVO::MASTERSTATE::RUNNING_BATCH) { |
| | |
| | | |
| | | void CServoDlg::OnMenuHelpAbout() |
| | | { |
| | | theApp.m_model.getMaster().test(); |
| | | CAboutDlg dlgAbout; |
| | | dlgAbout.DoModal(); |
| | | } |