From c8173fa96f226ff88412d07955fb340de4681ffc Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期四, 06 三月 2025 11:21:34 +0800
Subject: [PATCH] 1.实现 CIM model change指令下发到机器。与之前的从CC link读数据逻辑稍有不同,下发指令为写数据,因此,从原CStep派生两个类,CReadStep(用于读数据),CWriteStep(用于写数据),然后根据使用场景选择合适的基数做应用层逻辑。已完成待测试验证

---
 SourceCode/Bond/Servo/CEqStatusStep.h          |    4 
 SourceCode/Bond/Servo/CReadStep.cpp            |  187 +++++++++++++
 SourceCode/Bond/Servo/Servo.vcxproj            |    6 
 SourceCode/Bond/Servo/CWriteStep.h             |   38 ++
 SourceCode/Bond/Servo/CWriteStep.cpp           |  197 ++++++++++++++
 SourceCode/Bond/Servo/CEqAlarmStep.cpp         |   10 
 SourceCode/Bond/Servo/CReadStep.h              |   35 ++
 SourceCode/Bond/Servo/CEqCimModeChangeStep.h   |   23 +
 SourceCode/Bond/Servo/CEqModeStep.h            |    4 
 SourceCode/Bond/Servo/CEqProcessStep.cpp       |   10 
 SourceCode/Bond/Servo/CPanelAttributes.cpp     |   23 +
 SourceCode/Bond/Servo/CEqModeStep.cpp          |   10 
 SourceCode/Bond/Servo/Servo.vcxproj.filters    |    6 
 SourceCode/Bond/Servo/CEqAlarmStep.h           |    4 
 SourceCode/Bond/Servo/CStep.h                  |   18 -
 SourceCode/Bond/Servo/CEqStatusStep.cpp        |   10 
 SourceCode/Bond/Servo/CEquipment.cpp           |    9 
 SourceCode/Bond/Servo/CAttributeVector.cpp     |    5 
 SourceCode/Bond/Servo/CMaster.cpp              |   11 
 SourceCode/Bond/Servo/CEqProcessStep.h         |    4 
 SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp |   45 +++
 SourceCode/Bond/Servo/CEquipment.h             |    1 
 SourceCode/Bond/Servo/CStep.cpp                |  157 -----------
 SourceCode/Bond/Servo/Common.h                 |   19 
 24 files changed, 616 insertions(+), 220 deletions(-)

diff --git a/SourceCode/Bond/Servo/CAttributeVector.cpp b/SourceCode/Bond/Servo/CAttributeVector.cpp
index bb673f7..6d9213a 100644
--- a/SourceCode/Bond/Servo/CAttributeVector.cpp
+++ b/SourceCode/Bond/Servo/CAttributeVector.cpp
@@ -10,7 +10,10 @@
 
 	CAttributeVector::~CAttributeVector()
 	{
-
+		for (auto item : m_attributes) {
+			delete item;
+		}
+		m_attributes.clear();
 	}
 
 	void CAttributeVector::addAttribute(CAttribute* pAttribute)
