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

 

 

 

转载于:https://www.cnblogs.com/wenziqi/archive/2010/07/01/1769174.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值