CH372 USB内置固件类的编写

 

    使用CH372 USB芯片进行USB数据通信时,CH372默认有2种模式,一种是内置固件模式,另外一种是外置固件模式。当设置CH372为内置固件模式时,上位机界面需要调用该USB芯片公司提供的dll,为了使用上的方便,本人将基本的收发数据的功能封装成类库,方便以后调用。

    该类库有两个文件,分别是CCH37x.cpp和CCH37x.h。

 

CCH37x.h代码如下:

1 /***************************************************
2 *作 者:温子祺
3 *联系方式:wenziqi@hotmail.com
4 *说 明:CCH37x.cpp
5 提供外部调用的函数
6 Open(),Close(),
7 EP1Send(),EP1Recv(),
8 EP2Send(),EP2Recv(),
9 EP1和EP2接收数据时通过消息来实现
10 ***************************************************/
11 #ifndef __CCH37X_H__
12  #define __CCH37X_H__
13  #pragma once
14
15 #include "CH375DLL.H" // CH372/CH375的动态链接库
16  #pragma comment(lib,"CH375DLL") //隐式调用库文件
17
18
19  #define USB_INSERT 1
20  #define USB_DRAW 2
21
22  #define EP1_RX 1
23 #define EP2_RX 2
24
25 class CCH37x
26 {
27 public:
28
29 CCH37x();
30 virtual ~CCH37x();
31
32 BOOL Close(void);
33 BOOL Open (CWnd *pPortOwner,
34 ULONG ulIndex,
35 UINT unEP1RecvSize,
36 UINT unEP2RecvSize,
37 UINT unWriteTimeouts,
38 UINT unReadTimeouts,
39 UINT unEP1RecvMsg,
40 UINT unEP2RecvMsg,
41 UINT unConnectMsg);
42
43 UINT EP1Send(UCHAR *pSendBytes,UINT unSendLen);//端点1:向USB发送数据
44 UINT EP1Recv(UCHAR *pRecvBytes); //端点1:从USB接收数据
45
46 UINT EP2Send(UCHAR *pSendBytes,UINT unSendLen);//端点2:向USB发送数据
47 UINT EP2Recv(UCHAR *pRecvBytes); //端点2:从USB接收数据
48
49
50
51 protected:
52
53 BOOL Ready(void)const; //USB是否已经打开
54 BOOL SetTimeout(UINT unWriteTimeouts,
55 UINT unReadTimeouts); //设置超时
56
57 void SetCurIndex(ULONG ulIndex); //设置当前索引号
58 ULONG GetCurIndex(void) const; //获取当前索引号
59
60 BOOL CreateThreadAndEvent(void); //创建线程和事件
61 static
62 DWORD EP1RecvThread(LPVOID lpArg); //接收线程
63 static
64 DWORD EP2RecvThread(LPVOID lpArg); //接收线程
65
66 private:
67
68 CWnd * m_pOwner;
69 BOOL m_bInit;
70 ULONG m_ulIndex;
71
72 HANDLE m_hUsbEP1Down; //端点1下传设备打开句柄
73 HANDLE m_hUsbEP1Up; //端点1上传设备打开句柄
74 HANDLE m_hUsbEP2Down; //端点2下传设备打开句柄
75 HANDLE m_hUsbEP2Up; //端点2上传设备打开句柄
76 HANDLE m_hEP1RecvExitEvent;
77 HANDLE m_hEP2RecvExitEvent;
78
79 UCHAR *m_szEP1RecvBuf;
80 UINT m_unEP1RecvSize;
81 UCHAR *m_szEP2RecvBuf;
82 UINT m_unEP2RecvSize;
83
84 UINT m_unEP1RecvMsg;
85 UINT m_unEP2RecvMsg;
86
87 UINT m_unEP1CurRecvLength;
88 UINT m_unEP2CurRecvLength;
89 };
90
91 #endif

 

CCH37x.cpp代码如下:

 

