1 /******************************************************************************
2 ** File Name: DRV_usb.c *
3 ** Author: JiaYong.Yang *
5 ** Copyright: 2010 Spreatrum, Incoporated. All Rights Reserved. *
7 ******************************************************************************/
8 /**---------------------------------------------------------------------------*
10 **---------------------------------------------------------------------------*/
12 #include <asm/arch/common.h>
13 #include <asm/arch/usb200_fdl.h>
14 #include <asm/arch/drv_usb20.h>
15 #include <asm/arch/virtual_com.h>
16 #include <asm/arch/packet.h>
17 #include <asm/arch/usb20_reg_v3.h>
21 PUBLIC void Dcache_InvalRegion(unsigned int addr, unsigned int length);
22 PUBLIC void Dcache_CleanRegion(unsigned int addr, unsigned int length);
24 static __inline void usb_handler (void);
25 /**---------------------------------------------------------------------------*
27 **---------------------------------------------------------------------------*/
28 #define MAX_RECV_LENGTH (64*64)//640*64 0xa000
29 #define USB_TIMEOUT (1000)
31 /**---------------------------------------------------------------------------*
33 **---------------------------------------------------------------------------*/
35 static int currentDmaBufferIndex = 0;
36 LOCAL __align(64) uint32 s_setup_packet[8] = {0};
37 LOCAL uint32 enum_speed = 0;
38 LOCAL uint32 recv_length = 0;
39 LOCAL uint32 nIndex = 0;
40 LOCAL uint32 readIndex = 0;
42 PUBLIC __align (64) unsigned char usb_out_endpoint_buf[2] [MAX_RECV_LENGTH];
47 /*****************************************************************************/
48 // Description: configure out endpoint0 to receive setup message.
49 // Global resource dependence:
50 // Author: jiayong.yang
52 /*****************************************************************************/
53 LOCAL int EPO0_config (BOOLEAN is_dma, uint32 *buffer)
55 // Programs DOEPTSIZ0 register with Packet Count and Transfer Size
56 * (volatile uint32 *) USB_DOEP0TSIZ |= (unsigned int) (BIT_29|BIT_30); //setup packet count , 3 packet
57 * (volatile uint32 *) USB_DOEP0TSIZ |= (unsigned int) (BIT_3|BIT_4); //set Transfer Size ,24 bytes
61 * (volatile uint32 *) USB_DOEPDMA (0) = (uint32) buffer;//lint !e718
64 * (volatile uint32 *) USB_DOEP0CTL |= (unsigned int) BIT_26; // set clear NAK
65 * (volatile uint32 *) USB_DOEP0CTL |= (unsigned int) BIT_31; // set endpoint enable
68 /*****************************************************************************/
69 // Description: configure in endpoint0 to send message.
70 // Global resource dependence:
71 // Author: jiayong.yang
73 /*****************************************************************************/
74 void EPI0_config (uint32 transfer_size, uint32 packet_count, BOOLEAN is_dma, uint32 *buffer)
76 volatile USB_DIEP0TSIZ_U *diep0tsiz_ptr = (USB_DIEP0TSIZ_U *) USB_DIEP0TSIZ;
78 diep0tsiz_ptr->mBits.transfer_size = transfer_size;
79 diep0tsiz_ptr->mBits.packet_count = packet_count;
83 #if defined CONFIG_SC8810 || defined CONFIG_SC8825 || defined CONFIG_SC8830 || defined(CONFIG_SC9630)
84 Dcache_CleanRegion((unsigned int)(buffer), transfer_size);
86 * (volatile uint32 *) USB_DIEPDMA (0) = (uint32) buffer;//lint !e718
89 * (volatile uint32 *) USB_DIEP0CTL &= (unsigned int) (~ (BIT_22|BIT_23|BIT_24|BIT_25)); // set EP0 in tx fifo nummber
91 * (volatile uint32 *) USB_DIEP0CTL |= (unsigned int) BIT_26; // clear NAK
93 * (volatile uint32 *) USB_DIEP0CTL |= (unsigned int) BIT_31; // set endpoint enable
95 /*****************************************************************************/
96 // Description: usb reset interrupt handler.
97 // Global resource dependence:
98 // Author: jiayong.yang
100 /*****************************************************************************/
101 void usb_EPActive (USB_EP_NUM_E ep_num, BOOLEAN dir)
103 if (dir) // out endpoint
105 * (volatile uint32 *) USB_DOEPCTL (ep_num) |= (unsigned int) BIT_15; //lint !e718// endpoint active
106 * (volatile uint32 *) USB_DOEPMSK = (unsigned int) (BIT_13|BIT_12|BIT_3);
110 * (volatile uint32 *) USB_DIEPCTL (ep_num) |= (unsigned int) BIT_15; //lint !e718// endpoint active
111 * (volatile uint32 *) USB_DIEPMSK = 0xffffffff;
114 /*****************************************************************************/
115 // Description: configure specified endpoint to send/receive message.
116 // Global resource dependence:
117 // Author: jiayong.yang
119 /*****************************************************************************/
120 LOCAL void EPn_config (USB_EP_NUM_E ep_num, USB_EP_TYPE_E ep_type, BOOLEAN dir, uint32 mps)
125 volatile USB_DOEPCTL_U *doepctl_ptr = (USB_DOEPCTL_U *) USB_DOEPCTL (ep_num);
127 doepctl_ptr->mBits.ep_type = ep_type;
128 doepctl_ptr->mBits.mps =mps;
129 doepctl_ptr->mBits.set_nak = 0x1;
133 volatile USB_DIEPCTL_U *diepctl_ptr = (USB_DIEPCTL_U *) USB_DIEPCTL (ep_num);
135 diepctl_ptr->mBits.ep_type = ep_type;
136 diepctl_ptr->mBits.mps = mps;
137 diepctl_ptr->mBits.set_nak = 0x1;
141 /*****************************************************************************/
142 // Description: start endpoint transfer.
143 // Global resource dependence:
144 // Author: jiayong.yang
146 /*****************************************************************************/
147 LOCAL void usb_start_transfer (USB_EP_NUM_E ep_num, BOOLEAN dir, uint32 transfer_size, BOOLEAN is_dma, uint32 *buffer)
149 uint16 packet_count = 0;
153 volatile USB_DOEPTSIZ_U *doeptsiz_ptr = (USB_DOEPTSIZ_U *) USB_DOEPTSIZ (ep_num);
154 volatile USB_DOEPCTL_U *doepctl_ptr = (USB_DOEPCTL_U *) USB_DOEPCTL (ep_num);
158 // Dcache_InvalRegion((unsigned int)buffer, MAX_RECV_LENGTH);
159 * (volatile uint32 *) USB_DOEPDMA (ep_num) = (uint32) buffer;
162 doeptsiz_ptr->mBits.transfer_size = MAX_RECV_LENGTH; // transfer size
163 doeptsiz_ptr->mBits.packet_count = (MAX_RECV_LENGTH+doepctl_ptr->mBits.mps-1)/doepctl_ptr->mBits.mps;
164 * (volatile uint32 *) USB_DOEPCTL (ep_num) |= (unsigned int) BIT_26; // clear nak
165 * (volatile uint32 *) USB_DOEPCTL (ep_num) |= (unsigned int) BIT_31; // endpoint enable
169 volatile USB_DIEPTSIZ_U *dieptsiz_ptr = (USB_DIEPTSIZ_U *) USB_DIEPTSIZ (ep_num);
170 volatile USB_DIEPCTL_U *diepctl_ptr = (USB_DIEPCTL_U *) USB_DIEPCTL (ep_num);
175 #if defined CONFIG_SC8810 || defined CONFIG_SC8825 || defined CONFIG_SC8830 || defined(CONFIG_SC9630)
176 Dcache_CleanRegion((unsigned int)buffer, transfer_size);
178 * (volatile uint32 *) USB_DIEPDMA (ep_num) = (uint32) buffer;
181 dieptsiz_ptr->mBits.transfer_size = transfer_size; // transfer size
182 packet_count = (transfer_size+diepctl_ptr->mBits.mps-1) /diepctl_ptr->mBits.mps;
183 dieptsiz_ptr->mBits.packet_count = packet_count; // packet count
184 diepctl_ptr->mBits.tx_fifo_number = ep_num; // tx fifo number
186 * (volatile uint32 *) USB_DIEPCTL (ep_num) |= (unsigned int) BIT_26; // clear nak
187 * (volatile uint32 *) USB_DIEPCTL (ep_num) |= (unsigned int) BIT_31; // endpoint enable
192 /*****************************************************************************/
193 // Description: process desecriptor request.
194 // Global resource dependence:
195 // Author: jiayong.yang
197 /*****************************************************************************/
198 LOCAL void usb_get_descriptor (USB_REQUEST_1_U *request1, USB_REQUEST_2_U *request2)
201 uint8 *send_data=NULL;
204 length = (uint32) request2->mBits.length_l;
206 switch (request1->mBits.value_m)
209 case USB_DEVICE_DESCRIPTOR_TYPE:
211 send_data = (uint8 *) UCOM_Get_DevDesc();//lint !e718
212 EPI0_config (0x12, 0x1, TRUE, (uint32 *) send_data);
216 case USB_CONFIGURATION_DESCRIPTOR_TYPE:
218 send_data = (uint8 *) UCOM_Get_CfgDesc();//lint !e718
222 EPI0_config (0x20, 0x1, TRUE, (uint32 *) send_data);
226 EPI0_config (length, 0x1, TRUE, (uint32 *) send_data);
235 /*****************************************************************************/
236 // Description: process setup transaction.
237 // Global resource dependence:
238 // Author: jiayong.yang
240 /*****************************************************************************/
242 LOCAL void usb_setup_handle (void)
244 uint32 vendor_ack = 0;
245 USB_REQUEST_1_U *request1;
246 USB_REQUEST_2_U *request2;
248 request1 = (USB_REQUEST_1_U *) (unsigned int) (&s_setup_packet[0]);
249 request2 = (USB_REQUEST_2_U *) (unsigned int) (&s_setup_packet[1]);
251 switch (request1->mBits.type)
254 case USB_REQ_STANDARD://standard
256 switch (request1->mBits.brequest)
258 case USB_REQUEST_SET_ADDRESS:
260 volatile USB_DCFG_U *dcfg_ptr = (USB_DCFG_U *) USB_DCFG;
262 dcfg_ptr->mBits.devaddr = request1->mBits.value_l;
263 EPI0_config (0, 1, FALSE, NULL);
266 case USB_REQUEST_GET_DESCRIPTOR:
268 usb_get_descriptor (request1, request2);
271 case USB_REQUEST_SET_CONFIGURATION:
272 EPI0_config (0, 1, FALSE, NULL);
275 EPI0_config (0, 1, TRUE, &vendor_ack);
281 case USB_REQ_CLASS://class
283 switch (request1->mBits.recipient)
285 case USB_REC_INTERFACE:
287 if ( (0x01 == request1->mBits.value_l)
288 && (0x06 == request1->mBits.value_m))
291 usb_EPActive (USB_EP5, USB_EP_DIR_IN);
292 usb_EPActive (USB_EP6, USB_EP_DIR_OUT);
295 EPI0_config (0, 1, FALSE, NULL);
298 EPI0_config (0, 1, TRUE, NULL);
304 EPI0_config (4, 1, TRUE, &vendor_ack);
307 EPI0_config (0, 1, TRUE, NULL);
312 /*****************************************************************************/
313 // Description: usb reset interrupt handler.
314 // Global resource dependence:
315 // Author: jiayong.yang
317 /*****************************************************************************/
319 LOCAL void usb_reset_handler (void)
324 //SCI_TraceLow("enter usb reset.\r\n");
326 * (volatile uint32 *) USB_GINTMSK &= (unsigned int) (~BIT_12); // disable reset interrupt
328 * (volatile uint32 *) USB_DOEP0CTL |= (unsigned int) BIT_27; // set NAK for all OUT endpoint
330 * (volatile uint32 *) USB_DOEPCTL (6) |= (unsigned int) BIT_27;
332 * (volatile uint32 *) USB_DAINTMSK |= (unsigned int) (BIT_0|BIT_16);
333 * (volatile uint32 *) USB_DOEPMSK |= (unsigned int) (BIT_0|BIT_3|BIT_2|BIT_1);
334 * (volatile uint32 *) USB_DIEPMSK |= (unsigned int) (BIT_0|BIT_3|BIT_1|BIT_2|BIT_5);//lint !e718
336 * (volatile uint32 *) USB_GRXFSIZ = (unsigned int) (BIT_2|BIT_4|BIT_9); //RX fifo ,276 Dword,start address is 0
337 * (volatile uint32 *) USB_GNPTXFSIZ = (unsigned int) ( (BIT_2|BIT_4|BIT_9) |BIT_21); //EP0 TX fifo, 32 Dword, start address is 0+276=276
338 * (volatile uint32 *) USB_DIEPTXF (5) = (unsigned int) ( (BIT_2|BIT_4|BIT_5|BIT_9) |BIT_23); //lint !e718//EP5 TX fifo, 64 Dword, start address is 276+32 = 308
340 * (volatile uint32 *) USB_GRSTCTL |= (unsigned int) BIT_5; //reflush tx fifo
342 while ( (* (volatile uint32 *) USB_GRSTCTL) & ( (unsigned int) BIT_5))
346 if (timeout >= USB_TIMEOUT)
353 * (volatile uint32 *) USB_GRSTCTL |= (unsigned int) BIT_4; //reflush rx fifo
355 while ( (* (volatile uint32 *) USB_GRSTCTL) & ( (unsigned int) BIT_4))
359 if (timeout >= USB_TIMEOUT)
365 Dcache_InvalRegion((unsigned int)s_setup_packet, sizeof(s_setup_packet));
366 EPO0_config (TRUE, s_setup_packet);
368 * (volatile uint32 *) USB_GINTMSK |= (unsigned int) BIT_12; // enable reset interrupt
370 * (volatile uint32 *) USB_GINTSTS |= (unsigned int) BIT_12; //clear reset interrupt
374 /*****************************************************************************/
375 // Description: usb enumeration done handler.
376 // Global resource dependence:
377 // Author: jiayong.yang
379 /*****************************************************************************/
381 void usb_enumeration_done (void)
383 volatile USB_DSTS_U *dsts_ptr = (USB_DSTS_U *) USB_DSTS;
385 enum_speed = dsts_ptr->mBits.enumspd; //read enumration speed
386 //SCI_TraceLow("usb_enumeration_done: device_speed = %d\r\n",enum_speed);
388 * (volatile uint32 *) USB_DIEP0CTL &= (unsigned int) (~ (BIT_0|BIT_1));
390 EPn_config (USB_EP5, USB_EP_TYPE_BULK, USB_EP_DIR_IN, USB_PACKET_64);
391 EPn_config (USB_EP6, USB_EP_TYPE_BULK, USB_EP_DIR_OUT, USB_PACKET_64);
393 Dcache_InvalRegion((unsigned int)s_setup_packet, sizeof(s_setup_packet));
394 EPO0_config (TRUE, s_setup_packet);
396 * (volatile uint32 *) USB_DCTL |= (unsigned int) BIT_8;
398 * (volatile uint32 *) USB_GINTSTS |= (unsigned int) BIT_13;
401 /*****************************************************************************/
402 // Description: out endpoint6 handler.
403 // Global resource dependence:
404 // Author: jiayong.yang
406 /*****************************************************************************/
407 LOCAL void usb_EP6_handle (void)
409 volatile USB_DOEPINT_U *doepint_ptr = (USB_DOEPINT_U *) USB_DOEPINT (USB_EP6);
410 volatile USB_DOEPINT_U doepint;
411 volatile USB_DOEPTSIZ_U *doeptsiz_ptr = (USB_DOEPTSIZ_U *) USB_DOEPTSIZ (USB_EP6);
412 volatile uint32 mask;
414 mask = * (volatile uint32 *) USB_DOEPMSK;
415 doepint.dwValue = doepint_ptr->dwValue;
417 doepint.dwValue &= (unsigned int) mask;
419 if (doepint.mBits.transfer_com)
421 doepint_ptr->mBits.transfer_com = 1;
422 recv_length = MAX_RECV_LENGTH - doeptsiz_ptr->mBits.transfer_size;
423 Dcache_InvalRegion((unsigned int)(&usb_out_endpoint_buf[currentDmaBufferIndex][0]), MAX_RECV_LENGTH);
425 * (volatile uint32 *) USB_DOEPMSK |= (unsigned int) BIT_13;
426 * (volatile uint32 *) USB_DOEPMSK |= (unsigned int) BIT_4;
427 * (volatile uint32 *) USB_DOEPMSK &= (unsigned int) (~BIT_0);
429 else if (doepint.mBits.nak)
431 usb_start_transfer (USB_EP6, USB_EP_DIR_OUT, 1, TRUE, (uint32 *) usb_out_endpoint_buf[currentDmaBufferIndex]);
432 * (volatile uint32 *) USB_DOEPMSK &= (unsigned int) (~BIT_13);
433 * (volatile uint32 *) USB_DOEPMSK |= (unsigned int) BIT_0;
434 doepint_ptr->mBits.nak = 0x1;
437 else if (doepint.mBits.bbleerr)
439 doepint_ptr->mBits.bbleerr = 0x01;
442 /*****************************************************************************/
443 // Description: out endpoint0 handler.
444 // Global resource dependence:
445 // Author: jiayong.yang
447 /*****************************************************************************/
449 LOCAL void usb_EP0_out_handle (void)
451 volatile USB_DOEPINT_U *doepint_ptr = (USB_DOEPINT_U *) USB_DOEPINT (0);
453 if (doepint_ptr->mBits.timeout_condi)
458 if (doepint_ptr->mBits.transfer_com)
460 * (volatile uint32 *) USB_DOEP0CTL |= (unsigned int) BIT_27;
461 doepint_ptr->mBits.transfer_com = 0x1;
464 if (doepint_ptr->mBits.outtokenfifoemp)
466 doepint_ptr->mBits.outtokenfifoemp = 0x1;
469 doepint_ptr->dwValue = 0xffffffff;// clear all interrupt
471 Dcache_InvalRegion((unsigned int)s_setup_packet, sizeof(s_setup_packet));
472 EPO0_config (TRUE, s_setup_packet); //renable ep0 nd set packet count
475 /*****************************************************************************/
476 // Description: out endpoint handler.
477 // Global resource dependence:
478 // Author: jiayong.yang
480 /*****************************************************************************/
481 LOCAL void usb_EP_out_handle (void)
483 volatile USB_DAINT_U *daint_ptr = (USB_DAINT_U *) USB_DAINT;
486 daint.dwValue = daint_ptr->dwValue; // disable EP out interrupt
487 * (volatile uint32 *) USB_GINTMSK &= (unsigned int) (~BIT_19);
489 if (daint.mBits.outepint_0)
491 usb_EP0_out_handle();
494 if (daint.mBits.outepint_6)
499 * (volatile uint32 *) USB_GINTMSK |= (unsigned int) BIT_19; // enable reset interrupt
501 /*****************************************************************************/
502 // Description: in endpoint handler.
503 // Global resource dependence:
504 // Author: jiayong.yang
506 /*****************************************************************************/
507 LOCAL void usb_EP_in_handle (void)
509 volatile USB_DAINT_U *daint_ptr = (USB_DAINT_U *) USB_DAINT;
513 * (volatile uint32 *) USB_GINTMSK &= (unsigned int) (~BIT_18); // disable EP in interrupt
514 daint.dwValue = daint_ptr->dwValue;
516 if (daint.mBits.inepint_0)
518 volatile USB_DIEPINT_U *diepint_ptr = (USB_DIEPINT_U *) USB_DIEPINT (0);
520 diepint_ptr->dwValue = 0xFFFFFFFF;
523 if (daint.mBits.inepint_5)
525 volatile USB_DIEPINT_U *diepint_ptr = (USB_DIEPINT_U *) USB_DIEPINT (5);
527 diepint_ptr->dwValue = 0xFFFFFFFF;
530 * (volatile uint32 *) USB_GINTMSK |= (unsigned int) BIT_18; // enable EP in interrupt
533 /*****************************************************************************/
534 // Description: usb interrupt handler.
535 // Global resource dependence:
536 // Author: jiayong.yang
538 /*****************************************************************************/
539 static __inline void usb_handler (void)
541 volatile USB_INTSTS_U *usb_int_ptr = (USB_INTSTS_U *) USB_GINTSTS;
542 volatile USB_INTSTS_U usb_int;
544 usb_int.dwValue = usb_int_ptr->dwValue;
546 // in endpoint interrupt
547 if (usb_int.mBits.iepint)
552 // out endpoint interrupt
553 if (usb_int.mBits.oepint)
558 // enumeration done interrupt
559 if (usb_int.mBits.enumdone)
561 usb_enumeration_done();
565 if (usb_int.mBits.usbrst)
570 /*****************************************************************************/
571 // Description: configure in endpoint ep_id to send message.
572 // Global resource dependence:
573 // Author: jiayong.yang
575 /*****************************************************************************/
576 #define USB_SEND_MAX_TIME 1000
577 PUBLIC int USB_EPxSendData (char ep_id ,unsigned int *pBuf, int len)
579 volatile USB_DIEPTSIZ_U *dieptsiz_ptr = (USB_DIEPTSIZ_U*)USB_DIEPTSIZ(ep_id);
580 volatile USB_DIEPCTL_U *diepctl_ptr = (USB_DIEPCTL_U *) USB_DIEPCTL (ep_id);
581 uint32 old_tick, new_tick;
582 uint32 split_len = 0;
587 usb_start_transfer ( (USB_EP_NUM_E) ep_id, USB_EP_DIR_IN, len - split_len, TRUE, (uint32 *) pBuf);
588 old_tick = new_tick = SCI_GetTickCount();
589 while(dieptsiz_ptr->dwValue){
590 new_tick = SCI_GetTickCount();
591 if(new_tick - old_tick > USB_SEND_MAX_TIME){
594 dieptsiz_ptr = (USB_DIEPTSIZ_U*)USB_DIEPTSIZ(ep_id);
596 usb_start_transfer ( (USB_EP_NUM_E) ep_id, USB_EP_DIR_IN, split_len, TRUE, (uint32 *) ((uint32)pBuf + len - split_len));
598 usb_start_transfer ( (USB_EP_NUM_E) ep_id, USB_EP_DIR_IN, len, TRUE, (uint32 *) pBuf);
600 old_tick = new_tick = SCI_GetTickCount();
601 while(dieptsiz_ptr->dwValue){
602 new_tick = SCI_GetTickCount();
603 if(new_tick - old_tick > USB_SEND_MAX_TIME){
606 dieptsiz_ptr = (USB_DIEPTSIZ_U*)USB_DIEPTSIZ(ep_id);
607 if(diepctl_ptr->mBits.nak_status) {
608 if(dieptsiz_ptr->mBits.transfer_size ==0)
609 * (volatile uint32 *) USB_DIEPCTL (ep_id) |= (unsigned int) BIT_26;
611 * (volatile uint32 *) USB_DIEPCTL (ep_id) |= (unsigned int) BIT_30;
612 * (volatile uint32 *) USB_DIEPCTL (ep_id) |= (unsigned int) (BIT_31|BIT_26);
619 /*****************************************************************************/
620 // Description: initialize the usb core.
621 // Global resource dependence:
622 // Author: jiayong.yang
624 /*****************************************************************************/
625 PUBLIC void usb_core_init (void)
627 * (volatile uint32 *) USB_GAHBCFG |= (unsigned int) BIT_5;
628 * (volatile uint32 *) USB_DOEPMSK |= (unsigned int) BIT_13;
635 char VCOM_GetChar (void)
638 if (readIndex == recv_length)
647 nIndex = currentDmaBufferIndex;
648 //Dcache_InvalRegion((unsigned int)(&usb_out_endpoint_buf[nIndex][0]), MAX_RECV_LENGTH);
650 currentDmaBufferIndex ^= 0x1;
658 return usb_out_endpoint_buf[nIndex][readIndex++];
661 int VCOM_GetSingleChar (void)
663 if (readIndex == recv_length)
672 nIndex = currentDmaBufferIndex;
673 currentDmaBufferIndex ^= 0x1;
682 //printf("readIndex = %d recv_length = %d nIndex = %d error_count = %d\n", readIndex, recv_length, nIndex, error_count);
684 /*if ((error_count >= 6583) && (error_count <= 6585)) {
686 printf("%s %d error_count = %d\n", __FUNCTION__, __LINE__, error_count);
687 for (aaa = 0; aaa < recv_length; aaa ++) {
690 printf(" %02x", usb_out_endpoint_buf[nIndex][aaa]);
698 return (int)usb_out_endpoint_buf[nIndex][readIndex++];
701 int VCOM_Read(const unsigned char* buf, unsigned int len)
703 unsigned char *src, *dest = buf;
704 unsigned escape_flag = 0;
707 if(readIndex == recv_length){
713 if (recv_length > 0){
714 nIndex = currentDmaBufferIndex;
715 currentDmaBufferIndex ^= 0x1;
719 /* We reach an agreement that host can't send
720 a packet whose size exceeds MAX_PKT_SIZE;
722 len = recv_length < len ? recv_length : len;
723 src = usb_out_endpoint_buf[nIndex] + readIndex;
724 /* The last byte is HDLC_FLAG in most cases,
725 so it's picked out from escape process.
727 for(; readIndex < len - 1; readIndex++, src++)
729 if(*src == HDLC_ESCAPE){
732 }else if(escape_flag){
733 *dest++ = *src ^ HDLC_ESCAPE_MASK;
738 /* Check whether it's an entire packet,
739 if so exit this function,
740 otherwise continue to receive data from host.
743 if(*src == HDLC_FLAG)
745 if(*src == HDLC_ESCAPE)
747 else if(escape_flag){
748 *dest++ = *src ^ HDLC_ESCAPE_MASK;