google ADK bt test on MQX
[adk-bluetooth-test.git] / adk-stack / transport / usb / usbhci.c
blob9cb6d2738e0ec8b27dd20fc3c922f463cdcc8305
1 /* usb bt dongle hci driver */
3 #include "usbh.h"
5 #include "usbhci.h"
7 #include "usbdrv.h"
9 #ifdef DEBUG_COMPLETE_PKT_NUM
10 unsigned int complete_packets_num = 0;
11 #endif
13 #ifdef USE_WRITE_PACKET_BUFFER
14 static inline int ring_buffer_lock(ring_buffer_t * rbuff)
16 return OS_Mutex_lock(rbuff->r_lock);
19 static inline int ring_buffer_unlock(ring_buffer_t * rbuff)
21 return OS_Mutex_unlock(rbuff->r_lock);
24 static inline void ring_buff_zero(ring_buffer_t * rbuff)
26 rbuff->free_space = RING_BUFFER_END;
27 rbuff->buffer = NULL;
28 rbuff->idx_current = 0;
29 rbuff->packets = 0;
30 rbuff->next_desc = 0;
31 rbuff->last_returned_desc = 0;
32 rbuff->idx_complete = 0;
33 rbuff->r_lock = NULL;
34 #if 1
35 for(unsigned int i=0; i<MAX_ASYNC_PACKETS; i++) {
36 rbuff->desc[i].returned = TRUE;
37 rbuff->desc[i].idx_start = 0xFFFFFFFF;
39 #endif
41 #endif
43 static inline int ring_buff_init(ring_buffer_t * rbuff)
45 #ifdef USE_WRITE_PACKET_BUFFER
46 ring_buff_zero(rbuff);
47 if (! rbuff->buffer) {
48 rbuff->buffer = os_mem_alloc(RING_BUFFER_SIZE);
49 if (! rbuff->buffer) {
50 return -1;
54 if((rbuff->r_lock = OS_Mutex_create()) == NULL)
55 return -1;
56 #endif
57 return 0;
60 static inline void ring_buff_deinit(ring_buffer_t * rbuff)
62 #ifdef USE_WRITE_PACKET_BUFFER
63 if(rbuff->r_lock)
64 OS_Mutex_destroy(rbuff->r_lock);
66 os_mem_free(rbuff->buffer);
67 rbuff->buffer = NULL;
68 #endif
71 static inline usb_write_packet_t * rbuff_get_write_packet(ring_buffer_t * rbuff,unsigned int len, unsigned int * /* start_idx*/idx_start)
73 usb_write_packet_t* p_packet = NULL;
74 #ifdef USE_WRITE_PACKET_BUFFER
75 ring_buffer_lock(rbuff);
77 if (rbuff->free_space < len) {
78 // No space left in ring buffer
79 goto exit;
82 if (rbuff->packets >= MAX_ASYNC_PACKETS) {
83 // Out of packet descriptors
84 goto exit;
87 if (len > MAX_ASYNC_PACKET_SIZE) {
88 // Packet is too large
89 goto exit;
92 ASSERT(rbuff->desc[rbuff->next_desc].returned);
93 rbuff->desc[rbuff->next_desc].returned = FALSE;
94 rbuff->desc[rbuff->next_desc].idx_start = rbuff->idx_current;
95 rbuff->desc[rbuff->next_desc].total_len = len;
96 //rbuff->desc[rbuff->next_desc].packet.h_transfer = NULL;
97 os_mem_zero(&(rbuff->desc[rbuff->next_desc].packet.h_transfer),sizeof(tr_user_t));
99 *idx_start = rbuff->idx_current;
101 // get packet
102 p_packet = & rbuff->desc[rbuff->next_desc].packet;
103 p_packet->buffer = &rbuff->buffer[rbuff->idx_current];
105 rbuff->free_space -= len;
106 rbuff->idx_current += len;
107 if (rbuff->idx_current > RING_BUFFER_END) {
108 rbuff->free_space += rbuff->idx_current - RING_BUFFER_END; // recalculate free space
109 rbuff->idx_current = 0; // wrap around
112 rbuff->packets++;
113 rbuff->next_desc = (rbuff->next_desc + 1) % MAX_ASYNC_PACKETS;
114 exit:
115 ring_buffer_unlock(rbuff);
116 #endif
117 return p_packet;
120 static inline void rbuff_signal_complete(ring_buffer_t * rbuff,unsigned int idx_start,OS_Event_handle dev_wr_event)
122 #ifdef USE_WRITE_PACKET_BUFFER
124 ring_buffer_lock(rbuff);
126 rbuff->complete[rbuff->idx_complete] = idx_start;
127 rbuff->idx_complete++;
129 OS_Event_set(/*((USB_DEVICE_STRUCT_PTR)usb_pdev)->usbdev_event*/dev_wr_event, WRITEN_EVENT_MASK);
130 ring_buffer_unlock(rbuff);
131 #endif
134 static inline int rbuff_complete_packet(ring_buffer_t * rbuff,unsigned int idx_start, tr_user_t * * ph_transfer)
136 int ret = 0;
137 #ifdef USE_WRITE_PACKET_BUFFER
138 ring_buffer_lock(rbuff);
140 int i = rbuff->last_returned_desc;
141 unsigned int count = 0;
142 while ((count < rbuff->packets) && (rbuff->desc[i].idx_start != idx_start)) {
143 count++;
144 i++;
146 if (i == MAX_ASYNC_PACKETS) {
147 i = 0;
151 if (count == rbuff->packets) {
152 ret = -1; // not found
153 ASSERT(FALSE);
154 goto exit;
157 rbuff->desc[i].returned = TRUE;
159 if (ph_transfer)
160 *ph_transfer = &(rbuff->desc[i].packet.h_transfer);
162 ASSERT(rbuff->last_returned_desc < MAX_ASYNC_PACKETS);
163 count = 0;
164 unsigned int total = rbuff->packets;
165 while ((count < total) && rbuff->desc[rbuff->last_returned_desc].returned) {
166 ASSERT(rbuff->packets);
167 rbuff->packets--;
169 // calculate free space
170 unsigned int idx_end = rbuff->desc[rbuff->last_returned_desc].idx_start + rbuff->desc[rbuff->last_returned_desc].total_len;
171 if (idx_end > RING_BUFFER_END) {
172 ASSERT(rbuff->desc[rbuff->last_returned_desc].idx_start <= RING_BUFFER_END);
173 rbuff->free_space += (RING_BUFFER_END - rbuff->desc[rbuff->last_returned_desc].idx_start);
174 } else {
175 rbuff->free_space += rbuff->desc[rbuff->last_returned_desc].total_len;
178 rbuff->last_returned_desc = (rbuff->last_returned_desc + 1) % MAX_ASYNC_PACKETS;
180 count++;
183 exit:
184 ring_buffer_unlock(rbuff);
185 #endif
186 return ret;
189 static inline unsigned int rbuff_complete_packets(ring_buffer_t * rbuff)
191 #ifdef USE_WRITE_PACKET_BUFFER
193 ring_buffer_lock(rbuff);
195 tr_user_t * h_ptransfer;
197 for (unsigned int i = 0; i < rbuff->idx_complete; i++) {
198 h_ptransfer = NULL;
199 if (0 == rbuff_complete_packet(rbuff,rbuff->complete[i], &h_ptransfer)) {
200 if (h_ptransfer) {
201 close_transfer(h_ptransfer); /* close transfer */ /* tr complete callback will set 0 to close transfer */
206 rbuff->idx_complete = 0;
208 ring_buffer_unlock(rbuff);
209 #endif
211 return 0;
213 //#endif /* #ifdef USE_WRITE_PACKET_BUFFER */
216 // global variables
218 USB_DEVICE_STRUCT_PTR gp_usb_device = NULL;
219 OS_Mutex_handle g_usbdev_synch = NULL; /* allocate and init at program start */
221 BOOL g_dev_attached = FALSE;
222 int opend_sco = 0;
224 // local function declare
225 static void read_task_proc_stub(void * param);
226 static BOOL submit_read_request(int event);
227 static BOOL check_device();
229 static inline void clear_tr_handle(tr_user_t * tr_ptr)
231 tr_ptr->tr_blocked = 0;
232 //tr_ptr->tr_internal_ptr = 0;
233 //tr_ptr->drv_private = 0;
234 //tr_ptr->transfered = 0;
237 BOOL acl_attached(USB_DEV_HANDLE usb_dev)
239 OS_Mutex_lock(g_usbdev_synch);
241 gp_usb_device->usb_dev = usb_dev;
242 if(gp_usb_device->usb_dev == NULL) {
243 OS_Mutex_unlock(g_usbdev_synch);
244 printf("get usb dev failed\n");
245 return FALSE;
247 #if 0
248 /* move to hci open */
249 if ((gp_usb_device->usbdev_event = OS_Event_create(0/* 0 - manual clear */)) == NULL) {
250 printf("\ncreate usbdev_event failed!\n");
251 goto fail1;
253 #endif
255 //#ifndef USE_SCO_TRANSFER /* if has sco then move to sco attach */
256 // gp_usb_device->initialized = TRUE; // inited at interface
257 g_dev_attached = TRUE;
258 //#endif
260 OS_Mutex_unlock(g_usbdev_synch);
262 return TRUE;
264 fail1:
265 gp_usb_device->usb_dev = NULL;
266 OS_Mutex_unlock(g_usbdev_synch);
267 return FALSE;
271 void dev_set_min_packet_size(unsigned int size)
273 OS_Mutex_lock(g_usbdev_synch);
274 gp_usb_device->min_packet_size = size;
275 OS_Mutex_unlock(g_usbdev_synch);
278 unsigned int dev_get_min_packet_size()
280 OS_Mutex_lock(g_usbdev_synch);
281 return gp_usb_device->min_packet_size;
282 OS_Mutex_unlock(g_usbdev_synch);
285 void acl_detached(USB_DEV_HANDLE usb_dev)
287 OS_Mutex_lock(g_usbdev_synch);
288 if(gp_usb_device->usb_dev != usb_dev) {
289 printf("usb dev is invalid at detach\n");
291 else {
292 OS_Event_set(gp_usb_device->usbdev_event,CLOSE_EVENT_MASK);
294 OS_Event_destroy(gp_usb_device->usbdev_event);
295 gp_usb_device->usbdev_event = NULL;
296 gp_usb_device->usb_dev = NULL;*/
298 g_dev_attached = FALSE;
299 //-gp_usb_device->initialized = FALSE;
301 OS_Mutex_unlock(g_usbdev_synch);
304 void usb_dev_set_pipe_handle(PIPE_HANDLE h_pipe, unsigned int event ,unsigned int in_out)
306 switch(event) {
307 case EVENT_INTERRUPT:
308 gp_usb_device->usb_pipes[EVENT_INTERRUPT].h_pipe = h_pipe;
309 break;
310 case EVENT_BULK:
311 if(in_out) /* 1 => USB_SEND ,0 => USB_RECV */
312 gp_usb_device->out_pipes[EVENT_BULK] = h_pipe;
313 else
314 gp_usb_device->usb_pipes[EVENT_BULK].h_pipe = h_pipe;
315 break;
316 #ifdef USE_SCO_TRANSFER
317 case EVENT_ISOCH:
318 if(in_out) /* 1 => USB_SEND ,0 => USB_RECV */
319 gp_usb_device->out_pipes[EVENT_ISOCH] = h_pipe;
320 else
321 gp_usb_device->usb_pipes[EVENT_ISOCH].h_pipe = h_pipe;
322 break;
323 #endif
324 default :
325 printf("error pipe event\n");
329 PIPE_HANDLE usb_dev_get_pipe_handle(unsigned int event ,unsigned int in_out)
331 switch(event) {
332 case EVENT_INTERRUPT:
333 return gp_usb_device->usb_pipes[EVENT_INTERRUPT].h_pipe;
334 case EVENT_BULK:
335 if(in_out) /* 1 => USB_SEND ,0 => USB_RECV */
336 return gp_usb_device->out_pipes[EVENT_BULK];
337 else
338 return gp_usb_device->usb_pipes[EVENT_BULK].h_pipe;
339 break;
340 #ifdef USE_SCO_TRANSFER
341 case EVENT_ISOCH:
342 if(in_out) /* 1 => USB_SEND ,0 => USB_RECV */
343 return gp_usb_device->out_pipes[EVENT_ISOCH];
344 else
345 return gp_usb_device->usb_pipes[EVENT_ISOCH].h_pipe;
346 break;
347 #endif
348 default :
349 printf("error pipe event\n");
351 return NULL;
354 uint32_t usbdev_event_set(uint32_t event_mask)
356 uint32_t ret;
357 OS_Mutex_lock(g_usbdev_synch);
358 ret = OS_Event_set(gp_usb_device->usbdev_event,event_mask);
359 OS_Mutex_unlock(g_usbdev_synch);
360 return ret;
363 void usbdev_set_inited()
365 OS_Mutex_lock(g_usbdev_synch);
366 gp_usb_device->initialized = TRUE;
367 OS_Mutex_unlock(g_usbdev_synch);
370 unsigned int usbdev_check_attached()
372 //OS_Mutex_lock(g_usbdev_synch);
373 return g_dev_attached;
374 //OS_Mutex_unlock(g_usbdev_synch);
377 #ifdef USE_SCO_TRANSFER
378 #if 0
379 uint_16 drv_sco_packet_maxsize(void * usb_dev,int in_out,int ep_num)
381 SCO_DEVICE_STRUCT_PTR sco_dev =
382 (SCO_DEVICE_STRUCT_PTR)(((APP_DEVICE_STRUCT_PTR)usb_dev)->dev_classes[SCO_CLASS_INTF]);
383 if(in_out) /* 1 - USB_SEND, 0 - USB_RECV */
384 return (uint_16)(SHORT_UNALIGNED_LE_TO_HOST(sco_dev->endp_sco_out[ep_num].wMaxPacketSize) & PACKET_SIZE_MASK);
385 else
386 return (uint_16)(SHORT_UNALIGNED_LE_TO_HOST(sco_dev->endp_sco_in[ep_num].wMaxPacketSize) & PACKET_SIZE_MASK);
388 #endif
390 /* the same interface will callback at attach for diffrent alt settings */
391 BOOL sco_attached(USB_DEV_HANDLE usb_dev,int alt_setting)
393 OS_Mutex_lock(g_usbdev_synch);
394 if(gp_usb_device->sco_pdata == NULL) {
395 //ASSERT(gp_usb_device->sco_pdata == NULL);
396 gp_usb_device->sco_pdata = (SCO_DATA_PRT) os_mem_alloc_zero(sizeof(SCO_DATA));
397 if(gp_usb_device->sco_pdata == NULL) {
398 OS_Mutex_destroy(g_usbdev_synch);
399 printf("alloc USB_DEVICE_STRUCT failed\n");
400 return FALSE;
404 //get describ //todo
405 //g_dev_attached = TRUE;
407 OS_Mutex_unlock(g_usbdev_synch);
409 return TRUE;
412 void sco_detached(USB_DEV_HANDLE usb_dev,int alt_setting)
414 OS_Mutex_lock(g_usbdev_synch);
415 //if(alt_setting == 0) {
416 if(gp_usb_device->sco_pdata != NULL) {
417 // ASSERT(gp_usb_device->sco_pdata != NULL);
418 os_mem_free(gp_usb_device->sco_pdata );
419 gp_usb_device->sco_pdata = NULL;
421 // todo other
423 OS_Mutex_unlock(g_usbdev_synch);
426 void sco_set_interfaced(USB_DEV_HANDLE usb_dev)
428 OS_Mutex_lock(g_usbdev_synch);
429 opend_sco = 1;
430 OS_Mutex_unlock(g_usbdev_synch);
433 static int sco_actived(/* USB_DEV_HANDLE usb_dev */)
435 return (gp_usb_device->sco_pdata->sco_pipe_idx >= 0 &&
436 gp_usb_device->sco_pdata->sco_pipe_idx < NUM_SCO_ENDPOINTS);
438 #endif
440 void sent_packet_signal_complete(unsigned int idx_start)
442 rbuff_signal_complete(&gp_usb_device->ring_buffer,idx_start,gp_usb_device->usbdev_event);
445 static BOOL check_device()
447 // call this function ,must after gp_usb_device locked !
448 if(!g_dev_attached)
449 return FALSE;
451 if (!gp_usb_device->initialized) {
452 printf("[HCI] [USB] check_device - device not active\n");
453 return FALSE;
456 if (gp_usb_device->closing) {
457 printf("[HCI] [USB] check_device - device closing...\n");
458 return FALSE;
461 return TRUE;
464 /* called by hci_open */
465 static BOOL open_connection(void)
467 // int opend_sco = 0; // move to global
468 #ifdef USE_SCO_TRANSFER
469 USB_DEV_HANDLE udev_handle = gp_usb_device->usb_dev;
470 SCO_DATA_PRT sco_pdata = gp_usb_device->sco_pdata;
471 int sco_rd_pkts = SCO_READ_PACKETS_PER_TRANSFER;
472 #endif
473 int i;
475 OS_Mutex_lock(g_usbdev_synch);
477 if ((gp_usb_device->usbdev_event = OS_Event_create(0/* 0 - manual clear */)) == NULL) {
478 printf("\ncreate usbdev_event failed!\n");
479 return FALSE;
482 if (! check_device()) {
483 printf("[USB] -open_connection : ERROR_NOT_READY\n");
484 OS_Mutex_unlock(g_usbdev_synch);
485 return FALSE;
488 // open acl interface at attach event callback
489 // open_acl_interface
491 gp_usb_device->packet_size = DEFPACKETSIZE;
492 gp_usb_device->block_size = DEFBLOCKSIZE;
494 #ifdef USE_SCO_TRANSFER
495 gp_usb_device->sco_pdata->suggested_sco_alt_setting = SCO_DEFAULT_ALT_SETTING; /* */
497 /* SCO_READ_PACKETS_PER_TRANSFER x SCO_READ_FRAMES_PER_PACKET = 9*3 = 27 */
498 sco_pdata->sco_read_frames = sco_rd_pkts * SCO_READ_FRAMES_PER_PACKET;
499 if (sco_pdata->sco_read_frames > MAX_SCO_READ_FRAMES_PER_TRANSFER) {
500 sco_pdata->sco_read_frames = MAX_SCO_READ_FRAMES_PER_TRANSFER;
503 if (sco_pdata->suggested_sco_alt_setting != 0) {
504 for (int i = 0 ; i < sco_pdata->sco_in_count ; ++i ) {
505 if ((sco_pdata->endp_sco_alt_setting[i] == sco_pdata->suggested_sco_alt_setting)) {
506 sco_pdata->sco_pipe_idx = i;
508 uint_16 ep_max_size = get_sco_endp_max_packetsize(udev_handle, i, USB_RECV);
509 if (( ep_max_size * sco_pdata->sco_read_frames) > gp_usb_device->min_packet_size)
510 gp_usb_device->min_packet_size = ep_max_size * sco_pdata->sco_read_frames;
515 // check --can remove for cut code size
516 if (sco_actived()) {
517 int sco_idx = sco_pdata->sco_pipe_idx;
518 uint_16 sco_in_ep_size = get_sco_endp_max_packetsize(udev_handle, sco_idx, USB_RECV);
519 uint_16 sco_out_ep_size = get_sco_endp_max_packetsize(udev_handle, sco_idx, USB_SEND);
520 if ((sco_in_ep_size != sco_out_ep_size) || (sco_pdata->sco_out_count != sco_pdata->sco_in_count) ) {
521 sco_pdata->sco_pipe_idx = -1;
522 printf("[HCI] [USB] iso endpoints in/out mismatch!\n");
523 ASSERT(0);
526 #endif
528 OS_Event_clear(gp_usb_device->usbdev_event, CLOSE_EVENT_MASK);
529 OS_Event_clear(gp_usb_device->usbdev_event, WRITEN_EVENT_MASK);
531 #ifdef USE_SCO_TRANSFER
532 if (sco_actived()) {
533 if(open_sco_interface( gp_usb_device->usb_dev, gp_usb_device->sco_pdata->suggested_sco_alt_setting)) {
534 // sco_detached(gp_usb_device->usb_dev,gp_usb_device->sco_pdata->suggested_sco_alt_setting);
535 printf("open sco intf altsetting %d failed\n",gp_usb_device->sco_pdata->suggested_sco_alt_setting);
536 // goto Cleanup;
538 // opend_sco = 1;
539 // OS_Time_delay(10); // waiting set interface finish.
541 #endif
543 if (gp_usb_device->packet_size < gp_usb_device->min_packet_size)
544 gp_usb_device->packet_size = gp_usb_device->min_packet_size;
546 if(ring_buff_init(&gp_usb_device->ring_buffer)) {
547 printf("alloc ring_buffer failed\n");
548 goto Cleanup;
551 gp_usb_device->fmem_id = os_alloc_fixed_mem (offsetof(PACKET, data) + gp_usb_device->packet_size, gp_usb_device->block_size);
552 if (!gp_usb_device->fmem_id) {
553 printf("[HCI] [USB] Failed to allocate fixed memory for packets\n");
554 goto Cleanup;
557 // Ensure all events are reset
558 for (i=0; i<NUM_IN_PIPES; i++) {
559 OS_Event_clear(gp_usb_device->usbdev_event ,(1 << i));
562 // creat read task
563 gp_usb_device->task_handle = OS_Task_create(read_task_proc_stub, (void*)NULL, (uint32_t)USB_READ_TASK_DEF_PRIORITY, USB_READ_TASK_STACKSIZE, "USB read task", NULL);
565 if (gp_usb_device->task_handle == (uint32_t)OS_TASK_ERROR) {
566 goto Cleanup;
568 //_task_ready(_task_get_td(task_id));
569 //OS_Task_resume(task_id);
571 for (i = EVENT_BULK; i <= (opend_sco ? EVENT_ISOCH : EVENT_INTERRUPT ); i++) {
572 if (!submit_read_request(i)) {
573 printf("[HCI] [USB] Read Request to %d failed.\n", i);
574 goto Cleanup;
578 printf("[USB] -open_connection : success\n");
579 OS_Mutex_unlock(g_usbdev_synch);
581 return TRUE;
583 Cleanup:
584 OS_Mutex_unlock(g_usbdev_synch);
585 //close_connection();
586 printf("[USB] -open_connection : err\n");
588 return FALSE;
591 BOOL pre_close_connection()
593 OS_Mutex_lock(g_usbdev_synch);
595 if (!gp_usb_device->initialized) {
596 OS_Mutex_unlock(g_usbdev_synch);
597 return FALSE;
600 printf("[HCI] set CLOSE_EVENT)\n");
601 OS_Event_set(gp_usb_device->usbdev_event,CLOSE_EVENT_MASK);
603 /* complete or cancel all in transfer , and close pipe */
604 close_acl_interface(gp_usb_device->usb_dev); /* will cancel the all pipe transfer ,todo check it */
605 for (int i = 0; i<NUM_IN_PIPES; i++) {
606 #ifdef FIXED_USE_DYNAMIC
607 PACKET *p_packet;
608 while(gp_usb_device->usb_pipes[i].packets) {
609 p_packet = gp_usb_device->usb_pipes[i].packets;
610 gp_usb_device->usb_pipes[i].packets = gp_usb_device->usb_pipes[i].packets->next;
611 os_put_fixed(p_packet,gp_usb_device->fmem_id);
613 #endif
614 /* complete or cancel all in transfer , and close pipe */
615 memset(&gp_usb_device->usb_pipes[i],0 ,sizeof(struct usb_pipe));
618 for (int i=0; i<NUM_OUT_PIPES; i++) {
619 /* close all of out pipe ,dont need cancel transfer */
620 if (gp_usb_device->out_pipes[i]) {
621 gp_usb_device->out_pipes[i] = NULL;
625 if (gp_usb_device->fmem_id) {
626 os_free_fixed_mem(gp_usb_device->fmem_id);
627 gp_usb_device->fmem_id = NULL;
630 while (gp_usb_device->packet_list) {
631 completed_packet_t *p_next = gp_usb_device->packet_list->next;
632 os_mem_free (gp_usb_device->packet_list);
633 gp_usb_device->packet_list = p_next;
636 ASSERT(gp_usb_device->packet_list == NULL);
637 gp_usb_device->last_packet = NULL;
638 #ifdef DEBUG_COMPLETE_PKT_NUM
639 complete_packets_num = 0;
640 #endif
642 #ifdef USE_SCO_TRANSFER
643 gp_usb_device->sco_pdata->sco_pipe_idx = -1;
644 #endif
646 OS_Mutex_unlock(g_usbdev_synch);
648 return TRUE;
651 void close_connection(void)
653 // in this point ,it is not locked.
654 printf("[USB] +close_connection\n");
655 if (!pre_close_connection()) {
656 printf("[HCI] [USB] -close_connection - device not active\n");
657 return;
660 OS_Mutex_lock(g_usbdev_synch);
662 ring_buff_deinit(&gp_usb_device->ring_buffer); /* ring buffer deinit */
664 /* clean task some else */
665 /* wait task close */
666 if (gp_usb_device->task_handle) {
667 OS_Task_delete(gp_usb_device->task_handle);
668 gp_usb_device->task_handle = 0;
671 OS_Event_destroy(gp_usb_device->usbdev_event);
672 gp_usb_device->usbdev_event = NULL;
673 // gp_usb_device->usb_dev = NULL;
675 OS_Mutex_unlock(g_usbdev_synch);
677 printf("[USB] -CloseConnection\n");
680 void close_usbdev(void)
682 OS_Mutex_lock(g_usbdev_synch);
683 if ((! gp_usb_device->initialized) || gp_usb_device->closing) {
684 OS_Mutex_unlock(g_usbdev_synch);
685 return ;
688 gp_usb_device->closing = TRUE;
689 close_connection();
690 gp_usb_device->closing = FALSE;
691 gp_usb_device->initialized = FALSE;
692 OS_Mutex_unlock(g_usbdev_synch);
695 static BOOL write_packet (unsigned char *p_buffer, int len, HCI_TYPE e_type)
697 BOOL tranfer_ret;
698 tr_user_t blocked_tr_handle; /* todo clean user tr handle */
700 if(len == 0)
701 return TRUE;
703 OS_Mutex_lock(g_usbdev_synch);
705 //printf("[USB] write_packet : %s : %d bytes\n", e_type == COMMAND_PACKET ? "COMMAND" : (e_type == DATA_PACKET_ACL ? "ACL" : (e_type == DATA_PACKET_SCO ? "SCO" : L"Error")), len));
707 if (!check_device()) {
708 OS_Mutex_unlock(g_usbdev_synch);
709 return FALSE;
712 #ifdef USE_SCO_TRANSFER
713 if ((DATA_PACKET_SCO == e_type) && !sco_actived()) {
715 OS_Mutex_unlock(g_usbdev_synch);
716 return FALSE;
718 #endif
720 //ASSERT(p_buffer);
721 //ASSERT(len > 0);
723 switch (e_type)
725 case COMMAND_PACKET:
727 OS_Mutex_unlock(g_usbdev_synch);
728 tranfer_ret = issue_cmd_transfer( gp_usb_device->usb_dev,&blocked_tr_handle,p_buffer,len);
729 OS_Mutex_lock(g_usbdev_synch);
731 if (!tranfer_ret || !check_device()) {
732 printf("[USB] -write_packet : (COMMAND_PACKET) failure!\n");
733 OS_Mutex_unlock(g_usbdev_synch);
734 return FALSE;
737 /* in some usbhost stack ,must close this transfer after transfer complete */
738 break;
741 case DATA_PACKET_ACL:
743 // ASSERT(gp_usb_device->out_pipes[PACKET_ACL]);
744 unsigned int idx_start = 0xffffffff;
745 int align_len = (len & 3) ? len + (4 - (len & 3)) : len;
746 usb_write_packet_t* p_packet = rbuff_get_write_packet(&gp_usb_device->ring_buffer, align_len, &idx_start);
747 if (! p_packet) {
748 OS_Mutex_unlock(g_usbdev_synch);
749 tranfer_ret = issue_acl_transfer(gp_usb_device->usb_dev,&blocked_tr_handle,
750 USB_OUT_TRANSFER/* wait */,/*NULL,*/NULL,p_buffer,len);
751 OS_Mutex_lock(g_usbdev_synch);
753 if ( !tranfer_ret || !check_device()) {
754 printf("[USB] -write_packet : (DATA_PACKET_ACL) failure!\n");
756 OS_Mutex_unlock(g_usbdev_synch);
757 return FALSE;
759 /* after complete close this transfer */
761 else {
762 p_packet->e_type = e_type;
763 memcpy(p_packet->buffer, p_buffer, len);
765 unsigned char * p_tmp = p_packet->buffer;
767 OS_Mutex_unlock(g_usbdev_synch);
768 tranfer_ret = issue_acl_transfer(gp_usb_device->usb_dev,&p_packet->h_transfer,
769 USB_OUT_TRANSFER | USB_NO_WAIT ,(pointer)idx_start,p_tmp,len);
770 OS_Mutex_lock(g_usbdev_synch);
772 if (!tranfer_ret || !check_device()) {
773 printf("[USB] -WritePacket : (DATA_PACKET_ACL) failure!\n");
775 rbuff_complete_packet( &gp_usb_device->ring_buffer,idx_start,NULL);
777 OS_Mutex_unlock(g_usbdev_synch);
778 return FALSE;
781 if (transfer_completed(&p_packet->h_transfer)) {
782 close_transfer(&p_packet->h_transfer);
785 break;
787 #ifdef USE_SCO_TRANSFER
788 case DATA_PACKET_SCO:
790 unsigned short max_pkt_out_size = get_sco_endp_max_packetsize(gp_usb_device->usb_dev,
791 gp_usb_device->sco_pdata->sco_pipe_idx,USB_SEND);
793 unsigned int idx_start = 0xffffffff;
794 int align_len = (len & 3) ? len + (4 - (len & 3)) : len;
795 usb_write_packet_t* p_packet = rbuff_get_write_packet(&gp_usb_device->ring_buffer, align_len, &idx_start);
797 ASSERT( (len /max_pkt_out_size) <= SCO_WRITE_FRAMES_PER_PACKET );
798 if ( (len / max_pkt_out_size) > SCO_WRITE_FRAMES_PER_PACKET ) {/* nLen / sco max packet size must little than 3 frames */
799 printf("[USB] SCO packet len exceeds 3 frames\n");
800 break;
803 if (! p_packet) {
804 unsigned int lens[SCO_WRITE_FRAMES_PER_PACKET];
806 for (int i = 0; i < SCO_WRITE_FRAMES_PER_PACKET; i++) {
807 lens[i] = SCO_DEF_SAMPLE_SIZE;
808 if (i < 3) {
810 lens[i]++;
814 OS_Mutex_unlock(g_usbdev_synch);
815 tranfer_ret = issue_sco_transfer(gp_usb_device->usb_dev,&blocked_tr_handle,
816 USB_OUT_TRANSFER/* and wait */,NULL,SCO_WRITE_FRAMES_PER_PACKET,lens,p_buffer);
817 OS_Mutex_lock(g_usbdev_synch);
819 if ( !tranfer_ret || !check_device()) {
820 printf("[USB] -write_packet : (DATA_PACKET_SCO) failure!\n");
821 OS_Mutex_unlock(g_usbdev_synch);
822 return FALSE;
826 else {
827 p_packet->e_type = e_type;
828 memcpy(p_packet->buffer, p_buffer, len);
830 for (int i = 0; i < SCO_WRITE_FRAMES_PER_PACKET; i++) {
831 p_packet->lens[i] = SCO_DEF_SAMPLE_SIZE;
832 if (i < 3) {
833 // First 3 packets have 1 extra byte for SCO header
834 p_packet->lens[i]++;
838 unsigned int * p_tmplens = p_packet->lens;
839 unsigned char * p_tmpbuff = p_packet->buffer;
841 OS_Mutex_unlock(g_usbdev_synch);
842 tranfer_ret = issue_sco_transfer(gp_usb_device->usb_dev,&blocked_tr_handle,
843 USB_OUT_TRANSFER | USB_NO_WAIT,NULL,SCO_WRITE_FRAMES_PER_PACKET,p_tmplens,p_tmpbuff);
844 OS_Mutex_lock(g_usbdev_synch);
846 if (!tranfer_ret || !check_device()) {
847 printf("[USB] -WritePacket : (DATA_PACKET_SCO) failure!\n");
849 rbuff_complete_packet( &gp_usb_device->ring_buffer,idx_start,NULL);
851 OS_Mutex_unlock(g_usbdev_synch);
852 return FALSE;
855 if (transfer_completed(&p_packet->h_transfer)) {
856 close_transfer(&p_packet->h_transfer);
860 break;
861 #endif
862 default:
863 printf("[HCI - USB] write_packet :: Invalid code!\n");
864 break;
867 OS_Mutex_unlock(g_usbdev_synch);
869 return TRUE;
872 /* acl ,sco, event, (cmd ?) , get number(needed) of bytes to d buffer from the offset of the buffer */
873 static BOOL get_buffer (int type, int offset, int needed, unsigned char *d, int clean_packets)
875 // If we remove packets from the queue, the transfer must be for the entire packet.
876 // The code below assumes it in calculation of how much data has been removed from the
877 // queue.
879 // ASSERT ((! cleanPackets) || (offset == 0));
881 usb_pipe_t *p_pipe = &gp_usb_device->usb_pipes[type];
883 if (p_pipe->packets == NULL) {
884 ASSERT (! clean_packets);
885 return FALSE;
888 PACKET *p_packet = p_pipe->packets;
890 while (p_packet) {
891 if (p_packet->size - p_packet->offset > offset) /* find offset (for locate) */
892 break;
894 offset -= p_packet->size - p_packet->offset;
895 if (clean_packets) {
896 p_pipe->packets = p_packet->next;
897 if (! p_pipe->packets)
898 p_pipe->last_packet = NULL;
899 //printf("put fixed %x\n",p_packet);
900 os_put_fixed(p_packet,gp_usb_device->fmem_id); /* delete fixed PACKET */
901 p_packet = p_pipe->packets;
903 else
904 p_packet = p_packet->next;
907 while (p_packet && needed) {
908 int transfer = p_packet->size - p_packet->offset - offset;
909 if (transfer > needed)
910 transfer = needed;
912 memcpy (d, p_packet->data + p_packet->offset + offset, transfer);
914 if (clean_packets) {
915 p_pipe->total_queue -= transfer;
917 p_packet->offset += transfer + offset;
918 ASSERT (p_packet->offset <= p_packet->size);
920 if (p_packet->offset == p_packet->size) {
921 p_pipe->packets = p_packet->next;
922 if (! p_pipe->packets)
923 p_pipe->last_packet = NULL;
925 //os_mem_free(p_packet);
926 // printf("put fixed1 %x\n",p_packet);
927 os_put_fixed(p_packet,gp_usb_device->fmem_id); /* delete fixed PACKET */
929 p_packet = p_pipe->packets;
931 else
932 ASSERT (needed == transfer);
934 else
935 p_packet = p_packet->next;
937 d += transfer;
938 needed -= transfer;
939 offset = 0;
941 ASSERT (needed >= 0);
944 if (needed != 0) {
945 ASSERT (! clean_packets);
946 return FALSE;
949 return TRUE;
952 static int packet_size (int type)
954 unsigned char d[2];
956 usb_pipe_t *p_pipe = &gp_usb_device->usb_pipes[type];
958 switch (type)
960 #ifdef USE_SCO_TRANSFER
961 case EVENT_ISOCH:
962 if (!get_buffer(type, 2, 1, d, FALSE))
963 return 0;
964 return d[0] + SCO_HEADER_SIZE; /* HCI sco */
965 #endif
967 case EVENT_BULK:
968 if (!get_buffer(type, 2, 2, d, FALSE)) /* HCI acl */
969 return 0;
970 ASSERT (p_pipe->packets->size >= 4);
971 return (d[0] | (d[1] << 8)) + ACL_HEADER_SIZE;
973 case EVENT_INTERRUPT: /* HCI event */
974 if (!get_buffer(type, 1, 1, d, FALSE))
975 return 0;
976 ASSERT (p_pipe->packets->size >= 3);
977 return d[0] + EVENT_HEADER_SIZE;
980 printf("[HCI] [USB] UNKNOWN PACKET ERROR!\n");
981 ASSERT (0);
983 return 0;
986 BOOL complete_packet (int type ) { /* get complete packet then hang up to packetlist */
987 int size_packet = packet_size(type);
989 usb_pipe_t *p_pipe = &gp_usb_device->usb_pipes[type];
991 ASSERT ((size_packet == 0) || (p_pipe->total_queue > 0));
993 if ((size_packet == 0) || (p_pipe->total_queue < size_packet)) { /* this is normal error !*/
994 //-printf("[HCI] [USB] type %d, Packet of invalid size1 %d .\n",/* size_packet */type,size_packet/*packet_size(type)*/);
995 return FALSE;
998 if ((size_packet <= 0) || (size_packet > PACKET_SIZE_R)) {
999 printf("[HCI] [USB] Packet of invalid size %d.\n",size_packet);
1000 return FALSE;
1003 BOOL res = FALSE;
1005 int aligned_size = offsetof (completed_packet_t, cdata) + size_packet + (4 - (size_packet & 3));
1006 completed_packet_t *p_new_packet = (completed_packet_t *)os_mem_alloc_zero (aligned_size/*offsetof (completed_packet_t, cdata) + size_packet*/);
1007 #ifdef DEBUG_COMPLETE_PKT_NUM
1008 printf("+cpkt %d,0x%x,%d\n ", ++complete_packets_num,p_new_packet,/*size_packet*/type);
1009 #endif
1010 if (p_new_packet) {
1011 p_new_packet->e_type = type;
1012 p_new_packet->clen = size_packet;
1013 p_new_packet->next = NULL;
1014 /* get the CompletedPacket from packet list of pipe[type] */
1015 res = get_buffer (p_new_packet->e_type, 0, p_new_packet->clen, p_new_packet->cdata, TRUE/* clean packets */);
1016 if (res) {
1017 if (gp_usb_device->last_packet)
1018 gp_usb_device->last_packet->next = p_new_packet; /* from pipe packet list get complete packet to usb_dev complete packet list */
1019 else
1020 gp_usb_device->packet_list = p_new_packet;
1021 gp_usb_device->last_packet = p_new_packet;
1022 } else {
1023 ASSERT (0);
1024 os_mem_free (p_new_packet);
1026 } else
1027 ASSERT (0); //out of mem
1029 return res;
1032 BOOL retrieve_packet (unsigned char *p_buffer, int *p_len, int *p_type, unsigned int *p_timeout)
1034 if (gp_usb_device->packet_list) { /* callby hci read, (btTaskf call it) , btTaskf's prority can't more than read task */
1035 *p_len = gp_usb_device->packet_list->clen;
1036 *p_type = gp_usb_device->packet_list->e_type;
1037 memcpy (p_buffer, gp_usb_device->packet_list->cdata, gp_usb_device->packet_list->clen);
1039 completed_packet_t *p_next = gp_usb_device->packet_list->next;
1040 os_mem_free (gp_usb_device->packet_list);
1041 #ifdef DEBUG_COMPLETE_PKT_NUM
1042 printf("-cpkt %d,0x%x\n ", --complete_packets_num,gp_usb_device->packet_list);
1043 #endif
1044 gp_usb_device->packet_list = p_next;
1045 if (! gp_usb_device->packet_list )
1046 gp_usb_device->last_packet = NULL;
1048 return TRUE;
1050 return FALSE;
1053 static BOOL read_packet (unsigned char *p_buffer, int *p_len, unsigned int *p_type) /* pnType get type of readed */
1055 // printf("[USB] +read_packet\n");
1057 for ( ; ; ) {
1058 OS_Mutex_lock(g_usbdev_synch);
1060 if (!check_device()) {
1061 printf("[USB] -read_packet : FALSE (device dead)\n");
1062 OS_Mutex_unlock(g_usbdev_synch);
1063 //OS_Time_delay(1); /* workaround for detach ,give usb task some time to do bt_deinit */
1064 return FALSE;
1067 unsigned int timeout = EVENT_TIMEOUT_INFINITE;
1069 if (retrieve_packet (p_buffer, p_len, (int *)p_type, &timeout)) { /* read at first, then wait event at below */
1070 /* printf("[USB] -read_packet : TRUE (got stuff) _usbPipes[%d].iTotalQueue=%d\n",
1071 *p_type, gp_usb_device->usb_pipes[*p_type].total_queue); */
1072 OS_Mutex_unlock(g_usbdev_synch);
1073 return TRUE;
1076 unsigned int events_mask = (PACKETS_EVENT_MASK | CLOSE_EVENT_MASK);
1078 // printf(DebugOut (DEBUG_HCI_TRANSPORT, L"[USB] read_packet : WAIT\n"));
1079 OS_Mutex_unlock(g_usbdev_synch);
1081 if (MQX_OK != OS_Event_wait(gp_usb_device->usbdev_event, events_mask, FALSE, timeout)) {
1082 printf("\n_lwevent_wait_ticks usbdev_event failed.\n");
1083 continue;
1086 //OS_Mutex_lock(g_usbdev_synch);
1087 if(OS_Event_check_bit(gp_usb_device->usbdev_event,PACKETS_EVENT_MASK)) {
1088 OS_Event_clear(gp_usb_device->usbdev_event,PACKETS_EVENT_MASK);
1089 //OS_Mutex_unlock(g_usbdev_synch);
1090 continue;
1092 //OS_Mutex_unlock(g_usbdev_synch);
1093 // printf("[USB] -read_packet : FALSE (device closed)\n");
1094 return FALSE;
1098 BOOL read_task_proc(void)
1100 unsigned int event_mask = READ_EVENT_BULK_MASK | READ_EVENT_INTERRUPT_MASK
1101 #ifdef USE_SCO_TRANSFER
1102 | READ_EVENT_ISO_MASK
1103 #endif
1104 | WRITEN_EVENT_MASK | CLOSE_EVENT_MASK;
1106 int stop_flag = FALSE;
1107 unsigned int event_status;
1109 // unsigned int err = USB_OK;
1110 BOOL success;
1111 unsigned int event;
1113 while(TRUE) {
1114 if (OS_Event_wait(gp_usb_device->usbdev_event, event_mask, FALSE, EVENT_TIMEOUT_INFINITE)) {
1115 printf("\n_lwevent_wait_ticks usbdev_event failed.\n");
1116 stop_flag = TRUE;
1117 break;
1120 event_status = OS_Event_status(gp_usb_device->usbdev_event);
1122 OS_Mutex_lock(g_usbdev_synch);
1124 //-printf("event_status %d set.\n", event_status);
1126 if (event_status & CLOSE_EVENT_MASK) {
1127 printf("[HCI] [USB] read_task_proc waited close event.\n");
1128 OS_Mutex_unlock(g_usbdev_synch);
1129 break;
1132 if (!check_device()) {
1133 printf("[HCI] [USB] Device closed. Exiting read thread...\n");
1134 OS_Mutex_unlock(g_usbdev_synch);
1135 break;
1137 // 1. event writen
1138 if (event_status & WRITEN_EVENT_MASK) {
1139 OS_Event_clear(gp_usb_device->usbdev_event,WRITEN_EVENT_MASK);
1140 if(rbuff_complete_packets(&gp_usb_device->ring_buffer)) {
1141 printf("[WARN] USB write completed async but could not complete packets.\n");
1144 OS_Mutex_unlock(g_usbdev_synch);
1145 continue;
1148 // unsigned int err = USB_OK;
1149 // BOOL success;
1150 // unsigned int event;
1151 #if 1
1152 if(event_status & /* READ_EVENT_BULK_MASK */READ_EVENT_INTERRUPT_MASK)
1153 event = /* EVENT_BULK*/EVENT_INTERRUPT;
1154 else if(event_status & /* READ_EVENT_INTERRUPT_MASK */READ_EVENT_BULK_MASK)
1155 event = /* EVENT_INTERRUPT */EVENT_BULK;
1156 #else
1157 if(event_status & READ_EVENT_BULK_MASK)
1158 event = EVENT_BULK;
1159 else if(event_status & READ_EVENT_INTERRUPT_MASK)
1160 event = EVENT_INTERRUPT;
1161 #endif
1162 #ifdef USE_SCO_TRANSFER
1163 else if(event_status & READ_EVENT_ISO_MASK)
1164 event = EVENT_ISOCH;
1165 #endif
1167 //#ifdef USE_SCO_TRANSFER
1168 // // 2. event iso , below are events of in pipe
1169 // if (event == EVENT_ISOCH) {
1170 // // todo
1171 // } else
1172 //#endif
1174 { /* 3. other event EVENT_BULK EVENT_INTERRUPT EVENT_ */
1175 success = get_transfer_status(&( gp_usb_device->usb_pipes[event].h_transfer),
1176 (unsigned int *)&gp_usb_device->usb_pipes[event].cur_packet->size);
1179 if (!success) {
1180 printf("[HCI] [USB] Invalid USB transfer handle. Exiting task...\n");
1181 OS_Mutex_unlock(g_usbdev_synch);
1182 stop_flag = TRUE;
1183 break;
1185 else if (gp_usb_device->usb_pipes[event].cur_packet->size == 0) {
1186 if (event!= EVENT_ISOCH) {
1187 printf("[HCI] [USB] Packet size 0 : ignoring \n");
1190 else if (gp_usb_device->usb_pipes[event].cur_packet->size > gp_usb_device->packet_size) {
1191 printf("[HCI] [USB] Invalid Packet size %d : ignoring packet\n", gp_usb_device->usb_pipes[event].cur_packet->size);
1192 ASSERT(0); /* todo remove it */
1193 gp_usb_device->usb_pipes[event].cur_packet->size = 0;
1195 else { /* in transfer ok */
1196 // printf("[USB] get_transfer_status returns %d bytes transferred.\n", gp_usb_device->usb_pipes[event].cur_packet->size);
1197 // ASSERT(gp_usb_device->usb_pipes[event].cur_packet->size <= gp_usb_device->packet_size);
1199 if (gp_usb_device->usb_pipes[event].last_packet) { /* last_packet point to the last cur_packet , packets pointer the first cur_packet */
1200 ASSERT(gp_usb_device->usb_pipes[event].last_packet->next == NULL);
1201 gp_usb_device->usb_pipes[event].last_packet->next = gp_usb_device->usb_pipes[event].cur_packet;
1202 gp_usb_device->usb_pipes[event].last_packet = gp_usb_device->usb_pipes[event].cur_packet;
1204 else {
1205 ASSERT(gp_usb_device->usb_pipes[event].packets == NULL); /* first packet*/
1206 gp_usb_device->usb_pipes[event].last_packet = gp_usb_device->usb_pipes[event].packets = gp_usb_device->usb_pipes[event].cur_packet;
1209 gp_usb_device->usb_pipes[event].total_queue += gp_usb_device->usb_pipes[event].cur_packet->size;
1211 ASSERT (gp_usb_device->usb_pipes[event].last_packet->next == NULL);
1212 gp_usb_device->usb_pipes[event].cur_packet = NULL;
1214 if (complete_packet (event))
1215 OS_Event_set(gp_usb_device->usbdev_event, PACKETS_EVENT_MASK); /* Get completePacket then set evnet to read_packet */
1218 //ASSERT(gp_usb_device->usb_pipes[event].h_transfer.tr_blocked & TR_CLEAR_MASK);
1219 close_transfer(&gp_usb_device->usb_pipes[event].h_transfer);
1220 clear_tr_handle(& gp_usb_device->usb_pipes[event].h_transfer);
1222 BOOL submit_flag = submit_read_request(event);
1224 OS_Mutex_unlock(g_usbdev_synch);
1226 if (!submit_flag) {
1227 printf("[HCI] [USB] reader thread : Could not resubmit the request. Closing down\n");
1228 stop_flag = TRUE;
1229 break;
1233 if (stop_flag) {
1234 printf("[HCI] [USB] reader task : closing down\n");
1235 OS_Event_set(gp_usb_device->usbdev_event , CLOSE_EVENT_MASK);
1236 pre_close_connection();
1239 printf("[USB] reader task : exited\n");
1240 return FALSE;
1243 static void read_task_proc_stub(void * param)
1245 read_task_proc();
1246 //printf("read task exit\n");
1247 //OS_Task_suspend(0);
1248 return;
1251 static BOOL submit_read_request(int event)
1253 tr_user_t * tr_hptr;
1254 BOOL tr_ret;
1255 int i;
1256 unsigned short max_pkt_in_size;
1258 //printf("[USB] SubmitReadRequest %s\n", event == EVENT_BULK ? L"ACL" : (event == EVENT_INTERRUPT ? L"Event" : (event == EVENT_ISOCH ? L"SCO" : L"Error"))));
1260 // call after g_usbdev_synch locked
1261 #ifdef USE_SCO_TRANSFER
1262 if ( (event == EVENT_ISOCH) && !sco_actived() ) {
1263 printf("[HCI] [USB] -submit_read_request :: SCO read when no ISOCH endpoint found\n");
1264 return FALSE;
1266 #endif
1268 OS_Event_clear(gp_usb_device->usbdev_event,(1<< event));
1270 // ASSERT(!gp_usb_device->usb_pipes[event].h_transfer); // h_transfr must clear
1272 if (! gp_usb_device->usb_pipes[event].cur_packet) // if bulk transfer fail ,dont delete ,then use the old PACKET
1273 gp_usb_device->usb_pipes[event].cur_packet = os_get_fixed(gp_usb_device->fmem_id); /* get packet from the fixed memory */
1275 if (! gp_usb_device->usb_pipes[event].cur_packet ) {
1276 printf("[HCI] [USB] -submit_read_request :: out of memory!\n");
1277 return FALSE;
1279 else {
1280 memset(gp_usb_device->usb_pipes[event].cur_packet,0,sizeof(PACKET));
1281 // sprintf("get fixed %x\n", gp_usb_device->usb_pipes[event].cur_packet);
1284 // reset halt pipe
1285 switch(event)
1287 case EVENT_BULK:
1288 tr_hptr = & gp_usb_device->usb_pipes[event].h_transfer; /* to do clean user tr handle */
1289 tr_ret = issue_acl_transfer(gp_usb_device->usb_dev,
1290 tr_hptr, USB_IN_TRANSFER | USB_NO_WAIT ,(pointer)event,
1291 gp_usb_device->usb_pipes[event].cur_packet->data, gp_usb_device->packet_size);
1293 break;
1294 case EVENT_INTERRUPT:
1295 tr_hptr = & gp_usb_device->usb_pipes[event].h_transfer;
1296 tr_ret = issue_event_transfer(gp_usb_device->usb_dev, tr_hptr,
1297 /* USB_IN_TRANSFER | USB_NO_WAIT ,(pointer)event, */
1298 gp_usb_device->usb_pipes[event].cur_packet->data, gp_usb_device->packet_size);
1300 break;
1301 #ifdef USE_SCO_TRANSFER
1302 case EVENT_ISOCH:
1303 max_pkt_in_size = get_sco_endp_max_packetsize(gp_usb_device->usb_dev,
1304 gp_usb_device->sco_pdata->sco_pipe_idx,USB_RECV);
1306 for (i = 0; i < gp_usb_device->sco_pdata->sco_read_frames; i++) {
1307 gp_usb_device->sco_pdata->in_transfer_lens [i] = max_pkt_in_size;
1310 tr_hptr = & gp_usb_device->usb_pipes[event].h_transfer; /* to do clean user tr handle */
1311 tr_ret = issue_sco_transfer(gp_usb_device->usb_dev,
1312 tr_hptr, USB_IN_TRANSFER | USB_NO_WAIT ,(pointer)event,
1313 gp_usb_device->sco_pdata->sco_read_frames, gp_usb_device->sco_pdata->in_transfer_lens,
1314 gp_usb_device->usb_pipes[event].cur_packet->data);
1316 break;
1317 #endif
1318 default:
1319 ASSERT(FALSE);
1320 break;
1323 // check gp_usb_device->usb_pipes[event].h_transfer must not clear
1325 // printf("[USB] -submit_read_request %s : TRUE\n", event == EVENT_BULK ? L"ACL" : (event == EVENT_INTERRUPT ? L"Event" : (event == EVENT_ISOCH ? L"SCO" : L"Error"))));
1327 return tr_ret;
1330 BOOL hci_transport_init()
1332 if(!usb_drv_init())
1333 return FALSE;
1335 ASSERT((gp_usb_device == NULL) && (g_usbdev_synch == NULL));
1337 if ((g_usbdev_synch = OS_Mutex_create()) == NULL) {
1338 printf("\ncreate usbdev_synch failed!\n");
1339 return FALSE;
1342 gp_usb_device = (USB_DEVICE_STRUCT_PTR) os_mem_alloc_zero(sizeof(USB_DEVICE_STRUCT));
1343 if(gp_usb_device == NULL) {
1344 OS_Mutex_destroy(g_usbdev_synch);
1345 printf("alloc USB_DEVICE_STRUCT failed\n");
1346 return FALSE;
1348 return TRUE;
1351 void hci_transport_deinit()
1353 ASSERT((gp_usb_device != NULL) && (g_usbdev_synch != NULL));
1354 os_mem_free(gp_usb_device);
1355 if(g_usbdev_synch) {
1356 OS_Mutex_destroy(g_usbdev_synch);
1357 g_usbdev_synch = NULL;
1359 // todo add shutdown usb drv
1362 BOOL hci_open (void)
1364 printf("hci_open \n");
1365 if (open_connection()) {
1366 return TRUE;
1368 else {
1369 return FALSE;
1373 void hci_close (void)
1375 //close_connection();
1376 close_usbdev();
1377 printf("hci_close \n\n\n");
1380 BOOL hci_write (HCI_TYPE type, unsigned char * pbuff,unsigned int len)
1382 //print("hci_write type 0x%02x len %d\n", type, len);
1384 if (len > PACKET_SIZE_W) {
1385 printf("[USB] Packet too big (%d, should be <= %d), or no space for header!\n", len, PACKET_SIZE_W);
1386 return FALSE;
1389 if (!write_packet(pbuff, len, type)) {
1390 printf("write pakect failed\n");
1391 return FALSE;
1394 return TRUE;
1397 BOOL hci_read (HCI_TYPE *ptype, unsigned char * pbuff,unsigned int *plen)
1400 #define UART_PKT_TYP_CMD 1
1401 #define UART_PKT_TYP_ACL 2
1402 #define UART_PKT_TYP_SCO 3
1403 #define UART_PKT_TYP_EVT 4
1405 int type;
1406 //printf("hci_read\n");
1409 if (*plen > PACKET_SIZE_R) {
1410 printf("want read packet too big (should be <= %d), or no space for header!\n", PACKET_SIZE_W));
1411 return FALSE;
1414 if (!read_packet(pbuff, (int *)plen, &type)) {
1415 printf("read packet failed\n");
1416 return FALSE;
1419 ASSERT(*plen < PACKET_SIZE_R);
1421 switch(type)
1423 case EVENT_BULK: // ACL packet
1424 *ptype = UART_PKT_TYP_ACL;
1425 return TRUE;
1427 case EVENT_INTERRUPT: // HCI Event
1428 *ptype = UART_PKT_TYP_EVT;
1429 return TRUE;
1431 case EVENT_ISOCH: // SCO packet
1432 *ptype = UART_PKT_TYP_SCO;
1433 return TRUE;
1435 default:
1436 printf("unknown type packet (ignoring)\n");
1437 //ASSERT(FALSE);
1438 break;
1441 return FALSE;