1 /***************************************************
2 *作 者:温子祺
3 *联系方式:wenziqi@hotmail.com
4 *说 明:CCH37x.cpp
5 提供外部调用的函数
6 Open(),Close(),
7 EP1Send(),EP1Recv(),
8 EP2Send(),EP2Recv(),
9 EP1和EP2接收数据时通过消息来实现
10 ***************************************************/
11 #include "StdAfx.h"
12 #include "CCH37x.h"
13 #include <assert.h> //使用断言
14
15 UINT g_unConnectMsg=0;
16 CWnd *g_Wnd=NULL;
17
18
19 /**************************************************************************************************
20 ** 函数名称: CH375NOTIFYROUTINE
21 ** 功能描述: 回调函数(检测USB插入与拔出)
22 ** 输 入: iEventStatus-事件状态
23 ** 输 出: 无
24 ** 注 意: 设备事件通知回调程序,在此程序里不宜作过多的操作,主要是因为中断服务程序优先级高,
25 不宜进行USB传输,通常只是发个消息或者置个全局变量通知主程序处理
26 ***************************************************************************************************/
27 VOID CALLBACK CH375NOTIFYROUTINE(ULONG iEventStatus)
28 {
29
30 if(iEventStatus==CH375_DEVICE_ARRIVAL)//检测到设备插入事件
31 {
32
33 ::SendMessage(g_Wnd->m_hWnd,g_unConnectMsg,(WPARAM)USB_INSERT,0);
34 }
35
36 if (iEventStatus==CH375_DEVICE_REMOVE)
37 {
38 ::SendMessage(g_Wnd->m_hWnd,g_unConnectMsg,(WPARAM)USB_DRAW,0);
39 }
40
41 }
42
43 CCH37x::CCH37x(void)
44 {
45 m_bInit =FALSE;
46 m_ulIndex =0;
47 m_hUsbEP1Down=INVALID_HANDLE_VALUE;
48 m_hUsbEP1Up =INVALID_HANDLE_VALUE;
49 m_hUsbEP2Down=INVALID_HANDLE_VALUE;
50 m_hUsbEP2Up =INVALID_HANDLE_VALUE;
51 m_hEP1RecvExitEvent=NULL;
52 m_hEP2RecvExitEvent=NULL;
53 m_szEP1RecvBuf=NULL;
54 m_szEP2RecvBuf=NULL;
55 m_pOwner=NULL;
56 }
57
58 CCH37x::~CCH37x(void)
59 {
60 m_bInit =FALSE;
61 m_ulIndex =0;
62 m_hUsbEP1Down=INVALID_HANDLE_VALUE;
63 m_hUsbEP1Up =INVALID_HANDLE_VALUE;
64 m_hUsbEP2Down=INVALID_HANDLE_VALUE;
65 m_hUsbEP2Up =INVALID_HANDLE_VALUE;
66 m_hEP1RecvExitEvent=NULL;
67 m_hEP2RecvExitEvent=NULL;
68 m_szEP1RecvBuf=NULL;
69 m_szEP2RecvBuf=NULL;
70 m_pOwner=NULL;
71
72 }
73
74 BOOL CCH37x::Ready(void) const
75 {
76 return m_bInit;
77 }
78
79
80 BOOL CCH37x::Close(void)
81 {
82 ULONG ulindex=0;
83
84 ulindex=GetCurIndex();
85
86 m_bInit=FALSE;
87
88 if (m_hUsbEP2Up!= INVALID_HANDLE_VALUE)
89 {
90 CH375AbortRead(ulindex);
91 }
92
93 if (m_hUsbEP2Down!= INVALID_HANDLE_VALUE)
94 {
95 CH375AbortWrite(ulindex);
96
97 }
98
99 if (m_hUsbEP1Up!= INVALID_HANDLE_VALUE)
100 {
101 CH375AbortInter(ulindex);
102 }
103
104 if (m_hEP1RecvExitEvent)
105 {
106 SetEvent(m_hEP1RecvExitEvent); //退出线程
107 Sleep(10);
108 CloseHandle(m_hEP1RecvExitEvent);
109 m_hEP1RecvExitEvent=NULL;
110 }
111
112 if (m_hEP2RecvExitEvent)
113 {
114 SetEvent(m_hEP2RecvExitEvent); //退出线程
115 Sleep(10);
116 CloseHandle(m_hEP2RecvExitEvent);
117 m_hEP2RecvExitEvent=NULL;
118 }
119
120
121 if (m_hUsbEP2Up!= INVALID_HANDLE_VALUE)
122 {
123
124 CloseHandle(m_hUsbEP2Up);
125 m_hUsbEP2Up=INVALID_HANDLE_VALUE;
126 }
127
128 if (m_hUsbEP2Down!= INVALID_HANDLE_VALUE)
129 {
130
131 CloseHandle(m_hUsbEP2Down);
132 m_hUsbEP2Down=INVALID_HANDLE_VALUE;
133 }
134
135 if (m_hUsbEP1Up!= INVALID_HANDLE_VALUE)
136 {
137
138 CloseHandle(m_hUsbEP1Up);
139 m_hUsbEP1Up=INVALID_HANDLE_VALUE;
140 }
141
142 if (m_hUsbEP1Down!= INVALID_HANDLE_VALUE)
143 {
144 CloseHandle(m_hUsbEP1Down);
145 m_hUsbEP1Down=INVALID_HANDLE_VALUE;
146 }
147
148 if (m_szEP1RecvBuf)
149 {
150 delete []m_szEP1RecvBuf;
151 m_szEP1RecvBuf=NULL;
152 }
153
154 if (m_szEP2RecvBuf)
155 {
156 delete []m_szEP2RecvBuf;
157 m_szEP2RecvBuf=NULL;
158 }
159
160
161
162 if (m_pOwner)
163 {
164 m_pOwner=NULL;
165 }
166
167 CH375CloseDevice(ulindex);//Dll有Bug
168
169
170 return TRUE;
171 }
172
173
174 BOOL CCH37x::Open(CWnd *pPortOwner,
175 ULONG ulIndex,
176 UINT unEP1RecvSize,
177 UINT unEP2RecvSize,
178 UINT unWriteTimeouts,
179 UINT unReadTimeouts,
180 UINT unEP1RecvMsg,
181 UINT unEP2RecvMsg,
182 UINT unConnectMsg)
183 {
184 assert(NULL != pPortOwner);
185
186 g_Wnd=m_pOwner = pPortOwner;
187
188 if (Ready())
189 {
190 Close();
191 }
192
193 if (!m_szEP1RecvBuf)
194 {
195 m_unEP1RecvSize=unEP1RecvSize;
196 m_szEP1RecvBuf=new UCHAR[unEP1RecvSize];
197 }
198
199 if (!m_szEP2RecvBuf)
200 {
201 m_unEP2RecvSize=unEP2RecvSize;
202 m_szEP2RecvBuf=new UCHAR[unEP2RecvSize];
203 }
204
205 HANDLE hUsbDev=NULL;
206
207 SetCurIndex(ulIndex);
208
209 hUsbDev=CH375OpenDevice(ulIndex);
210
211 if (hUsbDev==INVALID_HANDLE_VALUE)
212 {
213 return FALSE;
214 }
215
216 CH375SetTimeout(ulIndex,unWriteTimeouts,unReadTimeouts);
217
218 WCHAR *wcdevName=new WCHAR[256];
219
220 MultiByteToWideChar(CP_ACP,
221 0,
222 (LPSTR)CH375GetDeviceName(ulIndex),
223 256, //不能够用sizeof
224 wcdevName,
225 256);
226
227 m_hUsbEP1Up=CreateFile((LPCWSTR)&wcdevName[0], //打开USB端点1上传句柄
228 GENERIC_READ | GENERIC_WRITE,
229 FILE_SHARE_READ | FILE_SHARE_WRITE,
230 NULL,
231 OPEN_EXISTING,
232 FILE_ATTRIBUTE_NORMAL,
233 NULL);
234
235 m_hUsbEP1Down=CreateFile((LPCWSTR)&wcdevName[0], //打开USB端点2下传句柄
236 GENERIC_READ | GENERIC_WRITE,
237 FILE_SHARE_READ | FILE_SHARE_WRITE,
238 NULL,
239 OPEN_EXISTING,
240 FILE_ATTRIBUTE_NORMAL,
241 NULL);
242
243
244
245 m_hUsbEP2Up=CreateFile((LPCWSTR)&wcdevName[0], //打开USB端点2上传句柄
246 GENERIC_READ | GENERIC_WRITE,
247 FILE_SHARE_READ | FILE_SHARE_WRITE,
248 NULL,
249 OPEN_EXISTING,
250 FILE_ATTRIBUTE_NORMAL,
251 NULL);
252
253 m_hUsbEP2Down=CreateFile((LPCWSTR)&wcdevName[0], //打开USB端点2下传句柄
254 GENERIC_READ | GENERIC_WRITE,
255 FILE_SHARE_READ | FILE_SHARE_WRITE,
256 NULL,
257 OPEN_EXISTING,
258 FILE_ATTRIBUTE_NORMAL,
259 NULL);
260
261 delete []wcdevName;
262
263 if (INVALID_HANDLE_VALUE==m_hUsbEP1Up || INVALID_HANDLE_VALUE==m_hUsbEP1Down\
264 ||INVALID_HANDLE_VALUE==m_hUsbEP2Up || INVALID_HANDLE_VALUE==m_hUsbEP2Down)
265 {
266 return FALSE;
267 }
268
269 if (!CreateThreadAndEvent())
270 {
271 return FALSE;
272 }
273
274 m_unEP1RecvMsg=unEP1RecvMsg;
275 m_unEP2RecvMsg=unEP2RecvMsg;
276
277 g_unConnectMsg=unConnectMsg;
278
279 CH375SetDeviceNotify(ulIndex,NULL,CH375NOTIFYROUTINE);
280
281 m_bInit=TRUE;
282
283 return TRUE;
284 }
285
286 UINT CCH37x::EP1Send(UCHAR *pSendBytes,UINT unSendLen)
287 {
288 if (!Ready())
289 {
290 return 0;
291 }
292
293 if (NULL == pSendBytes || 0==unSendLen)
294 {
295 return 0;
296 }
297
298 if (unSendLen>8)
299 {
300 unSendLen=8;
301 }
302
303 if (!(CH375WriteAuxData((ULONG)m_hUsbEP1Down,pSendBytes,(PULONG)&unSendLen)))
304 {
305 return 0;
306 }
307
308 return unSendLen;
309 }
310
311 UINT CCH37x::EP2Send(UCHAR *pSendBytes,UINT unSendLen)
312 {
313 if (!Ready())
314 {
315 return 0;
316 }
317
318 if (NULL == pSendBytes || 0==unSendLen)
319 {
320 return 0;
321 }
322
323 if (!(CH375WriteData((ULONG)m_hUsbEP2Down,pSendBytes,(PULONG)&unSendLen)))
324 {
325 return 0;
326 }
327
328 return unSendLen;
329 }
330
331 BOOL CCH37x::CreateThreadAndEvent(void)
332 {
333 m_hEP1RecvExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* 创建串口接收线程退出事件*/
334
335 if (NULL==m_hEP1RecvExitEvent)
336 {
337 return FALSE;
338 }
339
340 ResetEvent(m_hEP1RecvExitEvent); //设置线程没有退出
341
342 m_hEP2RecvExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* 创建串口接收线程退出事件*/
343
344 if (NULL==m_hEP2RecvExitEvent)
345 {
346 return FALSE;
347 }
348
349 ResetEvent(m_hEP2RecvExitEvent);
350
351
352 HANDLE hRecvThread=NULL;
353 DWORD dwThreadID =0;
354
355 Sleep(2);
356
357 // 创建串口接收线程
358 hRecvThread=CreateThread(0,
359 0,
360 (LPTHREAD_START_ROUTINE)EP1RecvThread,
361 this,
362 0,
363 &dwThreadID);
364
365 if (NULL==hRecvThread)
366 {
367 return FALSE;
368 }
369
370 // 创建串口接收线程
371 hRecvThread=CreateThread(0,
372 0,
373 (LPTHREAD_START_ROUTINE)EP2RecvThread,
374 this,
375 0,
376 &dwThreadID);
377
378 if (NULL==hRecvThread)
379 {
380 return FALSE;
381 }
382 CloseHandle(hRecvThread);
383 hRecvThread=NULL;
384
385 return TRUE;
386 }
387 DWORD CCH37x::EP1RecvThread(LPVOID lpArg)
388 {
389 assert(NULL != lpArg);
390
391 CCH37x *pArg=(CCH37x *)lpArg;
392
393 assert(NULL != pArg);
394
395 ULONG len=0;
396
397
398 UCHAR *szRecvBuf=new UCHAR[pArg->m_unEP1RecvSize];
399
400 while (1)
401 {
402 if (WaitForSingleObject(pArg->m_hEP1RecvExitEvent,0)==WAIT_OBJECT_0)
403 {
404 break; //线程退出
405 }
406
407 if (pArg->Ready())
408 {
409 //memset(szRecvBuf,0,pArg->m_unEP1RecvSize);
410
411 len =pArg->m_unEP1RecvSize;
412
413 if (CH375ReadInter((ULONG)(pArg->m_hUsbEP1Up),&szRecvBuf[0],&len))//该函数是阻塞的
414 {
415 if (len && pArg->m_szEP1RecvBuf)
416 {
417 memset(pArg->m_szEP1RecvBuf,0,pArg->m_unEP1RecvSize);
418 memcpy(pArg->m_szEP1RecvBuf,szRecvBuf,len);
419 pArg->m_unEP1CurRecvLength=len;
420
421 ::SendMessage((pArg->m_pOwner)->m_hWnd,
422 pArg->m_unEP1RecvMsg,
423 (WPARAM)EP1_RX,
424 0);
425 }
426
427
428 }
429
430 }
431 }
432
433 delete []szRecvBuf;
434
435 Sleep(10); //让线程安全退出
436
437 return 0;
438 }
439
440 DWORD CCH37x::EP2RecvThread(LPVOID lpArg)
441 {
442 assert(NULL != lpArg);
443
444 CCH37x *pArg=(CCH37x *)lpArg;
445
446 assert(NULL != pArg);
447
448 ULONG len=0;
449
450
451 UCHAR *szRecvBuf=new UCHAR[pArg->m_unEP2RecvSize];
452 UINT RxStat=0;
453
454 while (1)
455 {
456 if (WaitForSingleObject(pArg->m_hEP2RecvExitEvent,0)==WAIT_OBJECT_0)
457 {
458 break; //线程退出
459 }
460
461 if (pArg->Ready())
462 {
463
464 //memset(szRecvBuf,0,pArg->m_unEP2RecvSize);
465
466 len =pArg->m_unEP2RecvSize;
467
468 if (CH375ReadData((ULONG)(pArg->m_hUsbEP2Up),&szRecvBuf[0],&len))
469 {
470 if (len && pArg->m_szEP2RecvBuf)
471 {
472 memset(pArg->m_szEP2RecvBuf,0,pArg->m_unEP2RecvSize);
473 memcpy(pArg->m_szEP2RecvBuf,szRecvBuf,len);
474 RxStat|=EP2_RX;
475 pArg->m_unEP2CurRecvLength=len;
476
477 ::SendMessage((pArg->m_pOwner)->m_hWnd,
478 pArg->m_unEP2RecvMsg,
479 (WPARAM)EP2_RX,
480 0);
481 }
482
483 }
484
485 }
486
487 Sleep(1);
488
489
490 }
491
492 delete []szRecvBuf;
493
494 Sleep(10); //让线程安全退出
495
496 return 0;
497 }
498
499 UINT CCH37x::EP1Recv(UCHAR *pRecvBytes)
500 {
501 if (!Ready())
502 {
503 return 0;
504 }
505
506 memcpy(pRecvBytes,m_szEP1RecvBuf,m_unEP1RecvSize);
507
508 return m_unEP1CurRecvLength;
509
510 }
511
512 UINT CCH37x::EP2Recv(UCHAR *pRecvBytes)
513 {
514 if (!Ready())
515 {
516 return 0;
517 }
518
519 memcpy(pRecvBytes,m_szEP2RecvBuf,m_unEP2RecvSize);
520
521 return m_unEP2CurRecvLength;
522 }
523
524 void CCH37x::SetCurIndex(ULONG ulIndex)
525 {
526 m_ulIndex=ulIndex;
527 }
528
529 ULONG CCH37x::GetCurIndex() const
530 {
531 return m_ulIndex;
532 }
533

 

 

 

posted @ 2010-07-01 15:10  温子祺  阅读(4999)  评论(2编辑  收藏  举报