1 /********************************** (C) COPYRIGHT *******************************
2  * File Name          : ch32v10x_usb_host.c
3  * Author             : WCH
4  * Version            : V1.0.0
5  * Date               : 2020/04/30
6  * Description        : This file provides all the USB firmware functions.
7  * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
8  * SPDX-License-Identifier: Apache-2.0
9  *******************************************************************************/
10 #include "ch32v10x_usb_host.h"
11 #include "debug.h"
12 
13 /******************************** HOST DEVICE **********************************/
14 UINT8       UsbDevEndp0Size;
15 UINT8       FoundNewDev;
16 _RootHubDev ThisUsbDev;
17 
18 PUINT8       pHOST_RX_RAM_Addr;
19 PUINT8       pHOST_TX_RAM_Addr;
20 extern UINT8 Com_Buffer[128];
21 
22 __attribute__((aligned(4))) const UINT8 SetupGetDevDescr[] = {USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_DEVICE, 0x00, 0x00, sizeof(USB_DEV_DESCR), 0x00};
23 
24 __attribute__((aligned(4))) const UINT8 SetupGetCfgDescr[] = {USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_CONFIG, 0x00, 0x00, 0x04, 0x00};
25 
26 __attribute__((aligned(4))) const UINT8 SetupSetUsbAddr[] = {USB_REQ_TYP_OUT, USB_SET_ADDRESS, USB_DEVICE_ADDR, 0x00, 0x00, 0x00, 0x00, 0x00};
27 
28 __attribute__((aligned(4))) const UINT8 SetupSetUsbConfig[] = {USB_REQ_TYP_OUT, USB_SET_CONFIGURATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
29 
30 __attribute__((aligned(4))) const UINT8 SetupSetUsbInterface[] = {USB_REQ_RECIP_INTERF, USB_SET_INTERFACE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
31 
32 __attribute__((aligned(4))) const UINT8 SetupClrEndpStall[] = {USB_REQ_TYP_OUT | USB_REQ_RECIP_ENDP, USB_CLEAR_FEATURE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
33 
34 /*********************************************************************
35  * @fn      DisableRootHubPort( )
36  *
37  * @brief  Disable root hub
38  *
39  * @return  none
40  */
DisableRootHubPort(void)41 void DisableRootHubPort(void)
42 {
43 #ifdef FOR_ROOT_UDISK_ONLY
44     CH103DiskStatus = DISK_DISCONNECT;
45 
46 #endif
47 
48 #ifndef DISK_BASE_BUF_LEN
49     ThisUsbDev.DeviceStatus = ROOT_DEV_DISCONNECT;
50     ThisUsbDev.DeviceAddress = 0x00;
51 
52 #endif
53 }
54 
55 /*********************************************************************
56  * @fn      AnalyzeRootHub
57  *
58  * @brief  Analyze root hub state.
59  *
60  * @return  Error
61  */
AnalyzeRootHub(void)62 UINT8 AnalyzeRootHub(void)
63 {
64     UINT8 s;
65 
66     s = ERR_SUCCESS;
67 
68     if(R8_USB_MIS_ST & RB_UMS_DEV_ATTACH)
69     {
70 #ifdef DISK_BASE_BUF_LEN
71         if(CH103DiskStatus == DISK_DISCONNECT
72 
73 #else
74         if(ThisUsbDev.DeviceStatus == ROOT_DEV_DISCONNECT
75 
76 #endif
77            || (R8_UHOST_CTRL & RB_UH_PORT_EN) == 0x00)
78         {
79             DisableRootHubPort();
80 
81 #ifdef DISK_BASE_BUF_LEN
82             CH103DiskStatus = DISK_CONNECT;
83 
84 #else
85             ThisUsbDev.DeviceSpeed = R8_USB_MIS_ST & RB_UMS_DM_LEVEL ? 0 : 1;
86             ThisUsbDev.DeviceStatus = ROOT_DEV_CONNECTED;
87 
88 #endif
89             s = ERR_USB_CONNECT;
90         }
91     }
92 
93 #ifdef DISK_BASE_BUF_LEN
94     else if(CH103DiskStatus >= DISK_CONNECT)
95     {
96 #else
97     else if(ThisUsbDev.DeviceStatus >= ROOT_DEV_CONNECTED)
98     {
99 
100 #endif
101         DisableRootHubPort();
102         if(s == ERR_SUCCESS)
103             s = ERR_USB_DISCON;
104     }
105 
106     return (s);
107 }
108 
109 /*********************************************************************
110  * @fn      SetHostUsbAddr
111  *
112  * @brief  Set USB host address
113  *
114  * @param   addr -  host address
115  *
116  * @return  none
117  */
118 void SetHostUsbAddr(UINT8 addr)
119 {
120     R8_USB_DEV_AD = (R8_USB_DEV_AD & RB_UDA_GP_BIT) | (addr & MASK_USB_ADDR);
121 }
122 
123 #ifndef FOR_ROOT_UDISK_ONLY
124 /*********************************************************************
125  * @fn      SetUsbSpeed
126  *
127  * @brief  Set USB speed.
128  *
129  * @param   FullSpeed - USB speed.
130  *
131  * @return  none
132  */
133 void SetUsbSpeed(UINT8 FullSpeed)
134 {
135     if(FullSpeed)
136     {
137         R8_USB_CTRL &= ~RB_UC_LOW_SPEED;
138         R8_UH_SETUP &= ~RB_UH_PRE_PID_EN;
139     }
140     else
141     {
142         R8_USB_CTRL |= RB_UC_LOW_SPEED;
143     }
144 }
145 #endif
146 
147 /*********************************************************************
148  * @fn      ResetRootHubPort( )
149  *
150  * @brief   Reset root hub
151  *
152  * @return  none
153  */
154 void ResetRootHubPort(void)
155 {
156     UsbDevEndp0Size = DEFAULT_ENDP0_SIZE;
157     SetHostUsbAddr(0x00);
158     R8_UHOST_CTRL &= ~RB_UH_PORT_EN;
159     SetUsbSpeed(1);
160     R8_UHOST_CTRL = (R8_UHOST_CTRL & ~RB_UH_LOW_SPEED) | RB_UH_BUS_RESET;
161     Delay_Ms(15);
162     R8_UHOST_CTRL = R8_UHOST_CTRL & ~RB_UH_BUS_RESET;
163     Delay_Us(250);
164     R8_USB_INT_FG = RB_UIF_DETECT;
165 }
166 
167 /*********************************************************************
168  * @fn      EnableRootHubPort( )
169  *
170  * @brief   Enable root hub.
171  *
172  * @return  ERROR
173  */
174 UINT8 EnableRootHubPort(void)
175 {
176 #ifdef DISK_BASE_BUF_LEN
177     if(CH103DiskStatus < DISK_CONNECT)
178         CH103DiskStatus = DISK_CONNECT;
179 
180 #else
181     if(ThisUsbDev.DeviceStatus < ROOT_DEV_CONNECTED)
182         ThisUsbDev.DeviceStatus = ROOT_DEV_CONNECTED;
183 
184 #endif
185     if(R8_USB_MIS_ST & RB_UMS_DEV_ATTACH)
186     {
187 #ifndef DISK_BASE_BUF_LEN
188         if((R8_UHOST_CTRL & RB_UH_PORT_EN) == 0x00)
189         {
190             ThisUsbDev.DeviceSpeed = (R8_USB_MIS_ST & RB_UMS_DM_LEVEL) ? 0 : 1;
191             if(ThisUsbDev.DeviceSpeed == 0)
192                 R8_UHOST_CTRL |= RB_UH_LOW_SPEED;
193         }
194 
195 #endif
196         R8_UHOST_CTRL |= RB_UH_PORT_EN;
197         return (ERR_SUCCESS);
198     }
199 
200     return (ERR_USB_DISCON);
201 }
202 
203 /*********************************************************************
204  * @fn      WaitUSB_Interrupt
205  *
206  * @brief   Wait USB Interrput.
207  *
208  * @return  ERROR
209  */
210 UINT8 WaitUSB_Interrupt(void)
211 {
212     UINT16 i;
213 
214     for(i = WAIT_USB_TOUT_200US; i != 0 && (R8_USB_INT_FG & RB_UIF_TRANSFER) == 0; i--)
215     {
216         ;
217     }
218     return ((R8_USB_INT_FG & RB_UIF_TRANSFER) ? ERR_SUCCESS : ERR_USB_UNKNOWN);
219 }
220 
221 /*********************************************************************
222  * @fn      USBHostTransact
223  *
224  * @brief   USB host transport transaction
225  * @param   endp_pid: endpoint and PID
226  *          tog: Synchronization flag
227  *          timeout: timeout times
228  *
229  * @return  EEROR:
230  *                         ERR_USB_UNKNOWN
231  *          ERR_USB_DISCON
232  *          ERR_USB_CONNECT
233  *          ERR_SUCCESS
234  */
235 UINT8 USBHostTransact(UINT8 endp_pid, UINT8 tog, UINT32 timeout)
236 {
237     UINT8  TransRetry;
238     UINT8  s, r;
239     UINT16 i;
240 
241     R8_UH_RX_CTRL = R8_UH_TX_CTRL = tog;
242     TransRetry = 0;
243 
244     do
245     {
246         R8_UH_EP_PID = endp_pid;
247         R8_USB_INT_FG = RB_UIF_TRANSFER;
248         for(i = WAIT_USB_TOUT_200US; i != 0 && (R8_USB_INT_FG & RB_UIF_TRANSFER) == 0; i--)
249             ;
250         R8_UH_EP_PID = 0x00;
251         if((R8_USB_INT_FG & RB_UIF_TRANSFER) == 0)
252         {
253             return (ERR_USB_UNKNOWN);
254         }
255 
256         if(R8_USB_INT_FG & RB_UIF_DETECT)
257         {
258             R8_USB_INT_FG = RB_UIF_DETECT;
259             s = AnalyzeRootHub();
260 
261             if(s == ERR_USB_CONNECT)
262                 FoundNewDev = 1;
263 
264 #ifdef DISK_BASE_BUF_LEN
265 
266             if(CH103DiskStatus == DISK_DISCONNECT)
267                 return (ERR_USB_DISCON);
268             if(CH103DiskStatus == DISK_CONNECT)
269                 return (ERR_USB_CONNECT);
270 
271 #else
272             if(ThisUsbDev.DeviceStatus == ROOT_DEV_DISCONNECT)
273                 return (ERR_USB_DISCON);
274             if(ThisUsbDev.DeviceStatus == ROOT_DEV_CONNECTED)
275                 return (ERR_USB_CONNECT);
276 
277 #endif
278             Delay_Us(200);
279         }
280 
281         if(R8_USB_INT_FG & RB_UIF_TRANSFER)
282         {
283             if(R8_USB_INT_ST & RB_UIS_TOG_OK)
284                 return (ERR_SUCCESS);
285             r = R8_USB_INT_ST & MASK_UIS_H_RES;
286             if(r == USB_PID_STALL)
287                 return (r | ERR_USB_TRANSFER);
288 
289             if(r == USB_PID_NAK)
290             {
291                 if(timeout == 0)
292                     return (r | ERR_USB_TRANSFER);
293                 if(timeout < 0xFFFF)
294                     timeout--;
295                 --TransRetry;
296             }
297             else
298                 switch(endp_pid >> 4)
299                 {
300                     case USB_PID_SETUP:
301 
302                     case USB_PID_OUT:
303                         if(r)
304                             return (r | ERR_USB_TRANSFER);
305                         break;
306 
307                     case USB_PID_IN:
308                         if(r == USB_PID_DATA0 && r == USB_PID_DATA1)
309                         {
310                         }
311                         else if(r)
312                             return (r | ERR_USB_TRANSFER);
313                         break;
314 
315                     default:
316                         return (ERR_USB_UNKNOWN);
317                 }
318         }
319         else
320         {
321             R8_USB_INT_FG = 0xFF;
322         }
323         Delay_Us(15);
324     } while(++TransRetry < 3);
325 
326     return (ERR_USB_TRANSFER);
327 }
328 
329 /*********************************************************************
330  * @fn      HostCtrlTransfer
331  *
332  * @brief  Host control transport.
333  *
334  * @param   DataBuf : Receive or send data buffer.
335  *          RetLen  : Data length.
336  *
337  * @return  ERR_USB_BUF_OVER IN
338  *          ERR_SUCCESS
339  */
340 UINT8 HostCtrlTransfer(PUINT8 DataBuf, PUINT8 RetLen)
341 {
342     UINT16 RemLen = 0;
343     UINT8  s, RxLen, RxCnt, TxCnt;
344     PUINT8 pBuf;
345     PUINT8 pLen;
346 
347     pBuf = DataBuf;
348     pLen = RetLen;
349     Delay_Us(200);
350     if(pLen)
351         *pLen = 0;
352 
353     R8_UH_TX_LEN = sizeof(USB_SETUP_REQ);
354     s = USBHostTransact(USB_PID_SETUP << 4 | 0x00, 0x00, 200000 / 20);
355     if(s != ERR_SUCCESS)
356         return (s);
357     R8_UH_RX_CTRL = R8_UH_TX_CTRL = RB_UH_R_TOG | RB_UH_R_AUTO_TOG | RB_UH_T_TOG | RB_UH_T_AUTO_TOG;
358     R8_UH_TX_LEN = 0x01;
359     RemLen = pSetupReq->wLength;
360 
361     if(RemLen && pBuf)
362     {
363         if(pSetupReq->bRequestType & USB_REQ_TYP_IN)
364         {
365             while(RemLen)
366             {
367                 Delay_Us(200);
368                 s = USBHostTransact(USB_PID_IN << 4 | 0x00, R8_UH_RX_CTRL, 200000 / 20);
369                 if(s != ERR_SUCCESS)
370                     return (s);
371                 RxLen = R8_USB_RX_LEN < RemLen ? R8_USB_RX_LEN : RemLen;
372                 RemLen -= RxLen;
373                 if(pLen)
374                     *pLen += RxLen;
375 
376                 for(RxCnt = 0; RxCnt != RxLen; RxCnt++) {
377                     *pBuf = pHOST_RX_RAM_Addr[RxCnt];
378                     pBuf++;
379                 }
380 
381                 if(R8_USB_RX_LEN == 0 || (R8_USB_RX_LEN & (UsbDevEndp0Size - 1)))
382                     break;
383             }
384             R8_UH_TX_LEN = 0x00;
385         }
386         else
387         {
388             while(RemLen)
389             {
390                 Delay_Us(200);
391                 R8_UH_TX_LEN = RemLen >= UsbDevEndp0Size ? UsbDevEndp0Size : RemLen;
392 
393                 for(TxCnt = 0; TxCnt != R8_UH_TX_LEN; TxCnt++){
394                     pHOST_TX_RAM_Addr[TxCnt] = *pBuf;
395                     pBuf++;
396                 }
397 
398                 s = USBHostTransact(USB_PID_OUT << 4 | 0x00, R8_UH_TX_CTRL, 200000 / 20);
399                 if(s != ERR_SUCCESS)
400                     return (s);
401                 RemLen -= R8_UH_TX_LEN;
402                 if(pLen)
403                     *pLen += R8_UH_TX_LEN;
404             }
405         }
406     }
407 
408     Delay_Us(200);
409     s = USBHostTransact((R8_UH_TX_LEN ? USB_PID_IN << 4 | 0x00 : USB_PID_OUT << 4 | 0x00), RB_UH_R_TOG | RB_UH_T_TOG, 200000 / 20);
410     if(s != ERR_SUCCESS)
411         return (s);
412     if(R8_UH_TX_LEN == 0)
413         return (ERR_SUCCESS);
414     if(R8_USB_RX_LEN == 0)
415         return (ERR_SUCCESS);
416 
417     return (ERR_USB_BUF_OVER);
418 }
419 
420 /*********************************************************************
421  * @fn      CopySetupReqPkg
422  *
423  * @brief  Copy setup request package.
424  *
425  * @param   pReqPkt: setup request package address.
426  *
427  * @return  none
428  */
429 void CopySetupReqPkg(const UINT8 *pReqPkt)
430 {
431     UINT8 i;
432 
433     for(i = 0; i != sizeof(USB_SETUP_REQ); i++) {
434         ((PUINT8)pSetupReq)[i] = *pReqPkt;
435         pReqPkt++;
436     }
437 }
438 
439 /*********************************************************************
440  * @fn      CtrlGetDeviceDescr
441  *
442  * @brief  Get device descrptor.
443  *
444  * @param   DataBuf: Data buffer.
445  *
446  * @return  ERR_USB_BUF_OVER
447  *          ERR_SUCCESS
448  */
449 UINT8 CtrlGetDeviceDescr(PUINT8 DataBuf)
450 {
451     UINT8 s;
452     UINT8 len;
453 
454     UsbDevEndp0Size = DEFAULT_ENDP0_SIZE;
455     CopySetupReqPkg(SetupGetDevDescr);
456     s = HostCtrlTransfer(DataBuf, &len);
457 
458     if(s != ERR_SUCCESS)
459         return (s);
460     UsbDevEndp0Size = ((PUSB_DEV_DESCR)DataBuf)->bMaxPacketSize0;
461     if(len < ((PUSB_SETUP_REQ)SetupGetDevDescr)->wLength)
462         return (ERR_USB_BUF_OVER);
463 
464     return (ERR_SUCCESS);
465 }
466 
467 /*********************************************************************
468  * @fn      CtrlGetConfigDescr
469  *
470  * @brief  Get configration descrptor.
471  *
472  * @param   DataBuf: Data buffer.
473  *
474  * @return  ERR_USB_BUF_OVER
475  *          ERR_SUCCESS
476  */
477 UINT8 CtrlGetConfigDescr(PUINT8 DataBuf)
478 {
479     UINT8 s;
480     UINT8 len;
481 
482     CopySetupReqPkg(SetupGetCfgDescr);
483     s = HostCtrlTransfer(DataBuf, &len);
484     if(s != ERR_SUCCESS)
485         return (s);
486     if(len < ((PUSB_SETUP_REQ)SetupGetCfgDescr)->wLength)
487         return (ERR_USB_BUF_OVER);
488 
489     len = ((PUSB_CFG_DESCR)DataBuf)->wTotalLength;
490     CopySetupReqPkg(SetupGetCfgDescr);
491     pSetupReq->wLength = len;
492     s = HostCtrlTransfer(DataBuf, &len);
493     if(s != ERR_SUCCESS)
494         return (s);
495 
496     return (ERR_SUCCESS);
497 }
498 
499 /*********************************************************************
500  * @fn      CtrlSetUsbAddress
501  *
502  * @brief   Set USB device address.
503  *
504  * @param   addr: Device address.
505  *
506  * @return  ERR_SUCCESS
507  */
508 UINT8 CtrlSetUsbAddress(UINT8 addr)
509 {
510     UINT8 s;
511 
512     CopySetupReqPkg(SetupSetUsbAddr);
513     pSetupReq->wValue = addr;
514     s = HostCtrlTransfer(NULL, NULL);
515     if(s != ERR_SUCCESS)
516         return (s);
517     SetHostUsbAddr(addr);
518     Delay_Ms(10);
519 
520     return (ERR_SUCCESS);
521 }
522 
523 /*********************************************************************
524  * @fn      CtrlSetUsbConfig
525  *
526  * @brief   Set usb configration.
527  *
528  * @param   cfg: Configration Value.
529  *
530  * @return  ERR_SUCCESS
531  */
532 UINT8 CtrlSetUsbConfig(UINT8 cfg)
533 {
534     CopySetupReqPkg(SetupSetUsbConfig);
535     pSetupReq->wValue = cfg;
536     return (HostCtrlTransfer(NULL, NULL));
537 }
538 
539 /*********************************************************************
540  * @fn      CtrlClearEndpStall
541  *
542  * @brief   Clear endpoint STALL.
543  *
544  * @param   endp: Endpoint address.
545  *
546  * @return  ERR_SUCCESS
547  */
548 UINT8 CtrlClearEndpStall(UINT8 endp)
549 {
550     CopySetupReqPkg(SetupClrEndpStall);
551     pSetupReq->wIndex = endp;
552     return (HostCtrlTransfer(NULL, NULL));
553 }
554 
555 /*********************************************************************
556  * @fn      CtrlSetUsbIntercace
557  *
558  * @brief   Set USB Interface configration.
559  *
560  * @param   cfg: Configration value.
561  *
562  * @return  ERR_SUCCESS
563  */
564 UINT8 CtrlSetUsbIntercace(UINT8 cfg)
565 {
566     CopySetupReqPkg(SetupSetUsbInterface);
567     pSetupReq->wValue = cfg;
568     return (HostCtrlTransfer(NULL, NULL));
569 }
570 
571 /*********************************************************************
572  * @fn      USB_HostInit
573  *
574  * @brief   Initializes USB host mode.
575  *
576  * @return  ERR_SUCCESS
577  */
578 void USB_HostInit(void)
579 {
580     R8_USB_CTRL = RB_UC_HOST_MODE;
581     R8_UHOST_CTRL = 0;
582     R8_USB_DEV_AD = 0x00;
583     R8_UH_EP_MOD = RB_UH_EP_TX_EN | RB_UH_EP_RX_EN;
584     R16_UH_RX_DMA = (UINT16)(UINT32)pHOST_RX_RAM_Addr;
585     R16_UH_TX_DMA = (UINT16)(UINT32)pHOST_TX_RAM_Addr;
586 
587     R8_UH_RX_CTRL = 0x00;
588     R8_UH_TX_CTRL = 0x00;
589     R8_USB_CTRL = RB_UC_HOST_MODE | RB_UC_INT_BUSY | RB_UC_DMA_EN;
590     R8_UH_SETUP = RB_UH_SOF_EN;
591     R8_USB_INT_FG = 0xFF;
592     DisableRootHubPort();
593     R8_USB_INT_EN = RB_UIE_TRANSFER | RB_UIE_DETECT;
594 
595     FoundNewDev = 0;
596 }
597 
598 /*********************************************************************
599  * @fn      InitRootDevice
600  *
601  * @brief   Initializes USB root hub.
602  *
603  * @param   DataBuf: Data buffer.
604  *
605  * @return  ERROR
606  */
607 UINT8 InitRootDevice(PUINT8 DataBuf)
608 {
609     UINT8 i, s;
610     UINT8 cfg, dv_cls, if_cls;
611 
612     ResetRootHubPort();
613 
614     for(i = 0, s = 0; i < 100; i++)
615     {
616         Delay_Ms(1);
617         if(EnableRootHubPort() == ERR_SUCCESS)
618         {
619             i = 0;
620             s++;
621             if(s > 100)
622                 break;
623         }
624     }
625 
626     if(i)
627     {
628         DisableRootHubPort();
629         return (ERR_USB_DISCON);
630     }
631 
632     SetUsbSpeed(ThisUsbDev.DeviceSpeed);
633 
634     s = CtrlGetDeviceDescr(DataBuf);
635 
636     if(s == ERR_SUCCESS)
637     {
638         ThisUsbDev.DeviceVID = ((PUSB_DEV_DESCR)DataBuf)->idVendor;
639         ThisUsbDev.DevicePID = ((PUSB_DEV_DESCR)DataBuf)->idProduct;
640         dv_cls = ((PUSB_DEV_DESCR)DataBuf)->bDeviceClass;
641 
642         s = CtrlSetUsbAddress(((PUSB_SETUP_REQ)SetupSetUsbAddr)->wValue);
643 
644         if(s == ERR_SUCCESS)
645         {
646             ThisUsbDev.DeviceAddress = ((PUSB_SETUP_REQ)SetupSetUsbAddr)->wValue;
647 
648             s = CtrlGetConfigDescr(DataBuf);
649 
650             if(s == ERR_SUCCESS)
651             {
652                 cfg = ((PUSB_CFG_DESCR)DataBuf)->bConfigurationValue;
653                 if_cls = ((PUSB_CFG_DESCR_LONG)DataBuf)->itf_descr.bInterfaceClass;
654 
655                 if((dv_cls == 0x00) && (if_cls == USB_DEV_CLASS_STORAGE))
656                 {
657 #ifdef FOR_ROOT_UDISK_ONLY
658                     CH103DiskStatus = DISK_USB_ADDR;
659                     return (ERR_SUCCESS);
660                 }
661                 else
662                     return (ERR_USB_UNSUPPORT);
663 
664 #else
665                     s = CtrlSetUsbConfig(cfg);
666 
667                     if(s == ERR_SUCCESS)
668                     {
669                         ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
670                         ThisUsbDev.DeviceType = USB_DEV_CLASS_STORAGE;
671                         SetUsbSpeed(1);
672                         return (ERR_SUCCESS);
673                     }
674                 }
675                 else if((dv_cls == 0x00) && (if_cls == USB_DEV_CLASS_PRINTER) && ((PUSB_CFG_DESCR_LONG)DataBuf)->itf_descr.bInterfaceSubClass == 0x01)
676                 {
677                     s = CtrlSetUsbConfig(cfg);
678                     if(s == ERR_SUCCESS)
679                     {
680                         ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
681                         ThisUsbDev.DeviceType = USB_DEV_CLASS_PRINTER;
682                         SetUsbSpeed(1);
683                         return (ERR_SUCCESS);
684                     }
685                 }
686                 else if((dv_cls == 0x00) && (if_cls == USB_DEV_CLASS_HID) && ((PUSB_CFG_DESCR_LONG)DataBuf)->itf_descr.bInterfaceSubClass <= 0x01)
687                 {
688                     if_cls = ((PUSB_CFG_DESCR_LONG)DataBuf)->itf_descr.bInterfaceProtocol;
689                     s = CtrlSetUsbConfig(cfg);
690                     if(s == ERR_SUCCESS)
691                     {
692                         ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
693                         if(if_cls == 1)
694                         {
695                             ThisUsbDev.DeviceType = DEV_TYPE_KEYBOARD;
696                             SetUsbSpeed(1);
697                             return (ERR_SUCCESS);
698                         }
699                         else if(if_cls == 2)
700                         {
701                             ThisUsbDev.DeviceType = DEV_TYPE_MOUSE;
702                             SetUsbSpeed(1);
703                             return (ERR_SUCCESS);
704                         }
705                         s = ERR_USB_UNSUPPORT;
706                     }
707                 }
708                 else
709                 {
710                     s = CtrlSetUsbConfig(cfg);
711                     if(s == ERR_SUCCESS)
712                     {
713                         ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
714                         ThisUsbDev.DeviceType = DEV_TYPE_UNKNOW;
715                         SetUsbSpeed(1);
716                         return (ERR_SUCCESS);
717                     }
718                 }
719 
720 #endif
721             }
722         }
723     }
724 
725 #ifdef FOR_ROOT_UDISK_ONLY
726     CH103DiskStatus = DISK_CONNECT;
727 
728 #else
729     ThisUsbDev.DeviceStatus = ROOT_DEV_FAILED;
730 
731 #endif
732 
733     SetUsbSpeed(1);
734 
735     return (s);
736 }
737 
738 /*********************************************************************
739  * @fn      HubGetPortStatus
740  *
741  * @brief   ��ѯHUB�˿�״̬,������Com_Buffer��
742  *
743  * @param   UINT8 HubPortIndex
744  *
745  * @return  ERR_SUCCESS �ɹ�
746  *          ERR_USB_BUF_OVER ���ȴ���
747  */
HubGetPortStatus(UINT8 HubPortIndex)748 UINT8 HubGetPortStatus(UINT8 HubPortIndex)
749 {
750     UINT8 s;
751     UINT8 len;
752 
753     pSetupReq->bRequestType = HUB_GET_PORT_STATUS;
754     pSetupReq->bRequest = HUB_GET_STATUS;
755     pSetupReq->wValue = 0x0000;
756     pSetupReq->wIndex = 0x0000 | HubPortIndex;
757     pSetupReq->wLength = 0x0004;
758     s = HostCtrlTransfer(Com_Buffer, &len); // ִ�п��ƴ���
759     if(s != ERR_SUCCESS)
760     {
761         return (s);
762     }
763     if(len < 4)
764     {
765         return (ERR_USB_BUF_OVER); // ���������ȴ���
766     }
767 
768     return (ERR_SUCCESS);
769 }
770 
771 /*********************************************************************
772  * @fn      HubSetPortFeature
773  *
774  * @brief   ����HUB�˿�����
775  *
776  * @param   UINT8 HubPortIndex
777  *          UINT8 FeatureSelt
778  *
779  * @return  ERR_SUCCESS �ɹ�
780  */
HubSetPortFeature(UINT8 HubPortIndex,UINT8 FeatureSelt)781 UINT8 HubSetPortFeature(UINT8 HubPortIndex, UINT8 FeatureSelt)
782 {
783     pSetupReq->bRequestType = HUB_SET_PORT_FEATURE;
784     pSetupReq->bRequest = HUB_SET_FEATURE;
785     pSetupReq->wValue = 0x0000 | FeatureSelt;
786     pSetupReq->wIndex = 0x0000 | HubPortIndex;
787     pSetupReq->wLength = 0x0000;
788     return (HostCtrlTransfer(NULL, NULL)); // ִ�п��ƴ���
789 }
790 
791 /*********************************************************************
792  * @fn      HubClearPortFeature
793  *
794  * @brief   ���HUB�˿�����
795  *
796  * @param   UINT8 HubPortIndex
797  *          UINT8 FeatureSelt
798  *
799  * @return  ERR_SUCCESS �ɹ�
800  */
HubClearPortFeature(UINT8 HubPortIndex,UINT8 FeatureSelt)801 UINT8 HubClearPortFeature(UINT8 HubPortIndex, UINT8 FeatureSelt)
802 {
803     pSetupReq->bRequestType = HUB_CLEAR_PORT_FEATURE;
804     pSetupReq->bRequest = HUB_CLEAR_FEATURE;
805     pSetupReq->wValue = 0x0000 | FeatureSelt;
806     pSetupReq->wIndex = 0x0000 | HubPortIndex;
807     pSetupReq->wLength = 0x0000;
808     return (HostCtrlTransfer(NULL, NULL)); // ִ�п��ƴ���
809 }
810