1 /*
2 ********************************************************************************
3 * USB Hid Driver
4 *
5 * (c) Copyright 2006-2010, All winners Co,Ld.
6 * All Right Reserved
7 *
8 * FileName : UsbMouse_DriftControl.c
9 *
10 * Author : Javen
11 *
12 * Date : 2010.06.02
13 *
14 * Description : USB Mouse 去抖动算法.
15 * 1、所有鼠标事件信息添加到队列中
16 * 2、每隔5ms处理队列中的所事件有信息。
17 * 3、
18 *
19 * Others : NULL
20 *
21 * History:
22 * <time> <version > <author> <desc>
23 * 2010.07.16 1.0 Javen build this file
24 *
25 ********************************************************************************
26 */
27
28 //#include "usb_host_config.h"
29 //#include "usb_host_base_types.h"
30 #include "usb_os_platform.h"
31 #include "usb_host_common.h"
32 #include "error.h"
33 #include "HidSpec.h"
34 #include "Hid_i.h"
35 #include "HidFunDrv.h"
36 #include "UsbMouse.h"
37 #include "UsbMouse_DriftControl.h"
38
39 /*
40 *******************************************************************************
41 * UsbMouse_AddToDriftArray
42 *
43 * Description:
44 *
45 *
46 * Parameters:
47 *
48 *
49 * Return value:
50 *
51 *
52 * note:
53 *
54 *
55 *******************************************************************************
56 */
UsbMouse_DriftTimeOut(void * parg)57 static void UsbMouse_DriftTimeOut(void *parg)
58 {
59 UsbMouseDriftControl_t *Drift = (UsbMouseDriftControl_t *)parg;
60 unsigned int cup_sr = 0;
61
62 if(Drift == NULL){
63 hal_log_err("ERR: input error\n");
64 return ;
65 }
66
67 /* 如果有可疑的点存在,就把可疑的点发出去 */
68 if(Drift->WaitEvent && Drift->DubiousMouseEvent.vaild) {
69 int val = 0;
70 ENTER_CRITICAL(cup_sr);
71 DMSG_MOUSE_TEST("TimeOut: DubiousCoordinate = %x\n", Drift->DubiousCoordinate);
72 memcpy(&Drift->CurrentMouseEvent, &Drift->DubiousMouseEvent, sizeof(UsbMouseEventUnit_t));
73 Drift->CurrentMouseEvent.vaild = 1;
74 EXIT_CRITICAL(cup_sr);
75
76 // UsbThreadWakeUp(Drift->ThreadSemi);
77 if (!hal_sem_getvalue(Drift->ThreadSemi, &val))
78 {
79 hal_sem_post(Drift->ThreadSemi);
80 }
81 }
82
83 return;
84 }
85
86 /*
87 *******************************************************************************
88 * UsbMouse_IsButtonEvent
89 *
90 * Description:
91 *
92 *
93 * Parameters:
94 *
95 *
96 * Return value:
97 *
98 *
99 * note:
100 *
101 *
102 *******************************************************************************
103 */
UsbMouse_IsButtonEvent(USBHMouseEvent_t * MouseEvent)104 static unsigned int UsbMouse_IsButtonEvent(USBHMouseEvent_t *MouseEvent)
105 {
106 return (MouseEvent->Button.LeftButton
107 || MouseEvent->Button.RightButton
108 || MouseEvent->Button.MiddleButton
109 || MouseEvent->Wheel);
110 }
111
112 /*
113 *******************************************************************************
114 * UsbMouse_IsDubiousEvent
115 *
116 * Description:
117 *
118 *
119 * Parameters:
120 *
121 *
122 * Return value:
123 *
124 *
125 * note:
126 *
127 *
128 *******************************************************************************
129 */
UsbMouse_IsDubiousEvent(USBHMouseEvent_t * Event,UsbMouseDriftControl_t * Drift)130 static unsigned int UsbMouse_IsDubiousEvent(USBHMouseEvent_t *Event, UsbMouseDriftControl_t *Drift)
131 {
132 unsigned int Dubious = 0;
133
134 /* 如果参考点PreMouseEvent不存在, 那么就不用怀疑本次的点 */
135 if(Drift->PreMouseEvent.vaild == 0){
136 return 0;
137 }
138
139 /* 如果前后两次 X 坐标差值大于127, 那么就认为本次的坐标为可疑的坐标 */
140 if(absolute(Event->X - Drift->PreMouseEvent.MouseEvent.X) > USB_HID_MOUSE_DITHER_AREA){
141 usb_set_bit(1, (volatile uint32_t *)&Drift->DubiousCoordinate);
142 Dubious = 1;
143 }
144
145 /* 如果前后两次 Y 坐标差值大于127, 那么就认为本次的坐标为可疑的坐标 */
146 if(absolute(Event->Y - Drift->PreMouseEvent.MouseEvent.Y) > USB_HID_MOUSE_DITHER_AREA){
147 usb_set_bit(2, (volatile uint32_t *)&Drift->DubiousCoordinate);
148 Dubious = 1;
149 }
150
151 if(Dubious){
152 DMSG_MOUSE_TEST("DubiousCoordinate = %x\n", Drift->DubiousCoordinate);
153 }
154
155 return Dubious;
156 }
157
158 /* 判断X和Y是否都是正数或者是否都是负数 */
UsbMouse_IsAccord8(__s8 x,__s8 y)159 static __u32 UsbMouse_IsAccord8(__s8 x, __s8 y)
160 {
161 /* 是否都是负数 */
162 if(x <= 0 && y <= 0){
163 return 1;
164 }
165
166 /* 是否都是正数 */
167 if(x >= 0 && y >= 0){
168 return 1;
169 }
170
171 return 0;
172 }
173
174 /*
175 *******************************************************************************
176 * UsbMouse_AddToDriftArray
177 *
178 * Description:
179 * 从3个鼠标数据中找出轨迹相同的两个, 然后取平均值。
180 *
181 * Parameters:
182 *
183 *
184 * Return value:
185 *
186 *
187 * note:
188 *
189 *******************************************************************************
190 */
UsbMouse_AdjustCoordinate(USBHMouseEvent_t * Event1,USBHMouseEvent_t * Event2,USBHMouseEvent_t * Event3,USBHMouseEvent_t * OutEvent)191 static int UsbMouse_AdjustCoordinate(USBHMouseEvent_t *Event1,
192 USBHMouseEvent_t *Event2,
193 USBHMouseEvent_t *Event3,
194 USBHMouseEvent_t *OutEvent)
195 {
196 /* 寻找 X 坐标上方向一致的点 */
197 if(UsbMouse_IsAccord8(Event1->X, Event2->X)
198 && UsbMouse_IsAccord8(Event1->X, Event3->X)){ /* 1,2,3都一致 */
199 OutEvent->X = (Event1->X / 3) + (Event2->X / 3) + (Event3->X / 3);
200 }else if(UsbMouse_IsAccord8(Event1->X, Event2->X)){ /* 1,2都是一致的 */
201 OutEvent->X = Event2->X;
202 }else if(UsbMouse_IsAccord8(Event1->X, Event3->X)){ /* 1,3都是一致的 */
203 OutEvent->X = Event3->X;
204 }else if(UsbMouse_IsAccord8(Event2->X, Event3->X)){ /* 2,3都是一致的 */
205 OutEvent->X = (Event2->X / 2) + (Event3->X / 2);
206 }else{ /* 1,2,3都不是一致的 */
207 OutEvent->X = (Event1->X / 3) + (Event2->X / 3) + (Event3->X / 3);
208 }
209
210 /* 寻找 Y 坐标上方向一致的点 */
211 if(UsbMouse_IsAccord8(Event1->Y, Event2->Y)
212 && UsbMouse_IsAccord8(Event1->Y, Event3->Y)){ /* 1,2,3都一致 */
213 OutEvent->Y = (Event1->Y / 3) + (Event2->Y / 3) + (Event3->Y / 3);
214 }else if(UsbMouse_IsAccord8(Event1->Y, Event2->Y)){ /* 1,2都是一致的 */
215 OutEvent->Y = Event2->Y;
216 }else if(UsbMouse_IsAccord8(Event1->Y, Event3->Y)){ /* 1,3都是一致的 */
217 OutEvent->Y = Event3->Y;
218 }else if(UsbMouse_IsAccord8(Event2->Y, Event3->Y)){ /* 2,3都是一致的 */
219 OutEvent->Y = (Event2->Y / 2) + (Event3->Y / 2);
220 }else{ /* 1,2,3都不是一致的 */
221 OutEvent->Y = (Event1->Y / 3) + (Event2->Y / 3) + (Event3->Y / 3);
222 }
223
224 return 0;
225 }
226
227 /*
228 *******************************************************************************
229 * UsbMouse_AddToDriftArray
230 *
231 * Description:
232 *
233 *
234 * Parameters:
235 *
236 *
237 * Return value:
238 *
239 *
240 * note:
241 *
242 * 1、只有按键消息,直接发送给app。
243 *
244 * 2、只有wheel消息,直接发送给app。
245 *
246 * 3、只有坐标,就预测鼠标的轨迹,
247 * 如果本次的点A和上一次的点B相差太大,在规定时间内取下一次的点C作参考,
248 * 如果A和C相近,就丢掉B点,发送A点和C点给app;如果规定时间内没有鼠标事件,就把A点和B点给发给app。
249 *
250 * 4、如果按键、wheel、坐标参杂在一起,遇到按键或者wheel事件后,
251 * 把当前所有的点全部发给app,并且把下一次的按键抬起消息,也及时的发送出去。
252 *
253 *******************************************************************************
UsbMouse_AddToDriftArray(usbMouse_t * usbMouse,USBHMouseEvent_t * Event)254 */void UsbMouse_AddToDriftArray(usbMouse_t *usbMouse, USBHMouseEvent_t *Event)
255 {
256 int val = 0;
257 UsbMouseDriftControl_t *Drift = NULL;
258 unsigned int cup_sr = 0;
259
260 if(usbMouse == NULL){
261 hal_log_err("ERR: input error\n");
262 return ;
263 }
264
265 Drift = usbMouse->Extern;
266 if(Drift == NULL){
267 hal_log_err("ERR: Drift == NULL\n");
268 return ;
269 }
270
271 /* 先前有按键按下, 这里遇到抬起键, 就给把本次消息发送给APP */
272 if(Drift->ButtonDown){
273 /* 如果本次还有按键消息, 就记录下来 */
274 if(UsbMouse_IsButtonEvent(Event)){
275 DMSG_MOUSE_TEST("Had send a button down event, then a new button event come\n");
276 Drift->ButtonDown = 1;
277 }else{
278 DMSG_MOUSE_TEST("Had send a button down event, then wait for button rise\n");
279 Drift->ButtonDown = 0;
280 }
281
282 goto SendMsg;
283 }
284
285 /* 有按键事件或者滚轮事件,就唤醒线程 */
286 if(UsbMouse_IsButtonEvent(Event)){
287 DMSG_MOUSE_TEST("have a button event\n");
288
289 Drift->ButtonDown = 1;
290 goto SendMsg;
291 }
292
293 /* 如果PreMouseEvent和dubiousMouseEvent都有效, 那么就直接比较 */
294 if(Drift->PreMouseEvent.vaild && Drift->DubiousMouseEvent.vaild){
295 ENTER_CRITICAL(cup_sr);
296 DMSG_MOUSE_TEST("------Pre------\n");
297 DMSG_MOUSE_TEST("DubiousCoordinate = %x\n", Drift->DubiousCoordinate);
298
299 DMSG_MOUSE_TEST("Pre Button 1 = %d\n", Drift->PreMouseEvent.MouseEvent.Button.LeftButton);
300 DMSG_MOUSE_TEST("Pre Button 2 = %d\n", Drift->PreMouseEvent.MouseEvent.Button.RightButton);
301 DMSG_MOUSE_TEST("Pre Button 3 = %d\n", Drift->PreMouseEvent.MouseEvent.Button.MiddleButton);
302 DMSG_MOUSE_TEST("Pre Button 4 = %d\n", Drift->PreMouseEvent.MouseEvent.Button.Button4);
303 DMSG_MOUSE_TEST("Pre Button 5 = %d\n", Drift->PreMouseEvent.MouseEvent.Button.Button5);
304 DMSG_MOUSE_TEST("Pre Button 6 = %d\n", Drift->PreMouseEvent.MouseEvent.Button.Button6);
305 DMSG_MOUSE_TEST("Pre Button 7 = %d\n", Drift->PreMouseEvent.MouseEvent.Button.Button7);
306 DMSG_MOUSE_TEST("Pre Button 8 = %d\n", Drift->PreMouseEvent.MouseEvent.Button.Button8);
307
308 DMSG_MOUSE_TEST("Pre X = %d\n", Drift->PreMouseEvent.MouseEvent.X);
309 DMSG_MOUSE_TEST("Pre Y = %d\n", Drift->PreMouseEvent.MouseEvent.Y);
310 DMSG_MOUSE_TEST("Pre Wheel = %d\n", Drift->PreMouseEvent.MouseEvent.Wheel);
311 DMSG_MOUSE_TEST("\n");
312
313 DMSG_MOUSE_TEST("\n");
314 DMSG_MOUSE_TEST("dubious Button 1 = %d\n", Drift->DubiousMouseEvent.MouseEvent.Button.LeftButton);
315 DMSG_MOUSE_TEST("dubious Button 2 = %d\n", Drift->DubiousMouseEvent.MouseEvent.Button.RightButton);
316 DMSG_MOUSE_TEST("dubious Button 3 = %d\n", Drift->DubiousMouseEvent.MouseEvent.Button.MiddleButton);
317 DMSG_MOUSE_TEST("dubious Button 4 = %d\n", Drift->DubiousMouseEvent.MouseEvent.Button.Button4);
318 DMSG_MOUSE_TEST("dubious Button 5 = %d\n", Drift->DubiousMouseEvent.MouseEvent.Button.Button5);
319 DMSG_MOUSE_TEST("dubious Button 6 = %d\n", Drift->DubiousMouseEvent.MouseEvent.Button.Button6);
320 DMSG_MOUSE_TEST("dubious Button 7 = %d\n", Drift->DubiousMouseEvent.MouseEvent.Button.Button7);
321 DMSG_MOUSE_TEST("dubious Button 8 = %d\n", Drift->DubiousMouseEvent.MouseEvent.Button.Button8);
322
323 DMSG_MOUSE_TEST("dubious X = %d\n", Drift->DubiousMouseEvent.MouseEvent.X);
324 DMSG_MOUSE_TEST("dubious Y = %d\n", Drift->DubiousMouseEvent.MouseEvent.Y);
325 DMSG_MOUSE_TEST("dubious Wheel = %d\n", Drift->DubiousMouseEvent.MouseEvent.Wheel);
326 DMSG_MOUSE_TEST("\n");
327
328 DMSG_MOUSE_TEST("\n");
329 DMSG_MOUSE_TEST("Event Button 1 = %d\n", Event->Button.LeftButton);
330 DMSG_MOUSE_TEST("Event Button 2 = %d\n", Event->Button.RightButton);
331 DMSG_MOUSE_TEST("Event Button 3 = %d\n", Event->Button.MiddleButton);
332 DMSG_MOUSE_TEST("Event Button 4 = %d\n", Event->Button.Button4);
333 DMSG_MOUSE_TEST("Event Button 5 = %d\n", Event->Button.Button5);
334 DMSG_MOUSE_TEST("Event Button 6 = %d\n", Event->Button.Button6);
335 DMSG_MOUSE_TEST("Event Button 7 = %d\n", Event->Button.Button7);
336 DMSG_MOUSE_TEST("Event Button 8 = %d\n", Event->Button.Button8);
337
338 DMSG_MOUSE_TEST("Event X = %d\n", Event->X);
339 DMSG_MOUSE_TEST("Event Y = %d\n", Event->Y);
340 DMSG_MOUSE_TEST("Event Wheel = %d\n", Event->Wheel);
341 DMSG_MOUSE_TEST("------Pre------\n");
342
343 EXIT_CRITICAL(cup_sr);
344
345 /* 寻找同方向的两个点 */
346 /* X坐标可疑 */
347 UsbMouse_AdjustCoordinate(&Drift->PreMouseEvent.MouseEvent,
348 &Drift->DubiousMouseEvent.MouseEvent,
349 Event,
350 Event);
351
352 Drift->DubiousMouseEvent.vaild = 0;
353 Drift->PreMouseEvent.vaild = 0;
354
355 goto SendMsg;
356 }else{
357 /* 判断本次坐标是否可疑? */
358 if(UsbMouse_IsDubiousEvent(Event, Drift) == 0){
359 goto SendMsg;
360 }else{
361 hal_log_info("a Dubious event\n");
362
363 ENTER_CRITICAL(cup_sr);
364 memcpy(&Drift->DubiousMouseEvent.MouseEvent, Event, sizeof(USBHMouseEvent_t));
365 Drift->DubiousMouseEvent.vaild = 1;
366 Drift->WaitEvent = 1;
367 EXIT_CRITICAL(cup_sr);
368 }
369 }
370
371 return;
372
373 SendMsg:
374 ENTER_CRITICAL(cup_sr);
375 memcpy(&Drift->CurrentMouseEvent.MouseEvent, Event, sizeof(USBHMouseEvent_t));
376 Drift->CurrentMouseEvent.vaild = 1;
377 EXIT_CRITICAL(cup_sr);
378
379 // UsbThreadWakeUp(Drift->ThreadSemi);
380 if (!hal_sem_getvalue(Drift->ThreadSemi, &val))
381 {
382 hal_sem_post(Drift->ThreadSemi);
383 }
384 // UsbThreadSleep(Drift->notify_complete);
385 hal_sem_wait(Drift->notify_complete);
386
387 return;
388 }
389
390 /*
391 *******************************************************************************
392 * UsbMouse_DriftControl
393 *
394 * Description:
395 * 鼠标去抖动
396 *
397 * Parameters:
398 *
399 *
400 * Return value:
401 *
402 *
403 * note:
404 * 无
405 *
406 *******************************************************************************
407 */
UsbMouse_DriftControl(UsbMouseDriftControl_t * Drift)408 static int UsbMouse_DriftControl(UsbMouseDriftControl_t *Drift)
409 {
410 int val = 0;
411 unsigned int cup_sr = 0;
412
413 /* 清除等待标志 */
414 ENTER_CRITICAL(cup_sr);
415 Drift->WaitEvent = 0;
416 EXIT_CRITICAL(cup_sr);
417
418 /* sent mouse event to system */
419 if(Drift->CurrentMouseEvent.vaild){
420 ENTER_CRITICAL(cup_sr);
421
422 memcpy(&Drift->usbMouse->MouseEvent, &Drift->CurrentMouseEvent.MouseEvent, sizeof(USBHMouseEvent_t));
423 memcpy(&Drift->PreMouseEvent, &Drift->CurrentMouseEvent, sizeof(UsbMouseEventUnit_t));
424
425 Drift->PreMouseEvent.vaild = 1;
426 Drift->CurrentMouseEvent.vaild = 0;
427 Drift->DubiousMouseEvent.vaild = 0;
428
429 DMSG_MOUSE_TEST("\n");
430 DMSG_MOUSE_TEST("msg Button 1 = %d\n", Drift->usbMouse->MouseEvent.Button.LeftButton);
431 DMSG_MOUSE_TEST("msg Button 2 = %d\n", Drift->usbMouse->MouseEvent.Button.RightButton);
432 DMSG_MOUSE_TEST("msg Button 3 = %d\n", Drift->usbMouse->MouseEvent.Button.MiddleButton);
433 DMSG_MOUSE_TEST("msg Button 4 = %d\n", Drift->usbMouse->MouseEvent.Button.Button4);
434 DMSG_MOUSE_TEST("msg Button 5 = %d\n", Drift->usbMouse->MouseEvent.Button.Button5);
435 DMSG_MOUSE_TEST("msg Button 6 = %d\n", Drift->usbMouse->MouseEvent.Button.Button6);
436 DMSG_MOUSE_TEST("msg Button 7 = %d\n", Drift->usbMouse->MouseEvent.Button.Button7);
437 DMSG_MOUSE_TEST("msg Button 8 = %d\n", Drift->usbMouse->MouseEvent.Button.Button8);
438
439 DMSG_MOUSE_TEST("msg X = %d\n", Drift->usbMouse->MouseEvent.X);
440 DMSG_MOUSE_TEST("msg Y = %d\n", Drift->usbMouse->MouseEvent.Y);
441 DMSG_MOUSE_TEST("msg Wheel = %d\n", Drift->usbMouse->MouseEvent.Wheel);
442 DMSG_MOUSE_TEST("\n");
443
444 EXIT_CRITICAL(cup_sr);
445
446 if(Drift->usbMouse->CallBack){
447 esKRNL_CallBack((__pCBK_t)Drift->usbMouse->CallBack, (void *)&Drift->usbMouse->MouseEvent);
448 }
449 }
450
451 // UsbThreadWakeUp(Drift->notify_complete);
452 if (!hal_sem_getvalue(Drift->ThreadSemi, &val))
453 {
454 hal_sem_post(Drift->ThreadSemi);
455 }
456
457 return USB_ERR_SUCCESS;
458 }
459
460 /*
461 *******************************************************************************
462 * UsbMouse_DriftThread
463 *
464 * Description:
465 *
466 *
467 * Parameters:
468 *
469 *
470 * Return value:
471 *
472 *
473 * note:
474 * 无
475 *
476 *******************************************************************************
477 */
UsbMouse_DriftThread(void * p_arg)478 static void UsbMouse_DriftThread(void *p_arg)
479 {
480 UsbMouseDriftControl_t *Drift = (UsbMouseDriftControl_t *)p_arg;
481
482 if(Drift == NULL){
483 hal_log_err("ERR: input error\n");
484 return ;
485 }
486
487
488 hal_sem_post(Drift->notify_complete);
489
490 while(1){
491 //--<1>--杀死线程
492 // TryToKillThreadSelf("UsbMouse_DriftThread");
493
494 // /* sleep */
495 // UsbThreadSleep(Drift->ThreadSemi);
496 kthread_stop(Drift->ThreadId);
497 hal_sem_wait(Drift->ThreadSemi);
498
499 UsbMouse_DriftControl(Drift);
500 }
501 }
502
503 /*
504 *******************************************************************************
505 * UsbMouse_DriftControl_Init
506 *
507 * Description:
508 *
509 *
510 * Parameters:
511 *
512 *
513 * Return value:
514 *
515 *
516 * note:
517 *
518 *
519 *******************************************************************************
520 */
UsbMouse_DriftControl_Init(usbMouse_t * usbMouse)521 int UsbMouse_DriftControl_Init(usbMouse_t *usbMouse)
522 {
523 int status = 0;
524 UsbMouseDriftControl_t *Drift;
525 unsigned int err = 0;
526
527 Drift = hal_malloc(sizeof(UsbMouseDriftControl_t));
528 if(Drift == NULL){
529 hal_log_err("ERR: hal_malloc failed\n");
530 return USB_ERR_MALLOC_FAILED;
531 }
532
533 memset(Drift, 0, sizeof(UsbMouseDriftControl_t));
534
535 /* create thread */
536 Drift->ThreadSemi = hal_sem_create(0);
537 if(Drift->ThreadSemi == NULL){
538 hal_log_err("ERR: USB_OS_SemCreate ThreadSemi failed\n");
539 status = USB_ERR_CREATE_SIME_FAILED;
540 goto err0;
541 }
542
543 Drift->notify_complete = hal_sem_create(0);
544 if(Drift->notify_complete == NULL){
545 hal_log_err("ERR: USB_OS_SemCreate notify_complete failed\n");
546 status = USB_ERR_CREATE_SIME_FAILED;
547 goto err1;
548 }
549
550 /* Mouse Drift thread */
551 Drift->ThreadId = kthread_create((void *)UsbMouse_DriftThread,
552 (void *)Drift,
553 "UsbMouse_DriftThread");
554 if(Drift->ThreadId == OS_NO_ERR){
555 hal_log_err("ERR: create MainThreadId failed\n");
556 status = USB_ERR_CREATE_THREAD_FAILED;
557 goto err2;
558 }
559
560 hal_sem_wait(Drift->notify_complete);
561
562 /* create timer */
563 Drift->TimerHdle = osal_timer_create("UsbMouse_DriftControl", UsbMouse_DriftTimeOut, (void*)Drift,
564 400, OSAL_TIMER_FLAG_PERIODIC);
565
566 if(Drift->TimerHdle == NULL){
567 hal_log_err("ERR: create timer failed\n");
568 status = USB_ERR_CREATE_TIMER_FAILED;
569 goto err3;
570 }
571
572 osal_timer_start(Drift->TimerHdle);
573
574 /* */
575 Drift->usbMouse = usbMouse;
576 usbMouse->Extern = Drift;
577
578 return USB_ERR_SUCCESS;
579
580
581 err3:
582 // UsbKillThread(Drift->ThreadId, NULL);
583 kthread_stop(Drift->ThreadId);
584 err2:
585 hal_sem_delete(Drift->notify_complete);
586 Drift->notify_complete = NULL;
587
588 err1:
589 hal_sem_delete(Drift->ThreadSemi);
590 Drift->ThreadSemi = NULL;
591
592 err0:
593 hal_free(Drift);
594
595 return status;
596 }
597
598 /*
599 *******************************************************************************
600 * UsbMouse_DriftControl_Exit
601 *
602 * Description:
603 *
604 *
605 * Parameters:
606 *
607 *
608 * Return value:
609 *
610 *
611 * note:
612 *
613 *
614 *******************************************************************************
615 */
UsbMouse_DriftControl_Exit(usbMouse_t * usbMouse)616 int UsbMouse_DriftControl_Exit(usbMouse_t *usbMouse)
617 {
618 UsbMouseDriftControl_t *Drift = NULL;
619 unsigned int err = 0;
620
621 if(usbMouse == NULL){
622 hal_log_err("ERR: input error\n");
623 return USB_ERR_BAD_ARGUMENTS;
624 }
625
626 Drift = usbMouse->Extern;
627 if(Drift == NULL){
628 hal_log_err("ERR: Drift == NULL\n");
629 return USB_ERR_BAD_ARGUMENTS;
630 }
631
632 /* stop and kill timer */
633 osal_timer_stop(Drift->TimerHdle);
634 osal_timer_delete(Drift->TimerHdle);
635 Drift->TimerHdle = NULL;
636
637 /* kill thread */
638 // UsbKillThread(Drift->ThreadId, Drift->ThreadSemi);
639 kthread_stop(Drift->ThreadId);
640
641 hal_sem_delete(Drift->ThreadSemi);
642 Drift->ThreadSemi = NULL;
643
644 hal_sem_delete(Drift->notify_complete);
645 Drift->notify_complete = NULL;
646
647 usbMouse->Extern = NULL;
648 hal_free(Drift);
649
650 return USB_ERR_SUCCESS;
651 }
652
653