| | |
| | | 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) |
| | |
| | | { |
| | | 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); |
| | | |
| | | } |
| | | |
| | |
| | | { |
| | | 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); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | 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; |
| | | } |
| | | |
| | |
| | | |
| | | 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); |