| | |
| | | CEquipment::onProcessData(pProcessData); |
| | | |
| | | |
| | | // 检查数据,当前两片玻璃,一片为G1, 一片为G2, 且pProcessData中的id能匹配G1或G2 |
| | | Lock(); |
| | | CGlass* pGlass2 = getGlassFromSlot(1); |
| | | CGlass* pGlass1 = getGlassFromSlot(2); |
| | | if (pGlass1 == nullptr || pGlass2 == nullptr) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!不满足两片玻璃且分别为G1与G2的条件,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | if (pGlass1->getBuddy() != nullptr) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!玻璃较早前已被绑定,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | if (pGlass1->getType() != MaterialsType::G1 || pGlass2->getType() != MaterialsType::G2) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!两片玻璃未匹配,必须分别为G1和G2类型,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | int CBonder::onProcessStateChanged(PROCESS_STATE state) |
| | | { |
| | | CEquipment::onProcessStateChanged(state); |
| | | |
| | | pGlass1->setBuddy(pGlass2); |
| | | getSlot(0)->setContext(nullptr); |
| | | LOGE("<CBonder-%s>onProcessData,%s和%s已贴合!", m_strName.c_str(), |
| | | pGlass1->getID().c_str(), pGlass2->getID().c_str()); |
| | | Unlock(); |
| | | if (state == PROCESS_STATE::Complete) { |
| | | // 检查数据,当前两片玻璃,一片为G1, 一片为G2, 且pProcessData中的id能匹配G1或G2 |
| | | Lock(); |
| | | CGlass* pGlass2 = getGlassFromSlot(1); |
| | | CGlass* pGlass1 = getGlassFromSlot(2); |
| | | if (pGlass1 == nullptr || pGlass2 == nullptr) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!不满足两片玻璃且分别为G1与G2的条件,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | if (pGlass1->getBuddy() != nullptr) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!玻璃较早前已被绑定,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | |
| | | if (pGlass1->getType() != MaterialsType::G1 || pGlass2->getType() != MaterialsType::G2) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!两片玻璃未匹配,必须分别为G1和G2类型,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | |
| | | pGlass1->setBuddy(pGlass2); |
| | | getSlot(0)->setContext(nullptr); |
| | | LOGE("<CBonder-%s>onProcessStateChanged,%s和%s已贴合!", m_strName.c_str(), |
| | | pGlass1->getID().c_str(), pGlass2->getID().c_str()); |
| | | Unlock(); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | |
| | | virtual void getAttributeVector(CAttributeVector& attrubutes); |
| | | virtual int recvIntent(CPin* pPin, CIntent* pIntent); |
| | | virtual int onProcessData(CProcessData* pProcessData); |
| | | virtual int onProcessStateChanged(PROCESS_STATE state); |
| | | virtual int getIndexerOperationModeBaseValue(); |
| | | |
| | | public: |
| | |
| | | m_pCclink = nullptr; |
| | | m_nBaseAlarmId = 0; |
| | | m_pArm = nullptr; |
| | | m_processState = PROCESS_STATE::Ready; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | |
| | | pStep->setCcLink(m_pCclink); |
| | | m_mapStep[addr] = pStep; |
| | | return 0; |
| | | } |
| | | |
| | | void CEquipment::setProcessState(PROCESS_STATE state) |
| | | { |
| | | m_processState = state; |
| | | onProcessStateChanged(m_processState); |
| | | |
| | | if (m_listener.onProcessStateChanged != nullptr) { |
| | | m_listener.onProcessStateChanged(this, m_processState); |
| | | } |
| | | } |
| | | |
| | | void CEquipment::init() |
| | |
| | | m_bLinkSignal[i][SIGNAL_SEND_ABLE] = isBitOn(pszData, size, index + 3); |
| | | index += 0x40; |
| | | } |
| | | |
| | | if(m_bLinkSignal[0][SIGNAL_SEND_ABLE]) { |
| | | onSendAble(); |
| | | } |
| | | |
| | | // 其它信号及响应 |
| | | index = 0x540; |
| | |
| | | pContext->release(); |
| | | Unlock(); |
| | | |
| | | |
| | | if (m_processState != PROCESS_STATE::Ready) { |
| | | setProcessState(PROCESS_STATE::Ready); |
| | | } |
| | | |
| | | if (m_listener.onDataChanged != nullptr) { |
| | | m_listener.onDataChanged(this, EDCC_FETCHOUT_JOB); |
| | | } |
| | |
| | | pGlass->release(); // tempFetchOut需要调用一次release |
| | | Unlock(); |
| | | |
| | | |
| | | // 如果此玻璃已经贴合,贴合的玻璃也要从加入到列表中 |
| | | /* |
| | | CGlass* pBuddy = pGlass->getBuddy(); |
| | | if (pBuddy != nullptr) { |
| | | Lock(); |
| | | pBuddy->addPath(m_nID, 0); |
| | | if (putSlot % 2 == 0) { |
| | | m_slot[putSlot - 2].setContext(pBuddy); |
| | | } |
| | | else { |
| | | m_slot[putSlot].setContext(pBuddy); |
| | | } |
| | | Unlock(); |
| | | if (m_processState != PROCESS_STATE::Processing) { |
| | | setProcessState(PROCESS_STATE::Processing); |
| | | } |
| | | */ |
| | | |
| | | if (m_listener.onDataChanged != nullptr) { |
| | | m_listener.onDataChanged(this, EDCC_STORED_JOB); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | /* |
| | | * 当从CC-Link检测到设备Send Able为On时调用此函数 |
| | | * 可能会多次重复调用(根据扫描频率), 注意防呆 |
| | | */ |
| | | int CEquipment::onSendAble() |
| | | { |
| | | LOGI("<CEquipment-%s>onSendAble.", m_strName.c_str()); |
| | | |
| | | if (m_processState != PROCESS_STATE::Complete) { |
| | | setProcessState(PROCESS_STATE::Complete); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CEquipment::onProcessStateChanged(PROCESS_STATE state) |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | int CEquipment::getIndexerOperationModeBaseValue() |
| | | { |
| | | return 0; |
| | |
| | | typedef std::function<void(void* pEiuipment, void* pReport)> ONVCREVENTREPORT; |
| | | typedef std::function<BOOL(void* pEiuipment, CJobDataB* pJobDataB)> ONPREFETCHEDOUTJOB; |
| | | typedef std::function<BOOL(void* pEiuipment, CJobDataB* pJobDataB, short& putSlot)> ONPRESTOREDJOB; |
| | | typedef std::function<void(void* pEiuipment, PROCESS_STATE state)> ONPROCESSSTATE; |
| | | typedef struct _EquipmentListener |
| | | { |
| | | ONALIVE onAlive; |
| | |
| | | ONVCREVENTREPORT onVcrEventReport; |
| | | ONPREFETCHEDOUTJOB onPreFethedOutJob; |
| | | ONPRESTOREDJOB onPreStoredJob; |
| | | ONPROCESSSTATE onProcessStateChanged; |
| | | } EquipmentListener; |
| | | |
| | | |
| | |
| | | virtual BOOL onPreStoredJob(int port, CJobDataB* pJobDataB, short& putSlot); |
| | | virtual int onStoredJob(int port, CJobDataB* pJobDataB); |
| | | virtual int onProcessData(CProcessData* pProcessData); |
| | | virtual int onSendAble(); |
| | | virtual int onProcessStateChanged(PROCESS_STATE state); |
| | | virtual int getIndexerOperationModeBaseValue(); |
| | | bool isAlarmStep(SERVO::CStep* pStep); |
| | | bool isVcrEventStep(SERVO::CStep* pStep); |
| | |
| | | int removeJobDataS(int nCassetteSequenceNo, int nJobSequenceNo); |
| | | CJobDataS* getJobDataS(int nCassetteSequenceNo, int nJobSequenceNo); |
| | | BOOL compareJobDataB(CJobDataB* pJobDataB1, CJobDataB* pJobDataB2); |
| | | void setProcessState(PROCESS_STATE state); |
| | | |
| | | protected: |
| | | EquipmentListener m_listener; |
| | |
| | | int m_nBaseAlarmId; |
| | | CRecipesManager m_recipesManager; |
| | | CSlot m_slot[SLOT_MAX]; |
| | | PROCESS_STATE m_processState; |
| | | |
| | | private: |
| | | CEquipment* m_pArm; |
| | |
| | | // 必须要实现的虚函数,在此初始化Slot信息 |
| | | void CLoadPort::initSlots() |
| | | { |
| | | m_slot[0].enable(); |
| | | m_slot[0].setPosition(m_nID); |
| | | m_slot[0].setNo(1); |
| | | m_slot[0].setName("Slot 1"); |
| | | m_slot[1].enable(); |
| | | m_slot[1].setPosition(m_nID); |
| | | m_slot[1].setNo(2); |
| | | m_slot[1].setName("Slot 2"); |
| | | m_slot[2].setPosition(m_nID); |
| | | m_slot[2].enable(); |
| | | m_slot[2].setNo(3); |
| | | m_slot[2].setName("Slot 3"); |
| | | m_slot[3].setPosition(m_nID); |
| | | m_slot[3].enable(); |
| | | m_slot[3].setNo(4); |
| | | m_slot[3].setName("Slot 4"); |
| | | m_slot[4].setPosition(m_nID); |
| | | m_slot[4].enable(); |
| | | m_slot[4].setNo(5); |
| | | m_slot[4].setName("Slot 5"); |
| | | m_slot[5].setPosition(m_nID); |
| | | m_slot[5].enable(); |
| | | m_slot[5].setNo(6); |
| | | m_slot[5].setName("Slot 6"); |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | m_slot[i].enable(); |
| | | m_slot[i].setPosition(m_nID); |
| | | m_slot[i].setNo(i + 1); |
| | | m_slot[i].setName((std::string("Slot") + std::to_string(i+1)).c_str()); |
| | | } |
| | | } |
| | | |
| | | void CLoadPort::initSteps() |
| | |
| | | |
| | | char szBuffer[64]; |
| | | int suffix = startSuffix; |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | for (int i = 0; i < 1; i++) { |
| | | if (!m_slot[i].isEnable()) continue; |
| | | |
| | | CJobDataB jb; |
| | |
| | | ASSERT(pMeasurement); |
| | | |
| | | pEfem->setPort(0, pPort1); |
| | | pEfem->setPort(1, pPort1); |
| | | pEfem->setPort(2, pPort1); |
| | | pEfem->setPort(3, pPort1); |
| | | pEfem->setPort(1, pPort2); |
| | | pEfem->setPort(2, pPort3); |
| | | pEfem->setPort(3, pPort4); |
| | | pEfem->setFliper(pFliper); |
| | | pEfem->setAligner(pAligner); |
| | | pEfem->setArmTray(0, pArmTray1); |
| | |
| | | |
| | | // 读标志位 |
| | | for (auto item : m_listEquipment) { |
| | | if (item->getID() == EQ_ID_Bonder1 || |
| | | item->getID() == EQ_ID_Bonder2) { |
| | | if (item->getID() == EQ_ID_Bonder1 || item->getID() == EQ_ID_Bonder2 |
| | | || item->getID() == EQ_ID_EFEM) { |
| | | const StationIdentifier& station = item->getStation(); |
| | | MemoryBlock& block = item->getReadBitBlock(); |
| | | |
| | |
| | | unlock(); |
| | | } |
| | | }; |
| | | |
| | | listener.onProcessStateChanged = [&](void* pEquipment, PROCESS_STATE state) -> void { |
| | | LOGI("<Master>onProcessStateChanged<%d>", (int)state); |
| | | }; |
| | | pEquipment->setListener(listener); |
| | | pEquipment->setCcLink(&m_cclink); |
| | | m_listEquipment.push_back(pEquipment); |
| | |
| | | else if (nCmd == ID_EQSGRAPHITEM_TEST1) { |
| | | BOOL bTestGenerate = FALSE; |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; |
| | | if (pEquipment->getID() == EQ_ID_LOADPORT1 && !pEquipment->hasGlass()) { |
| | | if (pEquipment->getID() == EQ_ID_LOADPORT4 && !pEquipment->hasGlass()) { |
| | | ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G1, |
| | | "P20250320G1X", 1); |
| | | bTestGenerate = TRUE; |
| | | } |
| | | /* |
| | | else if (pEquipment->getID() == EQ_ID_LOADPORT2 && !pEquipment->hasGlass()) { |
| | | ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G2, |
| | | "P20250320G2X", 1); |
| | | bTestGenerate = TRUE; |
| | | } |
| | | |
| | | */ |
| | | if (!bTestGenerate) { |
| | | SERVO::CRobotTask* pTask = theApp.m_model.getMaster().getActiveRobotTask(); |
| | | if (pTask != nullptr) { |
| | |
| | | ASSERT(m_pEFEM); |
| | | m_state = ROBOT_TASK_STATE::Picking; |
| | | |
| | | m_pEFEM->robotSendMoveToGet(m_robotCmdParam->sequenceNo, |
| | | m_pEFEM->robotSendGet(m_robotCmdParam->sequenceNo, |
| | | m_robotCmdParam[ACTION_PICK].armNo, |
| | | m_robotCmdParam[ACTION_PICK].getPosition, |
| | | m_robotCmdParam[ACTION_PICK].getSlotNo, |
| | |
| | | BOOL armState[2]; |
| | | } ROBOT_MONITORING_DATA, RMDATA; |
| | | |
| | | /* 工艺(加工处理)状态 */ |
| | | enum class PROCESS_STATE { |
| | | Ready = 0, |
| | | Processing, |
| | | Complete, |
| | | Error |
| | | }; |
| | | |
| | | /* EQ Data changed code */ |
| | | #define EDCC_FETCHOUT_JOB 1000 /* ȡƬ */ |