QuakeGod
2024-12-24 61deef5cdf96cbfdd6ad45be49e80d597c00ca65
提交 | 用户 | age
418cb3 1 #include "pch.h"
Q 2 #include "HvSerialPort.h"
3
4 int HvSerialPort1::Init()
5 {
6     return R_OK;
7 }
8
9 int HvSerialPort1::SetParams(int nPortNum, int BaudRate, CString Settings)
10 {
11     m_nPort = nPortNum;
12     m_nBaudRate = BaudRate;
13     m_Settings = Settings;
14     return R_OK;
15 }
16
17 int HvSerialPort1::Open()
18 {
19     // TODO: 在此处添加实现代码.
20     //Open Port
21     int j;
22     CString s1, s2;
23     CString ComPortName;
24     m_strResult.Empty();
25     if (this->m_nPort == 0) 
26     {
27         m_strResult.Format(_T("COM not specified %d"),m_nPort);
28         return R_ERR; 
29     }
30     if (this->m_bOpened) 
31     { 
32         m_strResult.Format(_T("COM%d already Opened"),m_nPort);
df0321 33         return R_OK;
418cb3 34     }
Q 35     ComPortName.Format(_T("\\\\.\\COM%d"), this->m_nPort);
36     hCom1 = CreateFile(ComPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED
37     if (hCom1 == INVALID_HANDLE_VALUE)
38     {
39         m_dwError = GetLastError();
40         m_bOpened = false;
41         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, m_dwError, 0, s1.GetBuffer(2048), 2048, NULL);
42         s1.ReleaseBuffer();
43
44         m_strResult.Format(_T("Open COM%d Err %d ,%s "), this->m_nPort, this->m_dwError, s1);
45         return R_ERR;
46     }
47     else
48     {
49         m_dwError = GetLastError();
50
51         m_strResult.Format(_T("COM%d OK."), this->m_nPort);
52         LastTime = GetTimemS();
53         TotalSendBytes = 0; TotalRecvBytes = 0;
54         LastSendBytes = 0; SendBytes = 0; RecvBytes = 0;
55         LastRecvBytes = 0; SendSpeed = 0; RecvSpeed = 0;
56     }
57
58     j = SetupComm(hCom1, 256, 256);
59
60     DCB dcb1;
61     j = GetCommState(hCom1, &dcb1);
62     BuildCommDCB(m_Settings, &dcb1);
63
64     dcb1.BaudRate = m_nBaudRate;
65
66     if (m_Settings.Find(_T("8")) != -1) { dcb1.ByteSize = 8; }
67     else if (m_Settings.Find(_T("7")) != -1) { dcb1.ByteSize = 8; }
68     else if (m_Settings.Find(_T("6")) != -1) { dcb1.ByteSize = 8; }
69     else if (m_Settings.Find(_T("5")) != -1) { dcb1.ByteSize = 8; }
70
71     if (m_Settings.Find(_T("N")) != -1) { dcb1.fParity = FALSE;    dcb1.Parity = NOPARITY; }
72     else if (m_Settings.Find(_T("O")) != -1) { dcb1.fParity = TRUE;    dcb1.Parity = ODDPARITY; }
73     else if (m_Settings.Find(_T("E")) != -1) { dcb1.fParity = TRUE;    dcb1.Parity = EVENPARITY; }
74     else if (m_Settings.Find(_T("M")) != -1) { dcb1.fParity = TRUE;    dcb1.Parity = MARKPARITY; }
75     else if (m_Settings.Find(_T("S")) != -1) { dcb1.fParity = TRUE;    dcb1.Parity = SPACEPARITY; }
76
77     if (m_Settings.Find(_T("1.5")) != -1) { dcb1.StopBits = ONE5STOPBITS; }
78     else if (m_Settings.Find(_T("1")) != -1) { dcb1.StopBits = ONESTOPBIT; }
79     else if (m_Settings.Find(_T("2")) != -1) { dcb1.StopBits = TWOSTOPBITS; }
80
81     dcb1.fDtrControl = 0;
82     dcb1.fDsrSensitivity = false;
83     dcb1.fBinary = 1;
84     dcb1.fOutxCtsFlow = false;
85     dcb1.fOutxDsrFlow = false;
86     dcb1.fRtsControl = RTS_CONTROL_DISABLE;
87
88     j = SetCommState(hCom1, &dcb1);
89     if (j == 0)
90     {
91         m_strResult.Format(_T("SetCommState Fail  %d %s \r\n"), m_nBaudRate, m_Settings);
92         CloseHandle(hCom1);
93         m_bOpened = false;
94         return R_ERR;
95     }
96     j = GetCommState(hCom1, &dcb1);
97
98     CString strParity;
99     CString strStopBit;
100
101     if (dcb1.Parity == NOPARITY) { strParity = _T("N"); }
102     else if (dcb1.Parity == EVENPARITY) { strParity = _T("E"); }
103     else if (dcb1.Parity == ODDPARITY) { strParity = _T("O"); }
104     else if (dcb1.Parity == MARKPARITY) { strParity = _T("M"); }
105     else if (dcb1.Parity == SPACEPARITY) { strParity = _T("S"); }
106     else { strParity = _T("X"); }
107
108     if (dcb1.StopBits == ONESTOPBIT) { strStopBit = _T("1"); }
109     else if (dcb1.StopBits == ONE5STOPBITS) { strStopBit = _T("1.5"); }
110     else if (dcb1.StopBits == TWOSTOPBITS) { strStopBit = _T("2"); }
111     else { strStopBit = _T("3"); }
112
113     s1.Format(_T("%d %d-%s-%s"), dcb1.BaudRate, dcb1.ByteSize, strParity, strStopBit);
114     m_strResult += s1;
115
116     COMMTIMEOUTS comtimeout1;
117     COMSTAT comstat1;
118     GetCommTimeouts(hCom1, &comtimeout1);
119
120     comtimeout1.ReadIntervalTimeout = 1;    //两个字符之间的时间
121     comtimeout1.ReadTotalTimeoutMultiplier = 0;    //每个字符等待的时间,读多个字符则等待时间为单个时间乘以字符个数
122     comtimeout1.ReadTotalTimeoutConstant = 2;        //读取时,再另外多等待的时间。
123     comtimeout1.WriteTotalTimeoutMultiplier = 0;    //写入时,每个字符等待的时间,写入多个字符则等待时间为单个时间乘以字符个数。
124     comtimeout1.WriteTotalTimeoutConstant = 0;    //写入时,再另外多等待的时间。
125
126     SetCommTimeouts(hCom1, &comtimeout1);
127     j = ClearCommError(hCom1, &m_dwError, &comstat1);
128     s1.Format(_T("ClearCommError  j %d  errors %d "), j, m_dwError);
129     s2 = s1;
130     s1.Format(_T("cbInQue %d "), comstat1.cbInQue);
131     s2 += s1;
132     s1.Format(_T("cbOutQue %d "), comstat1.cbOutQue);
133     s2 += s1;
134     //PurgeComBuf();
135     ClearBuf();
136     m_bOpened = true;
137
138     //Start Read Thread
61deef 139     if (m_bUseWorkThread) {
Q 140         MyThreadProc1ToRun = 1;
141         AfxBeginThread(MyJumper1, (LPVOID)this);
142     }
418cb3 143
Q 144
145     return R_OK;
146 }
147
148 int HvSerialPort1::ClearStatData()
149 {
150     LastSendBytes = 0;
151     LastRecvBytes = 0;
152     SendBytes = 0;
153     RecvBytes = 0;
154     SendSpeed = 0;
155     RecvSpeed = 0;
156     return R_OK;
157 }
158
159 int HvSerialPort1::CalSpeed()
160 {
161     double thistime = GetTimemS();
162     double diftime = thistime - LastTime;
163     if (diftime >= 500)
164     {
165         SendSpeed = (DWORD)(SendBytes * 1000 / diftime);
166         RecvSpeed = static_cast<DWORD> (RecvBytes * 1000 / diftime);
167         LastSendBytes = SendBytes; SendBytes = 0;
168         LastRecvBytes = RecvBytes; RecvBytes = 0;
169         LastTime = thistime;
170     }
171     return 0;
172 }
173
174 int HvSerialPort1::Close()
175 {
176     // TODO: 在此处添加实现代码.
177     if (m_bOpened)
178     {
179         //    SendSign(STOP);
180         MyThreadProc1ToRun = 0;
181         Sleep(10);
182         // wait for Thread stop
183         //WaitForMultipleObjects(nCount);
184         // close port
185         CloseHandle(hCom1);
186         m_bOpened = 0;
187         hCom1 = INVALID_HANDLE_VALUE;
188         m_strResult.Format(_T("COM%d Closed"), m_nPort);
189         return R_OK;
190     }
191     else
192     {
193         m_strResult.Format(_T("COM%d not Opened"),m_nPort);
194         return R_ERR;
195     }
196 }
197
198 int HvSerialPort1::SetRecvDoneCallBack(pRecvDone pRecvDoneFunc)
199 {
200     // TODO: 在此处添加实现代码.
201     if (pRecvDoneFunc != NULL)
202     {
203         RecvDoneCB = pRecvDoneFunc;
204         m_bRecvDoneCBSet = 1;
205     }
206     else
207     {
208         RecvDoneCB = NULL;
209         m_bRecvDoneCBSet = 0;
210     }
211     return R_OK;
212 }
213
214 UINT HvSerialPort1::MyJumper1(LPVOID pParam)        //线程跳板
215 {
216     HvSerialPort1 *pInput = (HvSerialPort1 *)pParam;    //反跳到真正的执行程序
217     return pInput->MyThreadProc1(0);
218 }
219
220 DWORD WINAPI HvSerialPort1::MyThreadProc1(LPVOID pParam)
221 {
222     //串口接收数据函数
223
224     //接收到的数据 通知方式
225     // 1. windows消息队列
226     // 2. callback 函数  // 不同线程 
227     // 3. Event 
228     // 4. Buffer
229
230     OVERLAPPED osRead;
231     HANDLE hEventArr[2];
232     memset(&osRead, 0, sizeof(OVERLAPPED));
233     osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
234     SetCommMask(hCom1, EV_RXCHAR | EV_TXEMPTY);
235
236     hEventArr[0] = osRead.hEvent;
237     //    hEventArr[1] = *g_OutPutList.GetEvent();
238
239     CString s1, s2;
240     //    SysLog(_T("线程开始运行\r\n"));
241     MyThreadProc1Running = 1;
242
243     /*
244         static OVERLAPPED ovlap1, ovlap2;
245     */
246
247     //SysLog(_T("准备接收\r\n"));
248     DWORD    dNumtoRead = 1000;
249     dNumtoRead = 64;
250     //nDataToSend = 0;
251     DWORD wCount2 = 0;
252     DWORD dwSent = 0;
253     int nRunCount = 0;
254     //计算接收速度;
255
256     int LastSpeedTime = (int)GetTimemS();
257     int nThisRecv = 0;
258
259     COMSTAT cs;
260     OVERLAPPED os;
261     DWORD dwTrans;
262     DWORD dwReaded;
263     for (; MyThreadProc1ToRun == 1;)
264     {
265
266         DWORD dwEvtMask = 0;
267 ///*
268 //        BOOL result = WaitCommEvent(hCom1, &dwEvtMask, NULL); // &os);
269 //        if (!result)
270         {
271 //            if (GetLastError() == ERROR_IO_PENDING)
272 //            {
273 //                GetOverlappedResult(hCom1, &os, &dwTrans, true);
274
275 //            }
276 //            if (dwEvtMask & EV_RXCHAR)
61deef 277             //if (1) { Sleep(1); } else
418cb3 278             {
Q 279                 ClearCommError(hCom1, &m_dwError, &cs);
280                 int bytes = cs.cbInQue;
281                 dwReaded = 0;
282                 if (bytes > 0)
283                 {
284                     int j = ReadFile(hCom1, RecvBuf2, bytes, &dwReaded, NULL);
61deef 285                     if (j > 0 && dwReaded>0)
418cb3 286                     {
Q 287                         //m_CS1.Lock();
288                         EnterCriticalSection(&g_cs);
289                         memcpy(RecvBuf + RecvBufDataLen, RecvBuf2, dwReaded);
290                         RecvBufDataLen += dwReaded;
291                         //m_CS1.Unlock();
292                         LeaveCriticalSection(&g_cs);
293                     }
294                 }
295                 else
296                 {
297                     Sleep(1);
298                 }
299             }
300         }
301         if (RecvBufDataLen > 1024) { RecvBufDataLen = 0; }
302         //EscapeCommFunction(hCom1, SETDTR);
303 //*/        
304     }
305     //SysLog(_T("跳出接收循环\r\n"));
306     //    hcurDC.SelectObject(def_font); 
307 //    CloseHandle(hCom);
308     //SysLog(_T("线程结束运行\r\n\r\n"));
309     MyThreadProc1Running = 0;
310     return 0;
311 }
312
313 int HvSerialPort1::ClearBuf()
314 {
315     COMSTAT cs;
316     for (int i = 0; i < 100;i++)
317     {
318         ClearCommError(hCom1, &m_dwError, &cs);
319         int bytes = cs.cbInQue;
320         if (bytes > 0)
321         {
322             Sleep(10);
323         }
324         PurgeComm(hCom1, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
325         if (bytes == 0) break;
326     }
327
328     RecvBufDataLen = 0;
329     RecvBufPos = 0;
330     return 0;
331 }
332
333 int HvSerialPort1::Send(void * pBuf, int len1)
334 {
335     // TODO: 在此处添加实现代码.
336     CString s1;
337     int i, j;
338     DWORD numsent;
339
340     if (!m_bOpened) { return R_ERR; }
341
342     j = WriteFile(hCom1, pBuf, len1, &numsent, NULL);
343
344     if (j != 0)
345     {
346         m_strResult.Format(_T("Send To COM%d OK %dB : "), this->m_nPort, numsent);
347         for (i = 0; (unsigned)i < numsent; i++)
348         {
349             m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
350         }
351         m_strResult.AppendFormat(_T("\r\n"));
352     }
353     else
354     {
355         m_dwError = GetLastError();
356         m_strResult.Format(_T("Send To COM%d fail. Error:%d  SentBytes:%d "), this->m_nPort, m_dwError, numsent);
357     }
358     SendBytes += numsent;
359     TotalSendBytes += numsent;
360     return numsent;
361
362     return R_OK;
363 }
364 int HvSerialPort1::Recv(void * pBuf, int len1)
365 {
61deef 366     if (m_bUseWorkThread) {
Q 367         return RecvFromBuf(pBuf, len1);
368     }
369     else {
370         return RecvFromCom(pBuf, len1);
371     }
372     
418cb3 373 }
Q 374
375 int HvSerialPort1::RecvFromBuf(void * pBuf, int len1)
376 {
377     CString s1;
378     int i, j;
379     DWORD numreaded = 0;
380     int numtoread = len1;
381     m_strResult.Format(_T("ToRead %d "), len1);
382     for (i = 0; i < 20; i++)
383     {
384         int k;
385         //m_CS1.Lock();
386         EnterCriticalSection(&g_cs);
387         if (RecvBufDataLen)
388         {
389             if (RecvBufDataLen >= numtoread)
390             {
391                 memcpy((char *)pBuf+numreaded, RecvBuf, numtoread);
392                 numreaded += numtoread;
393                 RecvBufDataLen -= numtoread;
394                 numtoread = 0;
395                 memmove(RecvBuf, RecvBuf + numtoread, RecvBufDataLen);
396             }
397             else
398             {
399                 memcpy((char *)pBuf + numreaded, RecvBuf, RecvBufDataLen);
400                 numreaded += RecvBufDataLen;
401                 RecvBufDataLen = 0;
402                 RecvBufPos = 0;
403                 numtoread -= RecvBufDataLen;
404             }
405         }
406         //m_CS1.Unlock();
407         LeaveCriticalSection(&g_cs);
408         if (numtoread == 0) break;
409         Sleep(1);
410     }
411     if (numreaded > 0) {
412         m_strResult.AppendFormat(_T("Read From COM%d OK %dB "), this->m_nPort, numreaded);
413         for (i = 0; (unsigned)i < numreaded; i++)
414         {
415             m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
416         }
417         m_strResult.AppendFormat(_T("\r\n"));
418     }
419     else {
420         m_strResult.Format(_T("Read From COM%d failed \r\n"), this->m_nPort);
421     }
422     m_strResult.AppendFormat(_T("ToRun %d, Running %d"), MyThreadProc1ToRun, MyThreadProc1Running);
423     
424     return numreaded;
425 }
426 int HvSerialPort1::RecvFromCom(void * pBuf, int len1)
427 {
428     // TODO: 在此处添加实现代码.
429     CString s1;
430     int i, j;
431     DWORD numreaded;
432     if (!m_bOpened) { return R_ERR; }
433     int len2 = 0;
434     //Sleep(n/10);
435     int nTryCount2 = 0;
436     m_strResult.Format(_T("ToRead %d "), len1);
437     for (int i = 0; i < m_nCountToTry; i++)
438     {
439         numreaded = 0;
440         
441         j = ReadFile(hCom1, (char *)pBuf + len2, len1 - len2, &numreaded, NULL);
442         if (j != 0) {
443             len2 += numreaded;
444             ((char *)pBuf)[len2] = 0;
445             if (len2 >= len1) break;
446             nTryCount2 = 0;
447         }
448         else {
449             if (len2 > 0) {
450                 nTryCount2++;
451                 if (nTryCount2 > m_nCountToWait) break;
452             }
453         }
454         if (len2 > 0 && nTryCount2 > m_nCountToWait) break;
455     }
456     numreaded = len2;
457     if (numreaded > 0) {
458         m_strResult.AppendFormat(_T("Read From COM%d OK %dB "), this->m_nPort, numreaded);
459         for (i = 0; (unsigned)i < numreaded; i++)
460         {
461             m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
462         }
463         m_strResult.AppendFormat(_T("\r\n"));
464     }
465     else {
466         m_strResult.AppendFormat(_T("Read From COM%d failed \r\n"),this->m_nPort);
467     }
468
469     RecvBytes += numreaded;
470     TotalRecvBytes += numreaded;
471
472     return numreaded;
473     return R_OK;
474 }