#include #include #include "c232comm.h" #include "CRIO.h" static int RIOLengths[] = { 0, // 0.CheckRequest 0, // 1.VersionRequest 0, // 2.AnalogRequest 1, // 3.ResetRequest 2, // 4.LampRequest 2, // 5.CheckReply 2, // 6.VersionReply 10, // 7.AnalogReply 1, // 8.ButtonPressed 1, // 9.ButtonReleased 2, // 10.KeyPressed 2, // 11.KeyReleased 1 // 12.TestModeChange }; static const char* RIOPackets[] = { "CheckRequest", "VersionRequest", "AnalogRequest", "ResetRequest", "LampRequest", "CheckReply", "VersionReply", "AnalogReply", "ButtonPressed", "ButtonReleased", "KeyPressed", "KeyReleased", "TestModeChange", }; void CRIO::Init () { m_pStart = &m_ba[0]; m_pEnd = &m_ba[sizeof (m_ba)]; m_nCount = 0; m_dwFlags = 0; m_nState = 0; m_nRead = 0; m_nLeft = 0; m_bCheck = 0; m_nReplies = 0; TestModeActive = 0; m_dwAnalogRequest = 0; } void CRIO::RIOBordState (BYTE ID) { switch (ID) { case BoardMissing: break; case BoardBad: break; case LampBad: break; case RestartCount: break; case AbandonCount: break; case FullBufferCount: break; } } void CRIO::DoEventLoop() { CString str, temp; BYTE baBuffer[256]; int nRet = -1; if (IsValid()) { memset (baBuffer, 0, sizeof(baBuffer)); nRet = rxCom (&baBuffer[0], sizeof(baBuffer)); if (nRet > 0) { EventLoop (baBuffer, nRet); } else { } CheckAnalogRequest(); } else { } while(m_ListBox.GetCount() > 40) { m_ListBox.DeleteString(0); } } void CRIO::EventLoop(const BYTE *buf, int nLen) { int nNewLen; BYTE *pIndex; CString strText; nNewLen = m_nCount + nLen; pIndex = &m_pStart[nNewLen]; if (pIndex > m_pEnd) { if (m_nCount > 0) { memcpy (&m_ba[0], m_pStart, m_nCount); } m_pStart = &m_ba[0]; } memcpy (&m_pStart[m_nCount], &buf[0], nLen); m_nCount += nNewLen; while (m_nCount > 0) { BYTE bCmd = m_pStart[0]; switch (bCmd) { case IDLE_CHAR: m_ListBox.AddString("IDLE"); break; case ACK_CHAR: m_dwFlags |= RX_ACK_BIT; m_ListBox.AddString("ACK"); break; case NAK_CHAR: m_dwFlags |= RX_NAK_BIT; m_ListBox.AddString("NAK"); break; default: if (m_nState) { if (bCmd & 0x80) { m_nState = 0; if (bCmd == RESTART_CHAR) { // discard... m_ListBox.AddString("DISCARD"); } else { // error. AddReply (NAK_CHAR); } } else { if (m_nLeft > 0) { m_baRead[m_nRead++] = bCmd; m_bCheck += bCmd; m_nLeft--; } else { MSBOFF (m_bCheck); m_nState = 0; if (bCmd == m_bCheck) { // chechsum OK. AddReply (ACK_CHAR); #ifdef TEST_RIO switch(m_baRead[0]) { case rio_CheckReply: strText.Format("CheckReply(%x)", m_baRead[1]); RIOBordState (m_baRead[1]); break; case rio_VersionReply: strText = "VersionReply"; break; case rio_AnalogReply: strText = "AnalogReply"; m_dwAnalogRequest = 0; break; case rio_ButtonPressed: strText.Format("[%d] 버튼눌림", m_baRead[1]); break; case rio_ButtonReleased: strText.Format("[%d] 버튼띰", m_baRead[1]); break; case rio_KeyPressed: strText = "KeyPressed"; break; case rio_TestModeChange: TestModeActive = 1; if (m_baRead[1] != 0) { } else { TestModeActive = 0; } strText = "TestModeChange"; break; default: strText = "Default"; break; } m_ListBox.AddString(strText); #else // //extern void RioButtonManager (BYTE *byData); //RioButtonManager(m_baRead); #endif // } else { // error. AddReply(NAK_CHAR); } } } } else { if (bCmd & 0x80) { if (bCmd == RESTART_CHAR) { // restart... m_ListBox.AddString("Restart"); } else { MSBOFF (bCmd); if (MAXLENGTH) { // valid command... m_bCheck = bCmd; m_baRead[0] = bCmd | 0x80; m_nRead = 1; m_nLeft = RIOLengths[bCmd]; m_nState = 1; } else { // unknown command... } } } else { // error... } } break; } m_pStart++; m_nCount--; } CheckReplies(); } void CRIO::AddReply (BYTE bReply) { // ASSERT ((bReply == ACK_CHAR) || (bReply == NAK_CHAR)); if (m_nReplies < (sizeof (m_baReplies) / sizeof (m_baReplies[0]))) { m_baReplies[m_nReplies++] = bReply; } else { // reply buffer full... } } void CRIO::CheckReplies () { if (m_nReplies > 0) { int nRet = txCom (&m_baReplies, m_nReplies); if (nRet > 0) { CString str; str.Format(">>ACK or NAK - %d", nRet); m_ListBox.AddString(str); m_nReplies -= nRet; if (m_nReplies > 0) { memcpy (&m_baReplies[0], &m_baReplies[nRet], m_nReplies); } else { // ASSERT (m_nReplies == 0); m_nReplies = 0; } } } } void CRIO::CheckAnalogRequest() { static BOOL s_b1st = TRUE; if (s_b1st) { s_b1st = FALSE; } else { if (m_dwAnalogRequest == 0) { update: RequestAnalogUpdate(); m_dwAnalogRequest = GetTickCount(); } else { if ((m_dwAnalogRequest + 1000) < GetTickCount()) { goto update; } } } } void CRIO::SendCommand (const BYTE* pbPacket) { BYTE ba[256]; BYTE bCmd = *pbPacket++; if (bCmd & 0x80) { MSBOFF (bCmd); if (bCmd < MAXLENGTH) { CString str; str.Format(">>%s", RIOPackets[bCmd]); int nLeft = RIOLengths[bCmd]; BYTE* p = &ba[0]; BYTE bCheck = bCmd; MSBON (bCmd); *p++ = bCmd; while (nLeft > 0) { BYTE b = *pbPacket++; MSBOFF (b); bCheck += b; *p++ = b; nLeft--; } MSBOFF (bCheck); *p++ = bCheck; SendPacket (&ba[0], p - &ba[0]); m_ListBox.AddString(str); } else { m_ListBox.AddString("unknown command"); } } else { m_ListBox.AddString("error"); } } void CRIO::SendPacket (const BYTE* pbPacket, int nLen) { CheckReplies(); txComLoop(pbPacket, nLen); } void CRIO::SetLamp(int lampNumber, int state) { static BYTE request_lamp_string[] = { rio_LampRequest, 0, 0 }; request_lamp_string[1] = (BYTE) (lampNumber & 0x7F); request_lamp_string[2] = (BYTE) (state & 0x7F); SendCommand (request_lamp_string); } void CRIO::GeneralReset() { static BYTE request_reset_string[] = { rio_ResetRequest, 0 }; SendCommand (request_reset_string); } void CRIO::ResetThrottle() { static BYTE request_throttle_string[] = { rio_ResetRequest, 1 }; SendCommand (request_throttle_string); } void CRIO::RequestCheck() { static BYTE request_check_string[] = { rio_CheckRequest }; SendCommand (request_check_string); } void CRIO::RequestVersion() { static BYTE request_version_string[] = { rio_VersionRequest }; SendCommand (request_version_string); } void CRIO::RequestAnalogUpdate() { static BYTE request_analog_string[] = { rio_AnalogRequest }; SendCommand (request_analog_string); }