#include "stdafx.h" #include "Common.h" #include "CMaster.h" namespace SERVO { CMaster* g_pMaster = NULL; void CALLBACK MasterTimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime) { if (g_pMaster != NULL) { g_pMaster->onTimer(nTimerid); } } CMaster::CMaster() { m_listener = {nullptr, nullptr, nullptr}; m_bDataModify = FALSE; } CMaster::~CMaster() { for (auto item : m_listEquipment) { delete item; } m_listEquipment.clear(); } void CMaster::setListener(MasterListener listener) { m_listener.onEqAlive = listener.onEqAlive; m_listener.onEqCimStateChanged = listener.onEqCimStateChanged; m_listener.onEqStepEvent = listener.onEqStepEvent; } int CMaster::init() { LOGI("ÕýÔÚ³õʼ»¯..."); StepListener listener; listener.onEvent = [&](void* pStep, int code, void* pData) -> void { TRACE("onEvent<%d, 0x%x>.\n", code, pData); if (m_listener.onEqStepEvent != nullptr) { m_listener.onEqStepEvent((CStep*)pStep, code, pData); } }; // cclink if (m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)) != 0) { LOGE("Á¬½ÓCC-Linkʧ°Ü."); } else { LOGI("Á¬½ÓCC-Link³É¹¦."); BoardVersion version{}; int nRet = m_cclink.GetBoardVersion(version); if (nRet == 0) { LOGI("°æ±¾ÐÅÏ¢£º%s.", version.toString().c_str()); } else { LOGE("»ñÈ¡CC-Link°æ±¾ÐÅϢʧ°Ü."); } BoardStatus status; nRet = m_cclink.GetBoardStatus(status); if (nRet == 0) { LOGI("״̬£º%s.", status.toString().c_str()); } else { LOGE("»ñÈ¡CC-Link״̬ʧ°Ü."); } } // ³õʼ»¯Ìí¼Ó¸÷×ÓÉ豸 addLoadPort(0, listener); addLoadPort(1, listener); addLoadPort(2, listener); addLoadPort(3, listener); addFliper(listener); addVacuumBake(listener); addAligner(listener); addEFEM(listener); addBonder(0, listener); addBonder(1, listener); addBakeCooling(listener); connectEquipments(); // ¶Á»º´æÊý¾Ý readCache(); // ¶¨Ê±Æ÷ g_pMaster = this; SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc); LOGI("³õʼ»¯Íê³É."); return 0; } int CMaster::term() { LOGI("ÕýÔÚ½áÊø³ÌÐò."); for (auto item : m_listEquipment) { item->term(); } saveCache(); return 0; } int CMaster::addToEquipmentList(CEquipment* pEquipment) { EquipmentListener listener; listener.onAlive = [&](void* pEquipment, BOOL bAlive) -> void { CEquipment* p = (CEquipment*)pEquipment; if (m_listener.onEqAlive != nullptr) { m_listener.onEqAlive(this, p, bAlive); } }; listener.onCimStateChanged = [&](void* pEquipment, BOOL bOn) -> void { CEquipment* p = (CEquipment*)pEquipment; if (m_listener.onEqCimStateChanged != nullptr) { m_listener.onEqCimStateChanged(this, p, bOn); } }; listener.onDataChanged = [&](void* pEquipment, int code) -> void { m_bDataModify = TRUE; }; pEquipment->setListener(listener); pEquipment->setCcLink(&m_cclink); m_listEquipment.push_back(pEquipment); return 0; } std::list& CMaster::getEquipmentList() { return m_listEquipment; } CEquipment* CMaster::getEquipment(int id) { for (auto item : m_listEquipment) { if (item->getID() == id) return item; } return nullptr; } /* Ìí¼ÓLoadPort1 * index -- 0~3 */ int CMaster::addLoadPort(int index, StepListener& listener) { ASSERT(index == 0 || index == 1 || index == 2 || index == 3); char szName[64]; sprintf_s(szName, 64, "LoadPort %d", index + 1); CLoadPort* pEquipment = new CLoadPort(); pEquipment->setID(EQ_ID_LOADPORT1 + index); pEquipment->setName(szName); pEquipment->setDescription(szName); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°%s¡±.", pEquipment->getName().c_str()); return 0; } int CMaster::addFliper(StepListener& listener) { CFliper* pEquipment = new CFliper(); pEquipment->setID(EQ_ID_FLIPER); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("Fliper"); pEquipment->setDescription("Fliper."); pEquipment->setReadBitBlock(0x4000, 0x45ff); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°Fliper¡±."); return 0; } int CMaster::addVacuumBake(StepListener& listener) { CVacuumBake* pEquipment = new CVacuumBake(); pEquipment->setID(EQ_ID_VACUUMBAKE); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("VacuumBake"); pEquipment->setDescription("VacuumBake."); pEquipment->setReadBitBlock(0x4000, 0x45ff); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°VacuumBake¡±."); return 0; } int CMaster::addAligner(StepListener& listener) { CAligner* pEquipment = new CAligner(); pEquipment->setID(EQ_ID_ALIGNER); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("Aligner"); pEquipment->setDescription("Aligner."); pEquipment->setReadBitBlock(0x4000, 0x45ff); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°Aligner¡±."); return 0; } int CMaster::addEFEM(StepListener& listener) { CEFEM* pEquipment = new CEFEM(); pEquipment->setID(EQ_ID_EFEM); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("EFEM(ROBOT)"); pEquipment->setDescription("EFEM(ROBOT)."); pEquipment->setReadBitBlock(0x4000, 0x45ff); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); // Ìí¼Ó step { CEqModeStep* pStep = new CEqModeStep(); pStep->setName(STEP_MODE); pStep->setListener(listener); pStep->setWriteSignalDev(0x30); pStep->setModeDev(0x4a8c); if (pEquipment->addStep(0x360, pStep) != 0) { delete pStep; } } { CEqStatusStep* pStep = new CEqStatusStep(); pStep->setName(STEP_STATUS); pStep->setListener(listener); pStep->setWriteSignalDev(0x31); pStep->setStatusDev(0x4a68); if (pEquipment->addStep(0x361, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK1); pStep->setListener(listener); pStep->setWriteSignalDev(0x32); pStep->setAlarmDev(0x4c1d); if (pEquipment->addStep(0x362, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK2); pStep->setListener(listener); pStep->setWriteSignalDev(0x33); pStep->setAlarmDev(0x4c4a); if (pEquipment->addStep(0x363, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK3); pStep->setListener(listener); pStep->setWriteSignalDev(0x34); pStep->setAlarmDev(0x4c77); if (pEquipment->addStep(0x364, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK4); pStep->setListener(listener); pStep->setWriteSignalDev(0x35); pStep->setAlarmDev(0x4ca4); if (pEquipment->addStep(0x365, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK5); pStep->setListener(listener); pStep->setWriteSignalDev(0x36); pStep->setAlarmDev(0x4cd1); if (pEquipment->addStep(0x366, pStep) != 0) { delete pStep; } } { CEqProcessStep* pStep = new CEqProcessStep(); pStep->setName(STEP_PROCESS); pStep->setListener(listener); pStep->setWriteSignalDev(0x37); pStep->setProcessDev(0x5864); if (pEquipment->addStep(0x367, pStep) != 0) { delete pStep; } } { CEqCimModeChangeStep* pStep = new CEqCimModeChangeStep(); pStep->setName(STEP_CIM_MODE_CHANGE); pStep->setListener(listener); pStep->setWriteSignalDev(0x50); pStep->setCimModeDev(0x15); if (pEquipment->addStep(0x350, pStep) != 0) { delete pStep; } } { CEqCimMessageCmdStep* pStep = new CEqCimMessageCmdStep(); pStep->setName(STEP_CIM_MESSAGE_CMD); pStep->setListener(listener); pStep->setWriteSignalDev(0x51); pStep->setCimMessageDev(0x0); if (pEquipment->addStep(0x351, pStep) != 0) { delete pStep; } } { CEqCimMessageClearStep* pStep = new CEqCimMessageClearStep(); pStep->setName(STEP_CIM_MESSAGE_CLEAR); pStep->setListener(listener); pStep->setWriteSignalDev(0x52); pStep->setClearCimMessageDev(0x13); if (pEquipment->addStep(0x352, pStep) != 0) { delete pStep; } } { CEqDateTimeSetCmdStep* pStep = new CEqDateTimeSetCmdStep(); pStep->setName(STEP_DATETIME_SET_CMD); pStep->setListener(listener); pStep->setWriteSignalDev(0x53); pStep->setDateTimeDev(0x16); if (pEquipment->addStep(0x353, pStep) != 0) { delete pStep; } } { CEqVCREnableStep* pStep = new CEqVCREnableStep(); pStep->setName(STEP_EQ_VCR_ENABLE); pStep->setListener(listener); pStep->setWriteSignalDev(0x54); pStep->setEqVCRModeDev(0x1F); if (pEquipment->addStep(0x354, pStep) != 0) { delete pStep; } } { CEqModeChangeStep* pStep = new CEqModeChangeStep(); pStep->setName(STEP_EQ_MODE_CHANGE); pStep->setListener(listener); pStep->setWriteSignalDev(0x55); pStep->setEqModeDev(0x1E); if (pEquipment->addStep(0x355, pStep) != 0) { delete pStep; } } pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°EFEM(ROBOT)¡±."); return 0; } /* Ìí¼Óbonder1 »ò bonder2 * index -- 0, bonder1 * index -- 1, bonder2 */ int CMaster::addBonder(int index, StepListener& listener) { ASSERT(index == 0 || index == 1); CBonder* pEquipment = new CBonder(); pEquipment->setID(EQ_ID_Bonder1 + index); pEquipment->setName(index == 0 ? "Bonder 1" : "Bonder 2"); pEquipment->setDescription(index == 0 ? "Bonder 1." : "Bonder 2."); pEquipment->setStation(1, index == 0 ? 3 : 4); pEquipment->setReadBitBlock(index == 0 ? 0x4600 : 0x4c00, index == 0 ? 0x4c00 : 0x5200); addToEquipmentList(pEquipment); // Ìí¼Ó step { CEqModeStep* pStep = new CEqModeStep(); pStep->setName(STEP_MODE); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x330 : 0x630); pStep->setModeDev(index == 0 ? 0x6a8c : 0x848c); if (pEquipment->addStep(0x360, pStep) != 0) { delete pStep; } } { CEqStatusStep* pStep = new CEqStatusStep(); pStep->setName(STEP_STATUS); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x331 : 0x631); pStep->setStatusDev(index == 0 ? 0x6a68 : 0x8a68); if (pEquipment->addStep(0x361, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK1); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x332 : 0x632); pStep->setAlarmDev(index == 0 ? 0x6c1d : 0x8c1d); if (pEquipment->addStep(0x362, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK2); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x333 : 0x633); pStep->setAlarmDev(index == 0 ? 0x6c4a : 0x8c4a); if (pEquipment->addStep(0x363, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK3); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x334 : 0x634); pStep->setAlarmDev(index == 0 ? 0x6c77 : 0x8c77); if (pEquipment->addStep(0x364, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK4); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x335 : 0x635); pStep->setAlarmDev(index == 0 ? 0x6ca4 : 0x8ca4); if (pEquipment->addStep(0x365, pStep) != 0) { delete pStep; } } { CEqAlarmStep* pStep = new CEqAlarmStep(); pStep->setName(STEP_ALARM_BLOCK5); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x336 : 0x636); pStep->setAlarmDev(index == 0 ? 0x6cd1 : 0x8cd1); if (pEquipment->addStep(0x366, pStep) != 0) { delete pStep; } } { CEqProcessStep* pStep = new CEqProcessStep(); pStep->setName(STEP_PROCESS); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x337 : 0x637); pStep->setProcessDev(index == 0 ? 0x7864 : 0x9864); if (pEquipment->addStep(0x367, pStep) != 0) { delete pStep; } } { CEqCimModeChangeStep* pStep = new CEqCimModeChangeStep(); pStep->setName(STEP_CIM_MODE_CHANGE); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x350 : 0x650); pStep->setCimModeDev(index == 0 ? 0x965 : 0x12b5); if (pEquipment->addStep(0x350, pStep) != 0) { delete pStep; } } { CEqCimMessageCmdStep* pStep = new CEqCimMessageCmdStep(); pStep->setName(STEP_CIM_MESSAGE_CMD); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x351 : 0x651); pStep->setCimMessageDev(index == 0 ? 0x950 : 0x12a0); if (pEquipment->addStep(0x351, pStep) != 0) { delete pStep; } } { CEqCimMessageClearStep* pStep = new CEqCimMessageClearStep(); pStep->setName(STEP_CIM_MESSAGE_CLEAR); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x352 : 0x652); pStep->setClearCimMessageDev(index == 0 ? 0x963 : 0x12b3); if (pEquipment->addStep(0x352, pStep) != 0) { delete pStep; } } { CEqDateTimeSetCmdStep* pStep = new CEqDateTimeSetCmdStep(); pStep->setName(STEP_DATETIME_SET_CMD); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x353 : 0x653); pStep->setDateTimeDev(index == 0 ? 0x966 : 0x12b6); if (pEquipment->addStep(0x353, pStep) != 0) { delete pStep; } } { CEqModeChangeStep* pStep = new CEqModeChangeStep(); pStep->setName(STEP_EQ_MODE_CHANGE); pStep->setListener(listener); pStep->setWriteSignalDev(index == 0 ? 0x355 : 0x655); pStep->setEqModeDev(index == 0 ? 0x96E : 0x12be); if (pEquipment->addStep(0x355, pStep) != 0) { delete pStep; } } pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°%s¡±.", pEquipment->getName().c_str()); return 0; } int CMaster::addBakeCooling(StepListener& listener) { CBakeCooling* pEquipment = new CBakeCooling(); pEquipment->setID(EQ_ID_BAKE_COOLING); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("BakeCooling"); pEquipment->setDescription("BakeCooling."); pEquipment->setReadBitBlock(0x4000, 0x45ff); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°Aligner¡±."); return 0; } void CMaster::onTimer(UINT nTimerid) { for (auto item : m_listEquipment) { item->onTimer(nTimerid); } // °´Ò»¶¨ÆµÂÊɨÃèLBÊý¾Ý static int i = 0; i++; if (i % (4 * 1) == 0) { for (auto item : m_listEquipment) { const StationIdentifier& station = item->getStation(); MemoryBlock& block = item->getReadBitBlock(); int nRet = m_cclink.ReadData2(station, (DeviceType)block.type, block.start, block.size, block.buffer); if (0 == nRet) { item->onReceiveLBData(block.buffer, block.size); } } } // ×Ô¶¯±£´æ»º´æ if (i % (4 * 2) == 0) { if (m_bDataModify) { saveCacheAndBackups(); m_bDataModify = FALSE; } } } void CMaster::connectEquipments() { int nRet; CLoadPort* pLoadPort1 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1); CLoadPort* pLoadPort2 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT2); CLoadPort* pLoadPort3 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT3); CLoadPort* pLoadPort4 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT4); CFliper* pFliper = (CFliper*)getEquipment(EQ_ID_FLIPER); CVacuumBake* pVacuumBake = (CVacuumBake*)getEquipment(EQ_ID_VACUUMBAKE); CAligner* pAligner = (CAligner*)getEquipment(EQ_ID_ALIGNER); CBonder* pBonder1 = (CBonder*)getEquipment(EQ_ID_Bonder1); CBonder* pBonder2 = (CBonder*)getEquipment(EQ_ID_Bonder2); CBakeCooling* pBakeCooling = (CBakeCooling*)getEquipment(EQ_ID_BAKE_COOLING); nRet = pLoadPort1->getPin("Out1")->connectPin(pFliper->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-Fliperʧ°Ü"); } nRet = pLoadPort2->getPin("Out1")->connectPin(pFliper->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-Fliperʧ°Ü"); } nRet = pLoadPort1->getPin("Out2")->connectPin(pVacuumBake->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-VacuumBakeʧ°Ü"); } nRet = pLoadPort2->getPin("Out2")->connectPin(pVacuumBake->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-VacuumBakeʧ°Ü"); } nRet = pFliper->getPin("Out")->connectPin(pAligner->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓFliper-Alignerʧ°Ü"); } nRet = pVacuumBake->getPin("Out")->connectPin(pAligner->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓVacuumBake-Alignerʧ°Ü"); } nRet = pAligner->getPin("Out1")->connectPin(pBonder1->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓAligner-Bondere1ʧ°Ü"); } nRet = pAligner->getPin("Out2")->connectPin(pBonder2->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓAligner-Bondere2ʧ°Ü"); } nRet = pBonder1->getPin("Out")->connectPin(pBakeCooling->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓBonder1-BakeCoolingʧ°Ü"); } nRet = pBonder2->getPin("Out")->connectPin(pBakeCooling->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓBonder2-BakeCoolingʧ°Ü"); } nRet = pBakeCooling->getPin("Out1")->connectPin(pLoadPort3->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓBakeCooling-LoadPort3ʧ°Ü"); } nRet = pBakeCooling->getPin("Out2")->connectPin(pLoadPort4->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓBakeCooling-LoadPort4ʧ°Ü"); } } int CMaster::saveCache() { CFile file; if (!file.Open(m_strFilepath.c_str(), CFile::modeCreate | CFile::modeWrite)) { return -1; } CArchive ar(&file, CArchive::store); serialize(ar); ar.Close(); file.Close(); return 0; } int CMaster::saveCacheAndBackups() { saveCache(); // ´´½¨±¸·ÝĿ¼ CString strNewFile; CString strFileDir = m_strFilepath.c_str(); int index = strFileDir.ReverseFind('\\'); ASSERT(index > 0); strFileDir = strFileDir.Left(index); strFileDir = strFileDir + _T("Backups"); ::CreateDirectory(strFileDir, nullptr); CTime time = CTime::GetCurrentTime(); strNewFile.Format(_T("%s//Master_%d_%02d_%02d_%02d_%02d_%02d.dat"), (LPTSTR)(LPCTSTR)strFileDir, time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond()); ::CopyFile(m_strFilepath.c_str(), strNewFile, FALSE); return 0; } void CMaster::setCacheFilepath(const char* pszFilepath) { m_strFilepath = pszFilepath; } int CMaster::readCache() { CFile file; if (!file.Open(m_strFilepath.c_str(), CFile::modeRead)) { return -1; } CArchive ar(&file, CArchive::load); serialize(ar); ar.Close(); file.Close(); return 0; } void CMaster::serialize(CArchive& ar) { for (auto item : m_listEquipment) { item->serialize(ar); } } }