📄 digitaldongle.cpp
字号:
// DigitalDongle.cpp: implementation of the CDigitalDongle class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "eVCComm.h"
#include "DigitalDongle.h"
#include "Mmsystem.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
enum {PACKET_TYPE_WRITE=0x01,PACKET_TYPE_READ=0x02};
enum {WAIT_FOR_PACKET_TYPE,WAIT_FOR_STATUS,WAIT_FOR_SUCCESS_DATA_LENGTH,
WAIT_FOR_ADDRESS,WAIT_FOR_DATA,WAIT_FOR_CHECKSUM}state;
CDigitalDongle::CDigitalDongle(int PortNum)
{
m_pSerialPort=new CSerialPort();
m_pSerialPort->OpenPort(PortNum);
m_pSerialPort->set_data_callback(OnDataFromPort,this);
state=WAIT_FOR_PACKET_TYPE;
done=TRUE;
operate_done_func=NULL;
monitor_operate_thread_terminate=FALSE;
Monitor_Operate();
}
CDigitalDongle::~CDigitalDongle()
{
monitor_operate_thread_terminate=TRUE;
Sleep(0);
}
void CDigitalDongle::OnDataFromPort(void * data, DWORD nDataCount,void * context)
{
static unsigned long addr;
static BYTE data_buf[256];
static int dataCount;
static int tmp_pos;
CDigitalDongle *pDongle;
int count;
int c; /* Temporary variable for index calculations */
BYTE *buf; /* Temporary pointer to the incoming data */
buf = (BYTE *)data;
count= nDataCount;
pDongle=(CDigitalDongle *)context;
while (count > 0) {
switch (state)
{
case WAIT_FOR_PACKET_TYPE:
tmp_pos = 0;
dataCount = 0;
switch(*buf) {
case PACKET_TYPE_WRITE:
case PACKET_TYPE_READ:
state = WAIT_FOR_STATUS;
break;
default:
#ifdef DEBUG
CString tmp;
tmp.Format(_T("packet type error[0x%02X] count=%d"),*buf,count);
AfxMessageBox(tmp);
#endif
return;
}
data_buf[dataCount++]=*buf;
buf++;
count--;
break;
case WAIT_FOR_STATUS:
data_buf[dataCount++]=*buf;
if((*buf)!=0x00)//status is failed
{
state = WAIT_FOR_CHECKSUM;
}
else
{
state = WAIT_FOR_SUCCESS_DATA_LENGTH;
}
buf++;
count--;
break;
case WAIT_FOR_SUCCESS_DATA_LENGTH:
data_buf[dataCount++]=*buf;
state = WAIT_FOR_ADDRESS;
buf++;
count--;
break;
case WAIT_FOR_ADDRESS:
if (tmp_pos <4) {
c = min(count,4 - tmp_pos);
memcpy(data_buf + dataCount,buf,c);
dataCount += c;
tmp_pos+=c;
count -=c;
buf += c;
if(tmp_pos == 4)
{
if(data_buf[0]==PACKET_TYPE_WRITE)
{
state = WAIT_FOR_CHECKSUM;
}
else
{
tmp_pos = 0;
state = WAIT_FOR_DATA;
}
}
}
break;
case WAIT_FOR_DATA:
if (tmp_pos < data_buf[2]/*data length*/) {
c = min(count, data_buf[2] - tmp_pos);
memcpy(data_buf + dataCount,buf,c);
dataCount += c;
tmp_pos += c;
count -= c;
buf += c;
if (tmp_pos == data_buf[2]) {
state = WAIT_FOR_CHECKSUM;
}
}
break;
case WAIT_FOR_CHECKSUM:
data_buf[dataCount++]=*buf;
buf++;
count--;
pDongle->ProcessPacket(data_buf,dataCount);
break;
default:
#ifdef DEBUG
AfxMessageBox(_T("not this message"));
#endif
break;
}
}
}
BOOL CDigitalDongle::SendWriteCmd(unsigned long addr, LPBYTE data, int len)
{
BYTE buffer[4];
if(!m_pSerialPort->IsOpen())
return FALSE;
if(len>128)//每个分组的数据量不能超过128个字节
return FALSE;
if(done==FALSE) //上一次操作还没有完成
return FALSE;
buffer[0]=PACKET_TYPE_WRITE;
m_pSerialPort->WriteData(buffer,1);
buffer[0]=len;
m_pSerialPort->WriteData(buffer,1);
buffer[0]=(BYTE)((addr >> 24) & 0xff);
buffer[1]=(BYTE)((addr >> 16) & 0xff);
buffer[2]=(BYTE)((addr >> 8) & 0xff);
buffer[3]=(BYTE)((addr >> 0) & 0xff);
m_pSerialPort->WriteData(buffer,4);
m_pSerialPort->WriteData(data,len);
buffer[0]=CheckSum(data,len);
m_pSerialPort->WriteData(buffer,1);
lastPacketType=PACKET_TYPE_WRITE;
lastAddr=addr;
memcpy(lastData,data,len);
lastDataLength=len;
lastRetryTime=CTime::GetCurrentTime().GetTime();
retryNum=0;
done=FALSE;
return TRUE;
}
BOOL CDigitalDongle::SendReadCmd(unsigned long addr, int len)
{
return TRUE;
}
/*计算数据的校验和*/
BYTE CDigitalDongle::CheckSum(LPBYTE data, int len)
{
BYTE checksum;
checksum=0;
for(int i=0;i<len;i++)
{
checksum+=data[i];
}
return checksum;
}
void CDigitalDongle::ProcessPacket(LPBYTE data, int len)
{
BYTE packet_type;
BYTE status;
BYTE length;
unsigned long addr;
packet_type=data[0];
status=data[1];
length=data[2];
addr=(((data[3]*256)+data[4])*256+data[5])+data[6];
if(CheckSum(data,len-1)!=data[len])/*校验失败*/
{
if(status==0x00)
status=STATUS_OPERATE_TIMEOUT;
}
if(operate_done_func)
{
operate_done_func(packet_type,status,addr,length,operate_done_func_context);
}
done=TRUE;
}
void CDigitalDongle::Monitor_Operate()
{
DWORD thread_id;
CreateThread(0, 0, CDigitalDongle::monitor_operate_thread, this, 0, &thread_id);
}
DWORD WINAPI CDigitalDongle::monitor_operate_thread(LPVOID arg)
{
CDigitalDongle *pDongle;
DWORD currTime;
pDongle = (CDigitalDongle *) arg;
pDongle->monitor_operate_thread_terminate=FALSE;
while (!pDongle->monitor_operate_thread_terminate)
{
if(pDongle->done==FALSE)//已经进行了一次操作,但还没有收到应答
{
currTime=CTime::GetCurrentTime().GetTime();
if(currTime - pDongle->lastRetryTime >= OPERATE_TIMEOUT)//操作超时
{
if(pDongle->retryNum<MAX_RETRY_COUNT)
{
pDongle->RedoLastOperator();
pDongle->retryNum++;
}
else
{
if(pDongle->operate_done_func)
{
pDongle->operate_done_func(pDongle->lastPacketType,STATUS_OPERATE_TIMEOUT,pDongle->lastAddr,0,pDongle->operate_done_func_context);
pDongle->done=TRUE;
}
}
}
}
Sleep(100);
}
return 0;
}
void CDigitalDongle::set_operate_complete_callback(void (*func)(BYTE, BYTE, unsigned long,BYTE,void *), void *context)
{
operate_done_func=func;
operate_done_func_context=context;
}
void CDigitalDongle::RedoLastOperator()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -