| | |
| | | #include "stdafx.h" |
| | | #include "CEquipment.h" |
| | | #include "ToolUnits.h" |
| | | #include <regex> |
| | | #include "CArm.h" |
| | | |
| | | |
| | | #define CHECK_READ_STEP_SIGNAL(addr, data, size) { \ |
| | |
| | | m_bVCREnable[0] = FALSE; |
| | | m_pCclink = nullptr; |
| | | m_nBaseAlarmId = 0; |
| | | m_pArm = nullptr; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | |
| | | 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) |
| | |
| | | void CEquipment::init() |
| | | { |
| | | initPins(); |
| | | initSteps(); |
| | | for (auto item : m_mapStep) { |
| | | item.second->init(); |
| | | } |
| | |
| | | for (auto item : m_mapStep) { |
| | | item.second->term(); |
| | | } |
| | | } |
| | | |
| | | void CEquipment::initSteps() |
| | | { |
| | | |
| | | } |
| | | |
| | | void CEquipment::setID(int nID) |
| | |
| | | |
| | | // 以下解释和处理数据 |
| | | BOOL bFlag; |
| | | int index = 0x840; |
| | | int index = 0x540; |
| | | |
| | | |
| | | // alive |
| | |
| | | m_bAutoRecipeChange = bFlag; |
| | | } |
| | | |
| | | // AutoRecipeChange |
| | | // VCR Enable |
| | | bFlag = isBitOn(pszData, size, ++index); |
| | | if (!equalBool(m_bVCREnable[0], bFlag)) { |
| | | m_bVCREnable[0] = bFlag; |
| | |
| | | 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); |
| | |
| | | // EQ mode change cmd reply |
| | | CHECK_WRITE_STEP_SIGNAL(STEP_ID_EQMODE_CHANGE_CMD_REPLY, pszData, size); |
| | | |
| | | // EQ Master recipe request cmd reply |
| | | CHECK_WRITE_STEP_SIGNAL(STEP_ID_MASTER_RECIPE_LIST_CMD_REPLY, pszData, size); |
| | | |
| | | // CIM Message Confirm |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_CIM_MSG_CONFIRM_REPORT, pszData, size); |
| | | |
| | |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_SENT_OUT_JOB_DOWNS1, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_SENT_OUT_JOB_DOWNS2, pszData, size); |
| | | |
| | | // Port1 ~ Port4 |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_TYPE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_TYPE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_TYPE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_TYPE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_CASSETTE_TYPE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_CASSETTE_TYPE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_CASSETTE_TYPE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_CASSETTE_TYPE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_TRANSFER_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_TRANSFER_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_TRANSFER_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_TRANSFER_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_ENABLE_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_ENABLE_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_ENABLE_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_ENABLE_MODE_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_TYPE_AUTO_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_TYPE_AUTO_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_TYPE_AUTO_CHANGE, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_TYPE_AUTO_CHANGE, pszData, size); |
| | | |
| | | // CEqCassetteTranserStateStep |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_CASSETTIE_EMPTY, pszData, size); |
| | |
| | | m_listener.onVcrEventReport(this, pVcrEventReport); |
| | | } |
| | | |
| | | // 0426, 先固定返回1(OK) |
| | | pEqVcrEventStep->setReturnCode(1); |
| | | return 1; |
| | | } |
| | | } |
| | |
| | | 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); |
| | | } |
| | | |
| | | bool CEquipment::isPortTypeStep(SERVO::CStep* pStep) |
| | | { |
| | | std::regex pattern("^EQPort\\d+Type$"); |
| | | return std::regex_match(pStep->getName(), pattern); |
| | | } |
| | | |
| | | bool CEquipment::isPortModeStep(SERVO::CStep* pStep) |
| | | { |
| | | std::regex pattern("^EQPort\\d+Mode$"); |
| | | return std::regex_match(pStep->getName(), pattern); |
| | | } |
| | | |
| | | bool CEquipment::isPortCassetteTypeStep(SERVO::CStep* pStep) |
| | | { |
| | | std::regex pattern("^EQPort\\d+CassetteType$"); |
| | | return std::regex_match(pStep->getName(), pattern); |
| | | } |
| | | |
| | | bool CEquipment::isPortTransferModeStep(SERVO::CStep* pStep) |
| | | { |
| | | std::regex pattern("^EQPort\\d+TransferMode$"); |
| | | return std::regex_match(pStep->getName(), pattern); |
| | | } |
| | | |
| | | bool CEquipment::isPortEnableStep(SERVO::CStep* pStep) |
| | | { |
| | | std::regex pattern("^EQPort\\d+Enable$"); |
| | | return std::regex_match(pStep->getName(), pattern); |
| | | } |
| | | |
| | | bool CEquipment::isPortTypeAutoChangeEnableStep(SERVO::CStep* pStep) |
| | | { |
| | | std::regex pattern("^EQPort\\d+CassetteType$"); |
| | | return std::regex_match(pStep->getName(), pattern); |
| | | } |
| | | |
| | | bool CEquipment::isCassetteTransferStateStep(SERVO::CStep* pStep) |
| | | { |
| | | return CToolUnits::startsWith(pStep->getName(), "EQPort") |
| | | && pStep->getName().find("Cassette") != std::string::npos; |
| | | std::regex pattern("^EQPort\\d+Cassette.*"); |
| | | return std::regex_match(pStep->getName(), pattern); |
| | | } |
| | | |
| | | bool CEquipment::isCimMessageConfirmStep(SERVO::CStep* pStep) |
| | |
| | | |
| | | return pStep->setDateTime(year, month, day, hour, minute, second); |
| | | } |
| | | |
| | | int CEquipment::masterRecipeListRequest(short unitNo) |
| | | { |
| | | SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_MASTER_RECIPE_LIST_REQ); |
| | | if (pStep == nullptr) { |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CEquipment-%s>正在请求单元<%d>主配方列表", m_strName.c_str(), unitNo); |
| | | if (m_recipesManager.syncing() != 0) { |
| | | return -2; |
| | | } |
| | | pStep->writeShort(unitNo, [&, unitNo](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>请求单元<%d>主配方列表成功,正在等待数据.", m_strName.c_str(), unitNo); |
| | | } |
| | | else { |
| | | m_recipesManager.syncFailed(); |
| | | LOGI("<CEquipment-%s>请求单元<%d>主配方列表失败,code:%d", m_strName.c_str(), unitNo, code); |
| | | } |
| | | |
| | | return 0; |
| | | }); |
| | | return 0; |
| | | } |
| | | |
| | | int CEquipment::recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo) |
| | | { |
| | | SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_MASTER_RECIPE_LIST_REQ); |
| | | if (pStep == nullptr) { |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CEquipment-%s>正在请求单元<%d>主配方列表", m_strName.c_str(), unitNo); |
| | | if (m_recipesManager.syncing() != 0) { |
| | | return -2; |
| | | } |
| | | pStep->writeShort(unitNo, [&, unitNo](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>请求单元<%d>主配方列表成功,正在等待数据.", m_strName.c_str(), unitNo); |
| | | } |
| | | else { |
| | | m_recipesManager.syncFailed(); |
| | | LOGI("<CEquipment-%s>请求单元<%d>主配方列表失败,code:%d", m_strName.c_str(), unitNo, code); |
| | | } |
| | | |
| | | return 0; |
| | | }); |
| | | return 0; |
| | | } |
| | | |
| | | short CEquipment::decodeRecipeListReport(const char* pszData, size_t size) |
| | | { |
| | | return m_recipesManager.decodeRecipeListReport(pszData, size); |
| | | } |
| | | |
| | | short CEquipment::decodeRecipeParameterReport(const char* pszData, size_t size) |
| | | { |
| | | 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); |
| | | } |
| | | } |