diff --git a/SourceCode/Bond/Servo/CEqAlarmStep.cpp b/SourceCode/Bond/Servo/CEqAlarmStep.cpp
index 1aa6dac..cddef97 100644
--- a/SourceCode/Bond/Servo/CEqAlarmStep.cpp
+++ b/SourceCode/Bond/Servo/CEqAlarmStep.cpp
@@ -5,7 +5,7 @@
 
 
 namespace SERVO {
-	CEqAlarmStep::CEqAlarmStep() : CStep()
+	CEqAlarmStep::CEqAlarmStep() : CReadStep()
 	{
 		m_nAlarmDev = 0;
 		m_nAlarmState = 0;
@@ -22,7 +22,7 @@
 
 	void CEqAlarmStep::getAttributeVector(CAttributeVector& attrubutes)
 	{
-		CStep::getAttributeVector(attrubutes);
+		CReadStep::getAttributeVector(attrubutes);
 
 		attrubutes.addAttribute(new CAttribute("Alarm State",
 			std::to_string(m_nAlarmState).c_str(), ""));
@@ -42,7 +42,7 @@
 
 	int CEqAlarmStep::onReadData()
 	{
-		CStep::onReadData();
+		CReadStep::onReadData();
 
 		char szBuffer[64];
 		int nRet = m_pCclink->ReadData2(m_station, DeviceType::W,
@@ -66,7 +66,7 @@
 
 	int CEqAlarmStep::onComplete()
 	{
-		CStep::onComplete();
+		CReadStep::onComplete();
 		LOGI("<CEqAlarmStep> onComplete.");
 
 		return 0;
@@ -74,7 +74,7 @@
 
 	int CEqAlarmStep::onTimeout()
 	{
-		CStep::onTimeout();
+		CReadStep::onTimeout();
 		LOGI("<CEqAlarmStep> onTimeout.");
 
 		return 0;
diff --git a/SourceCode/Bond/Servo/CEqAlarmStep.h b/SourceCode/Bond/Servo/CEqAlarmStep.h
index 5157215..7c33958 100644
--- a/SourceCode/Bond/Servo/CEqAlarmStep.h
+++ b/SourceCode/Bond/Servo/CEqAlarmStep.h
@@ -1,9 +1,9 @@
 #pragma once
-#include "CStep.h"
+#include "CReadStep.h"
 
 
 namespace SERVO {
-	class CEqAlarmStep : public CStep
+	class CEqAlarmStep : public CReadStep
 	{
 	public:
 		CEqAlarmStep();
diff --git a/SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp b/SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp
new file mode 100644
index 0000000..9e2d40c
--- /dev/null
+++ b/SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp
@@ -0,0 +1,45 @@
+#include "stdafx.h"
+#include "CEqCimModeChangeStep.h"
+
+
+namespace SERVO {
+	CEqCimModeChangeStep::CEqCimModeChangeStep() : CWriteStep()
+	{
+		m_nCimModeDev = 0;
+	}
+
+	CEqCimModeChangeStep::~CEqCimModeChangeStep()
+	{
+
+	}
+
+	void CEqCimModeChangeStep::setCimModeDev(int nDev)
+	{
+		m_nCimModeDev = nDev;
+	}
+
+	int CEqCimModeChangeStep::cimOn()
+	{
+		short mode = 1;
+		return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
+	}
+
+	int CEqCimModeChangeStep::cimOff()
+	{
+		short mode = 2;
+		return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
+	}
+
+	int CEqCimModeChangeStep::setCimMode(short mode)
+	{
+		return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
+	}
+
+	void CEqCimModeChangeStep::getAttributeVector(CAttributeVector& attrubutes)
+	{
+		CWriteStep::getAttributeVector(attrubutes);
+
+		attrubutes.addAttribute(new CAttribute("Cim Mode Dev",
+			std::to_string(m_nCimModeDev).c_str(), ""));
+	}
+}
diff --git a/SourceCode/Bond/Servo/CEqCimModeChangeStep.h b/SourceCode/Bond/Servo/CEqCimModeChangeStep.h
new file mode 100644
index 0000000..22afc6a
--- /dev/null
+++ b/SourceCode/Bond/Servo/CEqCimModeChangeStep.h
@@ -0,0 +1,23 @@
+#pragma once
+#include "CWriteStep.h"
+
+
+namespace SERVO {
+	class CEqCimModeChangeStep : public CWriteStep
+	{
+	public:
+		CEqCimModeChangeStep();
+		~CEqCimModeChangeStep();
+
+	public:
+		void setCimModeDev(int nDev);
+		int cimOn();
+		int cimOff();
+		int setCimMode(short mode);
+		void getAttributeVector(CAttributeVector& attrubutes);
+
+	private:
+		int m_nCimModeDev;
+	};
+}
+
diff --git a/SourceCode/Bond/Servo/CEqModeStep.cpp b/SourceCode/Bond/Servo/CEqModeStep.cpp
index 70787df..3b416b2 100644
--- a/SourceCode/Bond/Servo/CEqModeStep.cpp
+++ b/SourceCode/Bond/Servo/CEqModeStep.cpp
@@ -4,7 +4,7 @@
 
 
 namespace SERVO {
-	CEqModeStep::CEqModeStep() : CStep()
+	CEqModeStep::CEqModeStep() : CReadStep()
 	{
 		m_nModeDev = 0;
 		m_nMode = 0;
@@ -17,7 +17,7 @@
 
 	void CEqModeStep::getAttributeVector(CAttributeVector& attrubutes)
 	{
-		CStep::getAttributeVector(attrubutes);
+		CReadStep::getAttributeVector(attrubutes);
 
 		std::string strTemp;
 		attrubutes.addAttribute(new CAttribute("Mode",
@@ -28,7 +28,7 @@
 
 	int CEqModeStep::onReadData()
 	{
-		CStep::onReadData();
+		CReadStep::onReadData();
 
 		DWordContainer dc;
 		if (0 != m_pCclink->ReadDWordData(m_station, DeviceType::W, m_nModeDev, 1, dc)) {
@@ -48,7 +48,7 @@
 
 	int CEqModeStep::onComplete()
 	{
-		CStep::onComplete();
+		CReadStep::onComplete();
 		LOGI("<CEqModeStep> onComplete.");
 
 		return 0;
@@ -56,7 +56,7 @@
 
 	int CEqModeStep::onTimeout()
 	{
-		CStep::onTimeout();
+		CReadStep::onTimeout();
 		LOGI("<CEqModeStep> onTimeout.");
 
 		return 0;
diff --git a/SourceCode/Bond/Servo/CEqModeStep.h b/SourceCode/Bond/Servo/CEqModeStep.h
index ff68005..1bc611d 100644
--- a/SourceCode/Bond/Servo/CEqModeStep.h
+++ b/SourceCode/Bond/Servo/CEqModeStep.h
@@ -1,9 +1,9 @@
 #pragma once
-#include "CStep.h"
+#include "CReadStep.h"
 
 
 namespace SERVO {
-	class CEqModeStep : public CStep
+	class CEqModeStep : public CReadStep
 	{
 	public:
 		CEqModeStep();
diff --git a/SourceCode/Bond/Servo/CEqProcessStep.cpp b/SourceCode/Bond/Servo/CEqProcessStep.cpp
index e64e92b..f566e43 100644
--- a/SourceCode/Bond/Servo/CEqProcessStep.cpp
+++ b/SourceCode/Bond/Servo/CEqProcessStep.cpp
@@ -6,7 +6,7 @@
 
 
 namespace SERVO {
-	CEqProcessStep::CEqProcessStep()
+	CEqProcessStep::CEqProcessStep() : CReadStep()
 	{
 		m_nProcessDev = 0;
 		m_nTotalParameter = 0;
@@ -19,7 +19,7 @@
 
 	void CEqProcessStep::getAttributeVector(CAttributeVector& attrubutes)
 	{
-		CStep::getAttributeVector(attrubutes);
+		CReadStep::getAttributeVector(attrubutes);
 
 		attrubutes.addAttribute(new CAttribute("Glass ID",
 			m_strGlassId.c_str(), ""));
@@ -46,7 +46,7 @@
 #define PROGRESS_BUF_SIZE		(1024 + 64)
 	int CEqProcessStep::onReadData()
 	{
-		CStep::onReadData();
+		CReadStep::onReadData();
 
 		// W1864 ~ W1A74, 529个word, 1058 bytes
 		char szBuffer[PROGRESS_BUF_SIZE];
@@ -107,7 +107,7 @@
 
 	int CEqProcessStep::onComplete()
 	{
-		CStep::onComplete();
+		CReadStep::onComplete();
 		LOGI("<CEqProcessStep> onComplete.");
 
 		return 0;
@@ -115,7 +115,7 @@
 
 	int CEqProcessStep::onTimeout()
 	{
-		CStep::onTimeout();
+		CReadStep::onTimeout();
 		LOGI("<CEqProcessStep> onTimeout.");
 
 		return 0;
diff --git a/SourceCode/Bond/Servo/CEqProcessStep.h b/SourceCode/Bond/Servo/CEqProcessStep.h
index ac195cf..d16a5a0 100644
--- a/SourceCode/Bond/Servo/CEqProcessStep.h
+++ b/SourceCode/Bond/Servo/CEqProcessStep.h
@@ -1,10 +1,10 @@
 #pragma once
-#include "CStep.h"
+#include "CReadStep.h"
 #include <list>
 
 
 namespace SERVO {
-	class CEqProcessStep : public CStep
+	class CEqProcessStep : public CReadStep
 	{
 	public:
 		CEqProcessStep();
diff --git a/SourceCode/Bond/Servo/CEqStatusStep.cpp b/SourceCode/Bond/Servo/CEqStatusStep.cpp
index 697e384..b525e6f 100644
--- a/SourceCode/Bond/Servo/CEqStatusStep.cpp
+++ b/SourceCode/Bond/Servo/CEqStatusStep.cpp
@@ -5,7 +5,7 @@
 
 
 namespace SERVO {
-	CEqStatusStep::CEqStatusStep() : CStep()
+	CEqStatusStep::CEqStatusStep() : CReadStep()
 	{
 		m_nStatusDev = 0;
 		for (int i = 0; i < STATUS_MAX; i++) {
@@ -23,7 +23,7 @@
 
 	void CEqStatusStep::getAttributeVector(CAttributeVector& attrubutes)
 	{
-		CStep::getAttributeVector(attrubutes);
+		CReadStep::getAttributeVector(attrubutes);
 
 		char szName[256];
 		for (int i = 0; i < STATUS_MAX; i++) {
@@ -49,7 +49,7 @@
 	}
 	int CEqStatusStep::onReadData()
 	{
-		CStep::onReadData();
+		CReadStep::onReadData();
 
 		char szBuffer[64];
 		int nRet = m_pCclink->ReadData2(m_station, DeviceType::W,
@@ -82,7 +82,7 @@
 
 	int CEqStatusStep::onComplete()
 	{
-		CStep::onComplete();
+		CReadStep::onComplete();
 		LOGI("<CEqStatusStep> onComplete.");
 
 		return 0;
@@ -90,7 +90,7 @@
 
 	int CEqStatusStep::onTimeout()
 	{
-		CStep::onTimeout();
+		CReadStep::onTimeout();
 		LOGI("<CEqStatusStep> onTimeout.");
 
 		return 0;
diff --git a/SourceCode/Bond/Servo/CEqStatusStep.h b/SourceCode/Bond/Servo/CEqStatusStep.h
index dd4e47f..f99e813 100644
--- a/SourceCode/Bond/Servo/CEqStatusStep.h
+++ b/SourceCode/Bond/Servo/CEqStatusStep.h
@@ -1,12 +1,12 @@
 #pragma once
-#include "CStep.h"
+#include "CReadStep.h"
 
 
 namespace SERVO {
 #define UNIT_MAX		6
 #define STATUS_MAX		(UNIT_MAX + 1)
 
-	class CEqStatusStep : public CStep
+	class CEqStatusStep : public CReadStep
 	{
 	public:
 		CEqStatusStep();
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index afd0c0e..3fa85bb 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -267,9 +267,16 @@
 			bFlag = isBitOn(pszData, size, index);
 			pStep = getStep(index);
 			if (pStep != nullptr) {
-				pStep->onSignal(bFlag);
+				((CReadStep*)pStep)->onReadSignal(bFlag);
 			}
 		}
+
+		index = 0x350;
+		bFlag = isBitOn(pszData, size, index);
+		pStep = getStep(index);
+		if (pStep != nullptr) {
+			((CWriteStep*)pStep)->onRecvSignal(bFlag);
+		}
 	}
 
 	BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index)
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index 978dbd2..c13e71e 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -5,6 +5,7 @@
 #include "CEqStatusStep.h"
 #include "CEqAlarmStep.h"
 #include "CEqProcessStep.h"
+#include "CEqCimModeChangeStep.h"
 #include <map>
 
 
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index d0bd080..7040c70 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -234,6 +234,17 @@
 				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;
+			}
+		}
+
 
 		pEquipment->init();
 		LOGE("已添加“EFEM(ROBOT)”.");
diff --git a/SourceCode/Bond/Servo/CPanelAttributes.cpp b/SourceCode/Bond/Servo/CPanelAttributes.cpp
index e36312d..75241c1 100644
--- a/SourceCode/Bond/Servo/CPanelAttributes.cpp
+++ b/SourceCode/Bond/Servo/CPanelAttributes.cpp
@@ -62,11 +62,12 @@
 	unsigned int nSize = attrubutes.size();
 	for (unsigned int i = 0; i < nSize; i++) {
 		SERVO::CAttribute* pAttribute = attrubutes.getAttribute(i);
-
-		m_gridCtrl.AddProperty(new CMFCPropertyGridProperty(
+		CMFCPropertyGridProperty* pProperty = new CMFCPropertyGridProperty(
 			pAttribute->getName().c_str(),
 			pAttribute->getValue().c_str(),
-			pAttribute->getDescription().c_str()));
+			pAttribute->getDescription().c_str());
+		pProperty->AllowEdit(TRUE);
+		m_gridCtrl.AddProperty(pProperty);
 	}
 }
 
@@ -146,16 +147,20 @@
 	pItem = GetDlgItem(IDC_LINE1);
 	pItem->MoveWindow(rcClient.right - 3, 0, 3, rcClient.Height());
 
+	int x2 = rcClient.right - 6;
 	int y = 3;
-	pItem = GetDlgItem(IDC_LABEL_TITLE);
-	pItem->GetWindowRect(&rcItem);
-	pItem->MoveWindow(5, y, rcClient.Width() - 8, rcItem.Height());
-
 	pItem = GetDlgItem(IDC_BUTTON_CLOSE);
 	pItem->GetWindowRect(&rcItem);
-	pItem->MoveWindow(rcClient.right - 6 - rcItem.Width(), y, rcItem.Width(), rcItem.Height());
+	pItem->MoveWindow(x2 - rcItem.Width(), y, rcItem.Width(), rcItem.Height());
+	x2 -= rcItem.Width();
+	x2 -= 3;
+
+	pItem = GetDlgItem(IDC_LABEL_TITLE);
+	pItem->GetWindowRect(&rcItem);
+	pItem->MoveWindow(5, y, x2 - 5, rcItem.Height());
 	y += rcItem.Height();
-	y += 3;
+	y += 8;
+
 
 	GetDlgItem(IDC_MFCPROPERTYGRID1)->MoveWindow(5, y, rcClient.Width() - 13, rcClient.Height() - 3 - y);
 }
diff --git a/SourceCode/Bond/Servo/CReadStep.cpp b/SourceCode/Bond/Servo/CReadStep.cpp
new file mode 100644
index 0000000..0a2474f
--- /dev/null
+++ b/SourceCode/Bond/Servo/CReadStep.cpp
@@ -0,0 +1,187 @@
+#include "stdafx.h"
+#include "CReadStep.h"
+#include "Common.h"
+
+
+namespace SERVO {
+#define TIMEOUT			15
+
+	unsigned __stdcall ReadStepWorkThreadFunction(LPVOID lpParam)
+	{
+		CReadStep* pStep = (CReadStep*)lpParam;
+		return pStep->WorkingProc();
+	}
+
+	CReadStep::CReadStep() : CStep()
+	{
+		m_nWordThreadAddr = 0;
+		m_hWorkStop = nullptr;
+		m_hWorkThreadHandle = nullptr;
+		m_hReadSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		m_hReadSignalOff = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		m_nCurStep = 0;
+	}
+
+	CReadStep::~CReadStep()
+	{
+		ASSERT(m_hReadSignalOn);
+		CloseHandle(m_hReadSignalOn);
+		m_hReadSignalOn = nullptr;
+
+		ASSERT(m_hReadSignalOff);
+		CloseHandle(m_hReadSignalOff);
+		m_hReadSignalOff = nullptr;
+	}
+
+	void CReadStep::setWriteSignalDev(int dev)
+	{
+		m_nWriteSignalDev = dev;
+	}
+
+	void CReadStep::onReadSignal(BOOL bSignal)
+	{
+		Lock();
+		if (m_nCurStep == 0 && bSignal) {
+			SetEvent(m_hReadSignalOn);
+		}
+		else if (m_nCurStep == 3 && !bSignal) {
+			SetEvent(m_hReadSignalOff);
+		}
+
+		Unlock();
+	}
+
+	int CReadStep::onReadData()
+	{
+		return 0;
+	}
+
+	unsigned CReadStep::WorkingProc()
+	{
+		HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		BOOL bReadOk = FALSE;
+
+		int nBeginAddr = 0x0;
+		while (1) {
+		RESET:
+			resetStep();
+
+			// 待退出信号或时间到
+			HANDLE hEvents[] = { m_hWorkStop, m_hReadSignalOn };
+			int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
+			if (nRet == WAIT_OBJECT_0) {
+				ResetEvent(m_hWorkStop);
+				break;
+			}
+
+			else if (nRet == WAIT_OBJECT_0 + 1) {
+				ResetEvent(m_hReadSignalOn);
+
+				// 1.读取数据
+				nextStep();
+				ASSERT(m_pCclink);
+				if (0 == onReadData()) {
+					if (m_listener.onEvent != nullptr) {
+						m_listener.onEvent(this, STEP_EVENT_READDATA, nullptr);
+					}
+				}
+
+				// 2.给对方写ON
+				nextStep();
+				m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+
+
+				// 3.等待对方OFF
+				nextStep();
+				int nStep3Ret = ::WaitForSingleObject(m_hReadSignalOff, TIMEOUT * 1000);
+				if (nStep3Ret == WAIT_TIMEOUT) {
+					m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+					onTimeout();
+					goto RESET;
+				}
+				ResetEvent(m_hReadSignalOff);
+
+
+				// 4.给对方写OFF
+				nextStep();
+				m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+
+
+				// 6.完成
+				nextStep();
+				if (0 == onComplete()) {
+					if (m_listener.onEvent != nullptr) {
+						m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
+					}
+				}
+			}
+		}
+
+		if (hEvent != nullptr) {
+			CloseHandle(hEvent);
+		}
+
+		// _endthreadex(0);
+		TRACE("CStep::WorkingProc 线程退出\n");
+		return 0;
+	}
+
+	void CReadStep::getAttributeVector(CAttributeVector& attrubutes)
+	{
+		CStep::getAttributeVector(attrubutes);
+		attrubutes.addAttribute(new CAttribute("Current Step",
+			std::to_string(m_nCurStep).c_str(), ""));
+		attrubutes.addAttribute(new CAttribute("Signal Dev",
+			std::to_string(m_nWriteSignalDev).c_str(), ""));
+	}
+
+	void CReadStep::init()
+	{
+		CStep::init();
+
+		if (m_hWorkStop != nullptr) return;
+		m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadStepWorkThreadFunction, this,
+			0, &m_nWordThreadAddr);
+	}
+
+	void CReadStep::term()
+	{
+		CStep::term();
+
+		ASSERT(m_hWorkStop);
+		SetEvent(m_hWorkStop);
+		if (m_hWorkThreadHandle != NULL) {
+			WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
+			CloseHandle(m_hWorkThreadHandle);
+			m_hWorkThreadHandle = NULL;
+		}
+		CloseHandle(m_hWorkStop);
+		m_hWorkStop = NULL;
+	}
+
+	void CReadStep::resetStep()
+	{
+		Lock();
+		m_nCurStep = 0;
+		Unlock();
+	}
+
+	void CReadStep::nextStep()
+	{
+		Lock();
+		m_nCurStep++;
+		Unlock();
+	}
+
+
+	int CReadStep::onComplete()
+	{
+		return 0;
+	}
+
+	int CReadStep::onTimeout()
+	{
+		return 0;
+	}
+}
diff --git a/SourceCode/Bond/Servo/CReadStep.h b/SourceCode/Bond/Servo/CReadStep.h
new file mode 100644
index 0000000..2b0df3b
--- /dev/null
+++ b/SourceCode/Bond/Servo/CReadStep.h
@@ -0,0 +1,35 @@
+#pragma once
+#include "CStep.h"
+
+
+namespace SERVO {
+	class CReadStep : public CStep
+	{
+	public:
+		CReadStep();
+		virtual ~CReadStep();
+
+	public:
+		unsigned WorkingProc();
+		virtual void setWriteSignalDev(int dev);
+		virtual void onReadSignal(BOOL bSignal);
+		virtual int onReadData();
+		virtual void init();
+		virtual void term();
+		virtual void getAttributeVector(CAttributeVector& attrubutes);
+		virtual int onComplete();
+		virtual int onTimeout();
+		inline void nextStep();
+		inline void resetStep();
+
+	protected:
+		HANDLE m_hWorkThreadHandle;
+		unsigned m_nWordThreadAddr;
+		HANDLE m_hWorkStop;
+		HANDLE m_hReadSignalOn;
+		HANDLE m_hReadSignalOff;
+		int m_nCurStep;
+		int m_nWriteSignalDev;			// 对方BIT地址
+	};
+}
+
diff --git a/SourceCode/Bond/Servo/CStep.cpp b/SourceCode/Bond/Servo/CStep.cpp
index 6690b0f..dbbf161 100644
--- a/SourceCode/Bond/Servo/CStep.cpp
+++ b/SourceCode/Bond/Servo/CStep.cpp
@@ -1,41 +1,18 @@
 #include "stdafx.h"
 #include "CStep.h"
-#include "Common.h"
 
 
 namespace SERVO {
-#define TIMEOUT			15
-
-	unsigned __stdcall StepWorkThreadFunction(LPVOID lpParam)
-	{
-		CStep* pStep = (CStep*)lpParam;
-		return pStep->WorkingProc();
-	}
 
 	CStep::CStep()
 	{
 		m_listener = {nullptr};
-		m_nWordThreadAddr = 0;
-		m_hWorkStop = nullptr;
-		m_hWorkThreadHandle = nullptr;
-		m_hSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
-		m_hSignalOff = ::CreateEvent(NULL, TRUE, FALSE, NULL);
-		m_nCurStep = 0;
 		m_pCclink = nullptr;
-		m_nWriteSignalDev = 0;
 		InitializeCriticalSection(&m_criticalSection);
 	}
 
 	CStep::~CStep()
 	{
-		ASSERT(m_hSignalOn);
-		CloseHandle(m_hSignalOn);
-		m_hSignalOn = nullptr;
-
-		ASSERT(m_hSignalOff);
-		CloseHandle(m_hSignalOff);
-		m_hSignalOff = nullptr;
-
 		DeleteCriticalSection(&m_criticalSection);
 	}
 
@@ -76,148 +53,16 @@
 			std::to_string(m_station.nNetNo).c_str(), ""));
 		attrubutes.addAttribute(new CAttribute("Station",
 			std::to_string(m_station.nStNo).c_str(), ""));
-		attrubutes.addAttribute(new CAttribute("Current Step",
-			std::to_string(m_nCurStep).c_str(), ""));
-		attrubutes.addAttribute(new CAttribute("Signal Dev",
-			std::to_string(m_nWriteSignalDev).c_str(), ""));
-	}
-
-	void CStep::setWriteSignalDev(int dev)
-	{
-		m_nWriteSignalDev = dev;
 	}
 
 	void CStep::init()
 	{
-		if (m_hWorkStop != nullptr) return;
-		m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
-		m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::StepWorkThreadFunction, this,
-			0, &m_nWordThreadAddr);
+
 	}
 
 	void CStep::term()
 	{
-		ASSERT(m_hWorkStop);
-		SetEvent(m_hWorkStop);
-		if (m_hWorkThreadHandle != NULL) {
-			WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
-			CloseHandle(m_hWorkThreadHandle);
-			m_hWorkThreadHandle = NULL;
-		}
-		CloseHandle(m_hWorkStop);
-		m_hWorkStop = NULL;
-	}
 
-	unsigned CStep::WorkingProc()
-	{
-		HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
-		BOOL bReadOk = FALSE;
-
-		int nBeginAddr = 0x0;
-		while (1) {
-RESET:
-			resetStep();
-
-			// 待退出信号或时间到
-			HANDLE hEvents[] = { m_hWorkStop, m_hSignalOn };
-			int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
-			if (nRet == WAIT_OBJECT_0) {
-				ResetEvent(m_hWorkStop);
-				break;
-			}
-
-			else if (nRet == WAIT_OBJECT_0 + 1) {
-				ResetEvent(m_hSignalOn);
-
-				// 1.读取数据
-				nextStep();
-				ASSERT(m_pCclink);
-				if (0 == onReadData()) {
-					if (m_listener.onEvent != nullptr) {
-						m_listener.onEvent(this, STEP_EVENT_READDATA, nullptr);
-					}
-				}
-
-				// 2.给对方写ON
-				nextStep();
-				m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
-
-
-				// 3.等待对方OFF
-				nextStep();
-				int nStep3Ret = ::WaitForSingleObject(m_hSignalOff, TIMEOUT * 1000);
-				if (nStep3Ret == WAIT_TIMEOUT) {
-					m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
-					onTimeout();
-					goto RESET;
-				}
-				ResetEvent(m_hSignalOff);
-
-
-				// 4.给对方写OFF
-				nextStep();
-				m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
-
-
-				// 6.完成
-				nextStep();
-				if (0 == onComplete()) {
-					if (m_listener.onEvent != nullptr) {
-						m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
-					}
-				}
-			}
-		}
-
-		if (hEvent != nullptr) {
-			CloseHandle(hEvent);
-		}
-
-		// _endthreadex(0);
-		TRACE("CStep::WorkingProc 线程退出\n");
-		return 0;
-	}
-
-	void CStep::onSignal(BOOL bSignal)
-	{
-		Lock();
-		if (m_nCurStep == 0 && bSignal) {
-			SetEvent(m_hSignalOn);
-		}
-		else if (m_nCurStep == 3 && !bSignal) {
-			SetEvent(m_hSignalOff);
-		}
-
-		Unlock();
-	}
-
-	int CStep::onReadData()
-	{
-		return 0;
-	}
-
-	int CStep::onComplete()
-	{
-		return 0;
-	}
-
-	int CStep::onTimeout()
-	{
-		return 0;
-	}
-
-	void CStep::resetStep()
-	{
-		Lock();
-		m_nCurStep = 0;
-		Unlock();
-	}
-
-	void CStep::nextStep()
-	{
-		Lock();
-		m_nCurStep++;
-		Unlock();
 	}
 
 	void CStep::convertString(const char* pszBuffer, int size, std::string& strOut)
diff --git a/SourceCode/Bond/Servo/CStep.h b/SourceCode/Bond/Servo/CStep.h
index d1ece05..fc6d403 100644
--- a/SourceCode/Bond/Servo/CStep.h
+++ b/SourceCode/Bond/Servo/CStep.h
@@ -19,7 +19,6 @@
 		virtual ~CStep();
 
 	public:
-		unsigned WorkingProc();
 		void setListener(StepListener listener);
 		void setCcLink(CCCLinkIEControl* pCcLink);
 		void setEquipment(CEquipment* pEquipment);
@@ -27,19 +26,13 @@
 		void setName(const char* pszName);
 		std::string& getName();
 		virtual void getAttributeVector(CAttributeVector& attrubutes);
-		virtual void setWriteSignalDev(int dev);
 		virtual void init();
-		virtual void CStep::term();
-		virtual void onSignal(BOOL bSignal);
-		virtual int onReadData();
-		virtual int onComplete();
-		virtual int onTimeout();
+		virtual void term();
+
 
 	protected:
 		inline void Lock() { EnterCriticalSection(&m_criticalSection); }
 		inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
-		inline void nextStep();
-		inline void resetStep();
 		void convertString(const char* pszBuffer, int size, std::string& strOut);
 
 	protected:
@@ -49,13 +42,6 @@
 		CEquipment* m_pEquipment;
 		CCCLinkIEControl* m_pCclink;
 		CRITICAL_SECTION m_criticalSection;
-		HANDLE m_hWorkThreadHandle;
-		unsigned m_nWordThreadAddr;
-		HANDLE m_hWorkStop;
-		HANDLE m_hSignalOn;
-		HANDLE m_hSignalOff;
-		int m_nCurStep;
-		int m_nWriteSignalDev;			// 对方BIT地址
 	};
 }
 
diff --git a/SourceCode/Bond/Servo/CWriteStep.cpp b/SourceCode/Bond/Servo/CWriteStep.cpp
new file mode 100644
index 0000000..15f6a2a
--- /dev/null
+++ b/SourceCode/Bond/Servo/CWriteStep.cpp
@@ -0,0 +1,197 @@
+#include "stdafx.h"
+#include "CWriteStep.h"
+#include "Common.h"
+
+
+namespace SERVO {
+#define TIMEOUT			15
+
+	unsigned __stdcall WriteStepWorkThreadFunction(LPVOID lpParam)
+	{
+		CWriteStep* pStep = (CWriteStep*)lpParam;
+		return pStep->WorkingProc();
+	}
+
+	CWriteStep::CWriteStep() : CStep()
+	{
+		m_nWordThreadAddr = 0;
+		m_hWorkStop = nullptr;
+		m_hWorkThreadHandle = nullptr;
+		m_nCurStep = 0;
+		m_nWriteSignalDev = 0;
+		m_nWriteDataSize = 0;
+		m_nWriteDevNo = 0;
+		m_hWriteSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		m_hRecvSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+	}
+
+	CWriteStep::~CWriteStep()
+	{
+		ASSERT(m_hWriteSignalOn);
+		CloseHandle(m_hWriteSignalOn);
+		m_hWriteSignalOn = nullptr;
+
+		ASSERT(m_hRecvSignalOn);
+		CloseHandle(m_hRecvSignalOn);
+		m_hRecvSignalOn = nullptr;
+	}
+
+	int CWriteStep::writeData(short devno, const char* pszData, int size)
+	{
+		if (size > 1024) return -1;
+		if (m_nCurStep != 0) return -2;
+
+		memcpy(m_szBuffer, pszData, size);
+		m_nWriteDataSize = size;
+		m_nWriteDevNo = devno;
+		SetEvent(m_hWriteSignalOn);
+
+		return 0;
+	}
+
+	void CWriteStep::setWriteSignalDev(int dev)
+	{
+		m_nWriteSignalDev = dev;
+	}
+
+	void CWriteStep::onRecvSignal(BOOL bSignal)
+	{
+		Lock();
+		if (m_nCurStep == 3 && bSignal) {
+			SetEvent(m_hRecvSignalOn);
+		}
+
+		Unlock();
+	}
+
+	unsigned CWriteStep::WorkingProc()
+	{
+		HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		BOOL bReadOk = FALSE;
+
+		int nBeginAddr = 0x0;
+		while (1) {
+		RESET:
+			resetStep();
+
+			// 待退出信号或时间到
+			HANDLE hEvents[] = { m_hWorkStop, m_hWriteSignalOn };
+			int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
+			if (nRet == WAIT_OBJECT_0) {
+				ResetEvent(m_hWorkStop);
+				break;
+			}
+
+			else if (nRet == WAIT_OBJECT_0 + 1) {
+				ResetEvent(m_hWriteSignalOn);
+
+				// 1.写数据
+				nextStep();
+				ASSERT(m_pCclink);
+				int nRet = m_pCclink->WriteData(m_station, (short)DeviceType::W,
+					m_nWriteDevNo, m_nWriteDataSize, (short*)m_szBuffer);
+				if (0 != nRet) {
+					onTimeout();
+					goto RESET;
+				}
+
+
+				// 2.给对方写ON
+				nextStep();
+				m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+
+
+				// 3.等待对方ON
+				nextStep();
+				int nStep3Ret = ::WaitForSingleObject(m_hRecvSignalOn, TIMEOUT * 1000);
+				if (nStep3Ret == WAIT_TIMEOUT) {
+					m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+					onTimeout();
+					goto RESET;
+				}
+				ResetEvent(m_hRecvSignalOn);
+
+
+				// 4.写OFF
+				nextStep();
+				m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
+
+
+				// 6.完成
+				nextStep();
+				if (0 == onComplete()) {
+					if (m_listener.onEvent != nullptr) {
+						m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
+					}
+				}
+			}
+		}
+
+		if (hEvent != nullptr) {
+			CloseHandle(hEvent);
+		}
+
+		// _endthreadex(0);
+		TRACE("CStep::WorkingProc 线程退出\n");
+		return 0;
+	}
+
+	void CWriteStep::getAttributeVector(CAttributeVector& attrubutes)
+	{
+		CStep::getAttributeVector(attrubutes);
+
+		attrubutes.addAttribute(new CAttribute("Current Step",
+			std::to_string(m_nCurStep).c_str(), ""));
+		attrubutes.addAttribute(new CAttribute("Signal Dev",
+			std::to_string(m_nWriteSignalDev).c_str(), ""));
+	}
+
+	void CWriteStep::init()
+	{
+		CStep::init();
+
+		if (m_hWorkStop != nullptr) return;
+		m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::WriteStepWorkThreadFunction, this,
+			0, &m_nWordThreadAddr);
+	}
+
+	void CWriteStep::term()
+	{
+		CStep::term();
+
+		ASSERT(m_hWorkStop);
+		SetEvent(m_hWorkStop);
+		if (m_hWorkThreadHandle != NULL) {
+			WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
+			CloseHandle(m_hWorkThreadHandle);
+			m_hWorkThreadHandle = NULL;
+		}
+		CloseHandle(m_hWorkStop);
+		m_hWorkStop = NULL;
+	}
+
+	void CWriteStep::resetStep()
+	{
+		Lock();
+		m_nCurStep = 0;
+		Unlock();
+	}
+
+	void CWriteStep::nextStep()
+	{
+		Lock();
+		m_nCurStep++;
+		Unlock();
+	}
+
+	int CWriteStep::onComplete()
+	{
+		return 0;
+	}
+
+	int CWriteStep::onTimeout()
+	{
+		return 0;
+	}
+}
diff --git a/SourceCode/Bond/Servo/CWriteStep.h b/SourceCode/Bond/Servo/CWriteStep.h
new file mode 100644
index 0000000..6bb6b30
--- /dev/null
+++ b/SourceCode/Bond/Servo/CWriteStep.h
@@ -0,0 +1,38 @@
+#pragma once
+#include "CStep.h"
+
+
+namespace SERVO {
+	class CWriteStep : public CStep
+	{
+	public:
+		CWriteStep();
+		virtual ~CWriteStep();
+
+	public:
+		unsigned WorkingProc();
+		virtual void setWriteSignalDev(int dev);
+		virtual void onRecvSignal(BOOL bSignal);
+		int writeData(short devno, const char* pszData, int size);
+		virtual void init();
+		virtual void term();
+		virtual void getAttributeVector(CAttributeVector& attrubutes);
+		virtual int onComplete();
+		virtual int onTimeout();
+		inline void nextStep();
+		inline void resetStep();
+
+	protected:
+		HANDLE m_hWorkThreadHandle;
+		unsigned m_nWordThreadAddr;
+		HANDLE m_hWorkStop;
+		HANDLE m_hWriteSignalOn;
+		HANDLE m_hRecvSignalOn;
+		int m_nCurStep;
+		int m_nWriteSignalDev;			// 对方BIT地址
+		char m_szBuffer[1024];
+		int m_nWriteDataSize;
+		int m_nWriteDevNo;
+	};
+}
+
diff --git a/SourceCode/Bond/Servo/Common.h b/SourceCode/Bond/Servo/Common.h
index 3b33cd4..f180769 100644
--- a/SourceCode/Bond/Servo/Common.h
+++ b/SourceCode/Bond/Servo/Common.h
@@ -46,15 +46,16 @@
 
 
 /* step name */
-#define STEP_MODE			_T("EQMode")
-#define STEP_STATUS			_T("EQStatus")
-#define STEP_ALARM_START	_T("EQAlarm")
-#define STEP_ALARM_BLOCK1	_T("EQAlarm1")
-#define STEP_ALARM_BLOCK2	_T("EQAlarm2")
-#define STEP_ALARM_BLOCK3	_T("EQAlarm3")
-#define STEP_ALARM_BLOCK4	_T("EQAlarm4")
-#define STEP_ALARM_BLOCK5	_T("EQAlarm5")
-#define STEP_PROCESS		_T("EQProcess")
+#define STEP_MODE				_T("EQMode")
+#define STEP_STATUS				_T("EQStatus")
+#define STEP_ALARM_START		_T("EQAlarm")
+#define STEP_ALARM_BLOCK1		_T("EQAlarm1")
+#define STEP_ALARM_BLOCK2		_T("EQAlarm2")
+#define STEP_ALARM_BLOCK3		_T("EQAlarm3")
+#define STEP_ALARM_BLOCK4		_T("EQAlarm4")
+#define STEP_ALARM_BLOCK5		_T("EQAlarm5")
+#define STEP_PROCESS			_T("EQProcess")
+#define STEP_CIM_MODE_CHANGE	_T("EQCimModeChange")
 
 
 #define BASE_ALARM_EFEM		10000
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index 454ab67..a09d426 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -205,12 +205,15 @@
     <ClInclude Include="CCLinkPerformance\CCLinkIEControl.h" />
     <ClInclude Include="CCLinkPerformance\PerformanceMelsec.h" />
     <ClInclude Include="CEqAlarmStep.h" />
+    <ClInclude Include="CEqCimModeChangeStep.h" />
     <ClInclude Include="CEqModeStep.h" />
     <ClInclude Include="CEqProcessStep.h" />
     <ClInclude Include="CEqStatusStep.h" />
     <ClInclude Include="CPanelAttributes.h" />
     <ClInclude Include="CPanelMaster.h" />
+    <ClInclude Include="CReadStep.h" />
     <ClInclude Include="CStep.h" />
+    <ClInclude Include="CWriteStep.h" />
     <ClInclude Include="DevicePropertyDlg.h" />
     <ClInclude Include="CEFEM.h" />
     <ClInclude Include="CEquipment.h" />
@@ -247,12 +250,15 @@
     <ClCompile Include="CCLinkPerformance\CCLinkIEControl.cpp" />
     <ClCompile Include="CCLinkPerformance\PerformanceMelsec.cpp" />
     <ClCompile Include="CEqAlarmStep.cpp" />
+    <ClCompile Include="CEqCimModeChangeStep.cpp" />
     <ClCompile Include="CEqModeStep.cpp" />
     <ClCompile Include="CEqProcessStep.cpp" />
     <ClCompile Include="CEqStatusStep.cpp" />
     <ClCompile Include="CPanelAttributes.cpp" />
     <ClCompile Include="CPanelMaster.cpp" />
+    <ClCompile Include="CReadStep.cpp" />
     <ClCompile Include="CStep.cpp" />
+    <ClCompile Include="CWriteStep.cpp" />
     <ClCompile Include="DevicePropertyDlg.cpp" />
     <ClCompile Include="CEFEM.cpp" />
     <ClCompile Include="CEquipment.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index 0f465c7..01cdf36 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -48,6 +48,9 @@
     <ClCompile Include="VerticalLine.cpp" />
     <ClCompile Include="ApredTreeCtrl2.cpp" />
     <ClCompile Include="CPanelAttributes.cpp" />
+    <ClCompile Include="CReadStep.cpp" />
+    <ClCompile Include="CWriteStep.cpp" />
+    <ClCompile Include="CEqCimModeChangeStep.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="AlarmManager.h" />
@@ -94,6 +97,9 @@
     <ClInclude Include="VerticalLine.h" />
     <ClInclude Include="ApredTreeCtrl2.h" />
     <ClInclude Include="CPanelAttributes.h" />
+    <ClInclude Include="CReadStep.h" />
+    <ClInclude Include="CWriteStep.h" />
+    <ClInclude Include="CEqCimModeChangeStep.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Servo.rc" />

--
Gitblit v1.9.3