Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
usb_core.c
00001 /******************** (C) COPYRIGHT 2010 STMicroelectronics ******************** 00002 * File Name : usb_core.c 00003 * Author : MCD Application Team 00004 * Version : V3.2.1 00005 * Date : 07/05/2010 00006 * Description : Standard protocol processing (USB v2.0) 00007 ******************************************************************************** 00008 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00009 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 00010 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 00011 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 00012 * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 00013 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00014 *******************************************************************************/ 00015 00016 /* Includes ------------------------------------------------------------------*/ 00017 #include "usb_lib.h" 00018 /* Private typedef -----------------------------------------------------------*/ 00019 /* Private define ------------------------------------------------------------*/ 00020 #define ValBit(VAR,Place) (VAR & (1 << Place)) 00021 #define SetBit(VAR,Place) (VAR |= (1 << Place)) 00022 #define ClrBit(VAR,Place) (VAR &= ((1 << Place) ^ 255)) 00023 00024 #ifdef STM32F10X_CL 00025 #define Send0LengthData() {PCD_EP_Write (0, 0, 0) ; vSetEPTxStatus(EP_TX_VALID);} 00026 #else 00027 #define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \ 00028 vSetEPTxStatus(EP_TX_VALID); \ 00029 } 00030 #endif /* STM32F10X_CL */ 00031 00032 #define vSetEPRxStatus(st) (SaveRState = st) 00033 #define vSetEPTxStatus(st) (SaveTState = st) 00034 00035 #define USB_StatusIn() Send0LengthData() 00036 #define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID) 00037 00038 #define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */ 00039 #define StatusInfo1 StatusInfo.bw.bb0 00040 00041 /* Private macro -------------------------------------------------------------*/ 00042 /* Private variables ---------------------------------------------------------*/ 00043 uint16_t_uint8_t StatusInfo; 00044 00045 bool Data_Mul_MaxPacketSize = FALSE; 00046 /* Private function prototypes -----------------------------------------------*/ 00047 static void DataStageOut(void); 00048 static void DataStageIn(void); 00049 static void NoData_Setup0(void); 00050 static void Data_Setup0(void); 00051 /* Private functions ---------------------------------------------------------*/ 00052 00053 /******************************************************************************* 00054 * Function Name : Standard_GetConfiguration. 00055 * Description : Return the current configuration variable address. 00056 * Input : Length - How many bytes are needed. 00057 * Output : None. 00058 * Return : Return 1 , if the request is invalid when "Length" is 0. 00059 * Return "Buffer" if the "Length" is not 0. 00060 *******************************************************************************/ 00061 uint8_t *Standard_GetConfiguration(uint16_t Length) 00062 { 00063 if (Length == 0) 00064 { 00065 pInformation->Ctrl_Info.Usb_wLength = 00066 sizeof(pInformation->Current_Configuration); 00067 return 0; 00068 } 00069 pUser_Standard_Requests->User_GetConfiguration(); 00070 return (uint8_t *)&pInformation->Current_Configuration; 00071 } 00072 00073 /******************************************************************************* 00074 * Function Name : Standard_SetConfiguration. 00075 * Description : This routine is called to set the configuration value 00076 * Then each class should configure device themself. 00077 * Input : None. 00078 * Output : None. 00079 * Return : Return USB_SUCCESS, if the request is performed. 00080 * Return USB_UNSUPPORT, if the request is invalid. 00081 *******************************************************************************/ 00082 RESULT Standard_SetConfiguration(void) 00083 { 00084 00085 if ((pInformation->USBwValue0 <= 00086 Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0) 00087 && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/ 00088 { 00089 pInformation->Current_Configuration = pInformation->USBwValue0; 00090 pUser_Standard_Requests->User_SetConfiguration(); 00091 return USB_SUCCESS; 00092 } 00093 else 00094 { 00095 return USB_UNSUPPORT; 00096 } 00097 } 00098 00099 /******************************************************************************* 00100 * Function Name : Standard_GetInterface. 00101 * Description : Return the Alternate Setting of the current interface. 00102 * Input : Length - How many bytes are needed. 00103 * Output : None. 00104 * Return : Return 0, if the request is invalid when "Length" is 0. 00105 * Return "Buffer" if the "Length" is not 0. 00106 *******************************************************************************/ 00107 uint8_t *Standard_GetInterface(uint16_t Length) 00108 { 00109 if (Length == 0) 00110 { 00111 pInformation->Ctrl_Info.Usb_wLength = 00112 sizeof(pInformation->Current_AlternateSetting); 00113 return 0; 00114 } 00115 pUser_Standard_Requests->User_GetInterface(); 00116 return (uint8_t *)&pInformation->Current_AlternateSetting; 00117 } 00118 00119 /******************************************************************************* 00120 * Function Name : Standard_SetInterface. 00121 * Description : This routine is called to set the interface. 00122 * Then each class should configure the interface them self. 00123 * Input : None. 00124 * Output : None. 00125 * Return : - Return USB_SUCCESS, if the request is performed. 00126 * - Return USB_UNSUPPORT, if the request is invalid. 00127 *******************************************************************************/ 00128 RESULT Standard_SetInterface(void) 00129 { 00130 RESULT Re; 00131 /*Test if the specified Interface and Alternate Setting are supported by 00132 the application Firmware*/ 00133 Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0); 00134 00135 if (pInformation->Current_Configuration != 0) 00136 { 00137 if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0) 00138 || (pInformation->USBwValue1 != 0)) 00139 { 00140 return USB_UNSUPPORT; 00141 } 00142 else if (Re == USB_SUCCESS) 00143 { 00144 pUser_Standard_Requests->User_SetInterface(); 00145 pInformation->Current_Interface = pInformation->USBwIndex0; 00146 pInformation->Current_AlternateSetting = pInformation->USBwValue0; 00147 return USB_SUCCESS; 00148 } 00149 00150 } 00151 00152 return USB_UNSUPPORT; 00153 } 00154 00155 /******************************************************************************* 00156 * Function Name : Standard_GetStatus. 00157 * Description : Copy the device request data to "StatusInfo buffer". 00158 * Input : - Length - How many bytes are needed. 00159 * Output : None. 00160 * Return : Return 0, if the request is at end of data block, 00161 * or is invalid when "Length" is 0. 00162 *******************************************************************************/ 00163 uint8_t *Standard_GetStatus(uint16_t Length) 00164 { 00165 if (Length == 0) 00166 { 00167 pInformation->Ctrl_Info.Usb_wLength = 2; 00168 return 0; 00169 } 00170 00171 /* Reset Status Information */ 00172 StatusInfo.w = 0; 00173 00174 if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) 00175 { 00176 /*Get Device Status */ 00177 uint8_t Feature = pInformation->Current_Feature; 00178 00179 /* Remote Wakeup enabled */ 00180 if (ValBit(Feature, 5)) 00181 { 00182 SetBit(StatusInfo0, 1); 00183 } 00184 else 00185 { 00186 ClrBit(StatusInfo0, 1); 00187 } 00188 00189 /* Bus-powered */ 00190 if (ValBit(Feature, 6)) 00191 { 00192 SetBit(StatusInfo0, 0); 00193 } 00194 else /* Self-powered */ 00195 { 00196 ClrBit(StatusInfo0, 0); 00197 } 00198 } 00199 /*Interface Status*/ 00200 else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) 00201 { 00202 return (uint8_t *)&StatusInfo; 00203 } 00204 /*Get EndPoint Status*/ 00205 else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) 00206 { 00207 uint8_t Related_Endpoint; 00208 uint8_t wIndex0 = pInformation->USBwIndex0; 00209 00210 Related_Endpoint = (wIndex0 & 0x0f); 00211 if (ValBit(wIndex0, 7)) 00212 { 00213 /* IN endpoint */ 00214 if (_GetTxStallStatus(Related_Endpoint)) 00215 { 00216 SetBit(StatusInfo0, 0); /* IN Endpoint stalled */ 00217 } 00218 } 00219 else 00220 { 00221 /* OUT endpoint */ 00222 if (_GetRxStallStatus(Related_Endpoint)) 00223 { 00224 SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */ 00225 } 00226 } 00227 00228 } 00229 else 00230 { 00231 return NULL; 00232 } 00233 pUser_Standard_Requests->User_GetStatus(); 00234 return (uint8_t *)&StatusInfo; 00235 } 00236 00237 /******************************************************************************* 00238 * Function Name : Standard_ClearFeature. 00239 * Description : Clear or disable a specific feature. 00240 * Input : None. 00241 * Output : None. 00242 * Return : - Return USB_SUCCESS, if the request is performed. 00243 * - Return USB_UNSUPPORT, if the request is invalid. 00244 *******************************************************************************/ 00245 RESULT Standard_ClearFeature(void) 00246 { 00247 uint32_t Type_Rec = Type_Recipient; 00248 uint32_t Status; 00249 00250 00251 if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) 00252 {/*Device Clear Feature*/ 00253 ClrBit(pInformation->Current_Feature, 5); 00254 return USB_SUCCESS; 00255 } 00256 else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) 00257 {/*EndPoint Clear Feature*/ 00258 DEVICE* pDev; 00259 uint32_t Related_Endpoint; 00260 uint32_t wIndex0; 00261 uint32_t rEP; 00262 00263 if ((pInformation->USBwValue != ENDPOINT_STALL) 00264 || (pInformation->USBwIndex1 != 0)) 00265 { 00266 return USB_UNSUPPORT; 00267 } 00268 00269 pDev = &Device_Table; 00270 wIndex0 = pInformation->USBwIndex0; 00271 rEP = wIndex0 & ~0x80; 00272 Related_Endpoint = ENDP0 + rEP; 00273 00274 if (ValBit(pInformation->USBwIndex0, 7)) 00275 { 00276 /*Get Status of endpoint & stall the request if the related_ENdpoint 00277 is Disabled*/ 00278 Status = _GetEPTxStatus(Related_Endpoint); 00279 } 00280 else 00281 { 00282 Status = _GetEPRxStatus(Related_Endpoint); 00283 } 00284 00285 if ((rEP >= pDev->Total_Endpoint) || (Status == 0) 00286 || (pInformation->Current_Configuration == 0)) 00287 { 00288 return USB_UNSUPPORT; 00289 } 00290 00291 00292 if (wIndex0 & 0x80) 00293 { 00294 /* IN endpoint */ 00295 if (_GetTxStallStatus(Related_Endpoint )) 00296 { 00297 #ifndef STM32F10X_CL 00298 ClearDTOG_TX(Related_Endpoint); 00299 #endif /* STM32F10X_CL */ 00300 SetEPTxStatus(Related_Endpoint, EP_TX_VALID); 00301 } 00302 } 00303 else 00304 { 00305 /* OUT endpoint */ 00306 if (_GetRxStallStatus(Related_Endpoint)) 00307 { 00308 if (Related_Endpoint == ENDP0) 00309 { 00310 /* After clear the STALL, enable the default endpoint receiver */ 00311 SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize); 00312 _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); 00313 } 00314 else 00315 { 00316 #ifndef STM32F10X_CL 00317 ClearDTOG_RX(Related_Endpoint); 00318 #endif /* STM32F10X_CL */ 00319 _SetEPRxStatus(Related_Endpoint, EP_RX_VALID); 00320 } 00321 } 00322 } 00323 pUser_Standard_Requests->User_ClearFeature(); 00324 return USB_SUCCESS; 00325 } 00326 00327 return USB_UNSUPPORT; 00328 } 00329 00330 /******************************************************************************* 00331 * Function Name : Standard_SetEndPointFeature 00332 * Description : Set or enable a specific feature of EndPoint 00333 * Input : None. 00334 * Output : None. 00335 * Return : - Return USB_SUCCESS, if the request is performed. 00336 * - Return USB_UNSUPPORT, if the request is invalid. 00337 *******************************************************************************/ 00338 RESULT Standard_SetEndPointFeature(void) 00339 { 00340 uint32_t wIndex0; 00341 uint32_t Related_Endpoint; 00342 uint32_t rEP; 00343 uint32_t Status; 00344 00345 wIndex0 = pInformation->USBwIndex0; 00346 rEP = wIndex0 & ~0x80; 00347 Related_Endpoint = ENDP0 + rEP; 00348 00349 if (ValBit(pInformation->USBwIndex0, 7)) 00350 { 00351 /* get Status of endpoint & stall the request if the related_ENdpoint 00352 is Disabled*/ 00353 Status = _GetEPTxStatus(Related_Endpoint); 00354 } 00355 else 00356 { 00357 Status = _GetEPRxStatus(Related_Endpoint); 00358 } 00359 00360 if (Related_Endpoint >= Device_Table.Total_Endpoint 00361 || pInformation->USBwValue != 0 || Status == 0 00362 || pInformation->Current_Configuration == 0) 00363 { 00364 return USB_UNSUPPORT; 00365 } 00366 else 00367 { 00368 if (wIndex0 & 0x80) 00369 { 00370 /* IN endpoint */ 00371 _SetEPTxStatus(Related_Endpoint, EP_TX_STALL); 00372 } 00373 00374 else 00375 { 00376 /* OUT endpoint */ 00377 _SetEPRxStatus(Related_Endpoint, EP_RX_STALL); 00378 } 00379 } 00380 pUser_Standard_Requests->User_SetEndPointFeature(); 00381 return USB_SUCCESS; 00382 } 00383 00384 /******************************************************************************* 00385 * Function Name : Standard_SetDeviceFeature. 00386 * Description : Set or enable a specific feature of Device. 00387 * Input : None. 00388 * Output : None. 00389 * Return : - Return USB_SUCCESS, if the request is performed. 00390 * - Return USB_UNSUPPORT, if the request is invalid. 00391 *******************************************************************************/ 00392 RESULT Standard_SetDeviceFeature(void) 00393 { 00394 SetBit(pInformation->Current_Feature, 5); 00395 pUser_Standard_Requests->User_SetDeviceFeature(); 00396 return USB_SUCCESS; 00397 } 00398 00399 /******************************************************************************* 00400 * Function Name : Standard_GetDescriptorData. 00401 * Description : Standard_GetDescriptorData is used for descriptors transfer. 00402 * : This routine is used for the descriptors resident in Flash 00403 * or RAM 00404 * pDesc can be in either Flash or RAM 00405 * The purpose of this routine is to have a versatile way to 00406 * response descriptors request. It allows user to generate 00407 * certain descriptors with software or read descriptors from 00408 * external storage part by part. 00409 * Input : - Length - Length of the data in this transfer. 00410 * - pDesc - A pointer points to descriptor struct. 00411 * The structure gives the initial address of the descriptor and 00412 * its original size. 00413 * Output : None. 00414 * Return : Address of a part of the descriptor pointed by the Usb_ 00415 * wOffset The buffer pointed by this address contains at least 00416 * Length bytes. 00417 *******************************************************************************/ 00418 uint8_t *Standard_GetDescriptorData(uint16_t Length, ONE_DESCRIPTOR *pDesc) 00419 { 00420 uint32_t wOffset; 00421 00422 wOffset = pInformation->Ctrl_Info.Usb_wOffset; 00423 if (Length == 0) 00424 { 00425 pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset; 00426 return 0; 00427 } 00428 00429 return pDesc->Descriptor + wOffset; 00430 } 00431 00432 /******************************************************************************* 00433 * Function Name : DataStageOut. 00434 * Description : Data stage of a Control Write Transfer. 00435 * Input : None. 00436 * Output : None. 00437 * Return : None. 00438 *******************************************************************************/ 00439 void DataStageOut(void) 00440 { 00441 ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; 00442 uint32_t save_rLength; 00443 00444 save_rLength = pEPinfo->Usb_rLength; 00445 00446 if (pEPinfo->CopyData && save_rLength) 00447 { 00448 uint8_t *Buffer; 00449 uint32_t Length; 00450 00451 Length = pEPinfo->PacketSize; 00452 if (Length > save_rLength) 00453 { 00454 Length = save_rLength; 00455 } 00456 00457 Buffer = (*pEPinfo->CopyData)(Length); 00458 pEPinfo->Usb_rLength -= Length; 00459 pEPinfo->Usb_rOffset += Length; 00460 00461 #ifdef STM32F10X_CL 00462 PCD_EP_Read(ENDP0, Buffer, Length); 00463 #else 00464 PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); 00465 #endif /* STM32F10X_CL */ 00466 } 00467 00468 if (pEPinfo->Usb_rLength != 0) 00469 { 00470 vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ 00471 SetEPTxCount(ENDP0, 0); 00472 vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ 00473 } 00474 /* Set the next State*/ 00475 if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) 00476 { 00477 pInformation->ControlState = OUT_DATA; 00478 } 00479 else 00480 { 00481 if (pEPinfo->Usb_rLength > 0) 00482 { 00483 pInformation->ControlState = LAST_OUT_DATA; 00484 } 00485 else if (pEPinfo->Usb_rLength == 0) 00486 { 00487 pInformation->ControlState = WAIT_STATUS_IN; 00488 USB_StatusIn(); 00489 } 00490 } 00491 } 00492 00493 /******************************************************************************* 00494 * Function Name : DataStageIn. 00495 * Description : Data stage of a Control Read Transfer. 00496 * Input : None. 00497 * Output : None. 00498 * Return : None. 00499 *******************************************************************************/ 00500 void DataStageIn(void) 00501 { 00502 ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; 00503 uint32_t save_wLength = pEPinfo->Usb_wLength; 00504 uint32_t ControlState = pInformation->ControlState; 00505 00506 uint8_t *DataBuffer; 00507 uint32_t Length; 00508 00509 if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) 00510 { 00511 if(Data_Mul_MaxPacketSize == TRUE) 00512 { 00513 /* No more data to send and empty packet */ 00514 Send0LengthData(); 00515 ControlState = LAST_IN_DATA; 00516 Data_Mul_MaxPacketSize = FALSE; 00517 } 00518 else 00519 { 00520 /* No more data to send so STALL the TX Status*/ 00521 ControlState = WAIT_STATUS_OUT; 00522 00523 #ifdef STM32F10X_CL 00524 PCD_EP_Read (ENDP0, 0, 0); 00525 #endif /* STM32F10X_CL */ 00526 00527 #ifndef STM32F10X_CL 00528 vSetEPTxStatus(EP_TX_STALL); 00529 #endif /* STM32F10X_CL */ 00530 } 00531 00532 goto Expect_Status_Out; 00533 } 00534 00535 Length = pEPinfo->PacketSize; 00536 ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; 00537 00538 if (Length > save_wLength) 00539 { 00540 Length = save_wLength; 00541 } 00542 00543 DataBuffer = (*pEPinfo->CopyData)(Length); 00544 00545 #ifdef STM32F10X_CL 00546 PCD_EP_Write (ENDP0, DataBuffer, Length); 00547 #else 00548 UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length); 00549 #endif /* STM32F10X_CL */ 00550 00551 SetEPTxCount(ENDP0, Length); 00552 00553 pEPinfo->Usb_wLength -= Length; 00554 pEPinfo->Usb_wOffset += Length; 00555 vSetEPTxStatus(EP_TX_VALID); 00556 00557 USB_StatusOut();/* Expect the host to abort the data IN stage */ 00558 00559 Expect_Status_Out: 00560 pInformation->ControlState = ControlState; 00561 } 00562 00563 /******************************************************************************* 00564 * Function Name : NoData_Setup0. 00565 * Description : Proceed the processing of setup request without data stage. 00566 * Input : None. 00567 * Output : None. 00568 * Return : None. 00569 *******************************************************************************/ 00570 void NoData_Setup0(void) 00571 { 00572 RESULT Result = USB_UNSUPPORT; 00573 uint32_t RequestNo = pInformation->USBbRequest; 00574 uint32_t ControlState; 00575 00576 if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) 00577 { 00578 /* Device Request*/ 00579 /* SET_CONFIGURATION*/ 00580 if (RequestNo == SET_CONFIGURATION) 00581 { 00582 Result = Standard_SetConfiguration(); 00583 } 00584 00585 /*SET ADDRESS*/ 00586 else if (RequestNo == SET_ADDRESS) 00587 { 00588 if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0) 00589 || (pInformation->USBwIndex != 0) 00590 || (pInformation->Current_Configuration != 0)) 00591 /* Device Address should be 127 or less*/ 00592 { 00593 ControlState = STALLED; 00594 goto exit_NoData_Setup0; 00595 } 00596 else 00597 { 00598 Result = USB_SUCCESS; 00599 00600 #ifdef STM32F10X_CL 00601 SetDeviceAddress(pInformation->USBwValue0); 00602 #endif /* STM32F10X_CL */ 00603 } 00604 } 00605 /*SET FEATURE for Device*/ 00606 else if (RequestNo == SET_FEATURE) 00607 { 00608 if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) 00609 && (pInformation->USBwIndex == 0) 00610 && (ValBit(pInformation->Current_Feature, 5))) 00611 { 00612 Result = Standard_SetDeviceFeature(); 00613 } 00614 else 00615 { 00616 Result = USB_UNSUPPORT; 00617 } 00618 } 00619 /*Clear FEATURE for Device */ 00620 else if (RequestNo == CLEAR_FEATURE) 00621 { 00622 if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP 00623 && pInformation->USBwIndex == 0 00624 && ValBit(pInformation->Current_Feature, 5)) 00625 { 00626 Result = Standard_ClearFeature(); 00627 } 00628 else 00629 { 00630 Result = USB_UNSUPPORT; 00631 } 00632 } 00633 00634 } 00635 00636 /* Interface Request*/ 00637 else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) 00638 { 00639 /*SET INTERFACE*/ 00640 if (RequestNo == SET_INTERFACE) 00641 { 00642 Result = Standard_SetInterface(); 00643 } 00644 } 00645 00646 /* EndPoint Request*/ 00647 else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) 00648 { 00649 /*CLEAR FEATURE for EndPoint*/ 00650 if (RequestNo == CLEAR_FEATURE) 00651 { 00652 Result = Standard_ClearFeature(); 00653 } 00654 /* SET FEATURE for EndPoint*/ 00655 else if (RequestNo == SET_FEATURE) 00656 { 00657 Result = Standard_SetEndPointFeature(); 00658 } 00659 } 00660 else 00661 { 00662 Result = USB_UNSUPPORT; 00663 } 00664 00665 00666 if (Result != USB_SUCCESS) 00667 { 00668 Result = (*pProperty->Class_NoData_Setup)(RequestNo); 00669 if (Result == USB_NOT_READY) 00670 { 00671 ControlState = PAUSE; 00672 goto exit_NoData_Setup0; 00673 } 00674 } 00675 00676 if (Result != USB_SUCCESS) 00677 { 00678 ControlState = STALLED; 00679 goto exit_NoData_Setup0; 00680 } 00681 00682 ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */ 00683 00684 USB_StatusIn(); 00685 00686 exit_NoData_Setup0: 00687 pInformation->ControlState = ControlState; 00688 return; 00689 } 00690 00691 /******************************************************************************* 00692 * Function Name : Data_Setup0. 00693 * Description : Proceed the processing of setup request with data stage. 00694 * Input : None. 00695 * Output : None. 00696 * Return : None. 00697 *******************************************************************************/ 00698 void Data_Setup0(void) 00699 { 00700 uint8_t *(*CopyRoutine)(uint16_t); 00701 RESULT Result; 00702 uint32_t Request_No = pInformation->USBbRequest; 00703 00704 uint32_t Related_Endpoint, Reserved; 00705 uint32_t wOffset, Status; 00706 00707 00708 00709 CopyRoutine = NULL; 00710 wOffset = 0; 00711 00712 /*GET DESCRIPTOR*/ 00713 if (Request_No == GET_DESCRIPTOR) 00714 { 00715 if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) 00716 { 00717 uint8_t wValue1 = pInformation->USBwValue1; 00718 if (wValue1 == DEVICE_DESCRIPTOR) 00719 { 00720 CopyRoutine = pProperty->GetDeviceDescriptor; 00721 } 00722 else if (wValue1 == CONFIG_DESCRIPTOR) 00723 { 00724 CopyRoutine = pProperty->GetConfigDescriptor; 00725 } 00726 else if (wValue1 == STRING_DESCRIPTOR) 00727 { 00728 CopyRoutine = pProperty->GetStringDescriptor; 00729 } /* End of GET_DESCRIPTOR */ 00730 } 00731 } 00732 00733 /*GET STATUS*/ 00734 else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0) 00735 && (pInformation->USBwLength == 0x0002) 00736 && (pInformation->USBwIndex1 == 0)) 00737 { 00738 /* GET STATUS for Device*/ 00739 if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) 00740 && (pInformation->USBwIndex == 0)) 00741 { 00742 CopyRoutine = Standard_GetStatus; 00743 } 00744 00745 /* GET STATUS for Interface*/ 00746 else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) 00747 { 00748 if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS) 00749 && (pInformation->Current_Configuration != 0)) 00750 { 00751 CopyRoutine = Standard_GetStatus; 00752 } 00753 } 00754 00755 /* GET STATUS for EndPoint*/ 00756 else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) 00757 { 00758 Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); 00759 Reserved = pInformation->USBwIndex0 & 0x70; 00760 00761 if (ValBit(pInformation->USBwIndex0, 7)) 00762 { 00763 /*Get Status of endpoint & stall the request if the related_ENdpoint 00764 is Disabled*/ 00765 Status = _GetEPTxStatus(Related_Endpoint); 00766 } 00767 else 00768 { 00769 Status = _GetEPRxStatus(Related_Endpoint); 00770 } 00771 00772 if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0) 00773 && (Status != 0)) 00774 { 00775 CopyRoutine = Standard_GetStatus; 00776 } 00777 } 00778 00779 } 00780 00781 /*GET CONFIGURATION*/ 00782 else if (Request_No == GET_CONFIGURATION) 00783 { 00784 if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) 00785 { 00786 CopyRoutine = Standard_GetConfiguration; 00787 } 00788 } 00789 /*GET INTERFACE*/ 00790 else if (Request_No == GET_INTERFACE) 00791 { 00792 if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) 00793 && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0) 00794 && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001) 00795 && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)) 00796 { 00797 CopyRoutine = Standard_GetInterface; 00798 } 00799 00800 } 00801 00802 if (CopyRoutine) 00803 { 00804 pInformation->Ctrl_Info.Usb_wOffset = wOffset; 00805 pInformation->Ctrl_Info.CopyData = CopyRoutine; 00806 /* sb in the original the cast to word was directly */ 00807 /* now the cast is made step by step */ 00808 (*CopyRoutine)(0); 00809 Result = USB_SUCCESS; 00810 } 00811 else 00812 { 00813 Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest); 00814 if (Result == USB_NOT_READY) 00815 { 00816 pInformation->ControlState = PAUSE; 00817 return; 00818 } 00819 } 00820 00821 if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF) 00822 { 00823 /* Data is not ready, wait it */ 00824 pInformation->ControlState = PAUSE; 00825 return; 00826 } 00827 if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0)) 00828 { 00829 /* Unsupported request */ 00830 pInformation->ControlState = STALLED; 00831 return; 00832 } 00833 00834 00835 if (ValBit(pInformation->USBbmRequestType, 7)) 00836 { 00837 /* Device ==> Host */ 00838 __IO uint32_t wLength = pInformation->USBwLength; 00839 00840 /* Restrict the data length to be the one host asks for */ 00841 if (pInformation->Ctrl_Info.Usb_wLength > wLength) 00842 { 00843 pInformation->Ctrl_Info.Usb_wLength = wLength; 00844 } 00845 00846 else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength) 00847 { 00848 if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) 00849 { 00850 Data_Mul_MaxPacketSize = FALSE; 00851 } 00852 else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0) 00853 { 00854 Data_Mul_MaxPacketSize = TRUE; 00855 } 00856 } 00857 00858 pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize; 00859 DataStageIn(); 00860 } 00861 else 00862 { 00863 pInformation->ControlState = OUT_DATA; 00864 vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */ 00865 } 00866 00867 return; 00868 } 00869 00870 /******************************************************************************* 00871 * Function Name : Setup0_Process 00872 * Description : Get the device request data and dispatch to individual process. 00873 * Input : None. 00874 * Output : None. 00875 * Return : Post0_Process. 00876 *******************************************************************************/ 00877 uint8_t Setup0_Process(void) 00878 { 00879 00880 union 00881 { 00882 uint8_t* b; 00883 uint16_t* w; 00884 } pBuf; 00885 00886 #ifdef STM32F10X_CL 00887 USB_OTG_EP *ep; 00888 uint16_t offset = 0; 00889 00890 ep = PCD_GetOutEP(ENDP0); 00891 pBuf.b = ep->xfer_buff; 00892 #else 00893 uint16_t offset = 1; 00894 00895 pBuf.b = PMAAddr + (uint8_t *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */ 00896 #endif /* STM32F10X_CL */ 00897 00898 if (pInformation->ControlState != PAUSE) 00899 { 00900 pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */ 00901 pInformation->USBbRequest = *pBuf.b++; /* bRequest */ 00902 pBuf.w += offset; /* word not accessed because of 32 bits addressing */ 00903 pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */ 00904 pBuf.w += offset; /* word not accessed because of 32 bits addressing */ 00905 pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */ 00906 pBuf.w += offset; /* word not accessed because of 32 bits addressing */ 00907 pInformation->USBwLength = *pBuf.w; /* wLength */ 00908 } 00909 00910 pInformation->ControlState = SETTING_UP; 00911 if (pInformation->USBwLength == 0) 00912 { 00913 /* Setup with no data stage */ 00914 NoData_Setup0(); 00915 } 00916 else 00917 { 00918 /* Setup with data stage */ 00919 Data_Setup0(); 00920 } 00921 return Post0_Process(); 00922 } 00923 00924 /******************************************************************************* 00925 * Function Name : In0_Process 00926 * Description : Process the IN token on all default endpoint. 00927 * Input : None. 00928 * Output : None. 00929 * Return : Post0_Process. 00930 *******************************************************************************/ 00931 uint8_t In0_Process(void) 00932 { 00933 uint32_t ControlState = pInformation->ControlState; 00934 00935 if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) 00936 { 00937 DataStageIn(); 00938 /* ControlState may be changed outside the function */ 00939 ControlState = pInformation->ControlState; 00940 } 00941 00942 else if (ControlState == WAIT_STATUS_IN) 00943 { 00944 if ((pInformation->USBbRequest == SET_ADDRESS) && 00945 (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))) 00946 { 00947 SetDeviceAddress(pInformation->USBwValue0); 00948 pUser_Standard_Requests->User_SetDeviceAddress(); 00949 } 00950 (*pProperty->Process_Status_IN)(); 00951 ControlState = STALLED; 00952 } 00953 00954 else 00955 { 00956 ControlState = STALLED; 00957 } 00958 00959 pInformation->ControlState = ControlState; 00960 00961 return Post0_Process(); 00962 } 00963 00964 /******************************************************************************* 00965 * Function Name : Out0_Process 00966 * Description : Process the OUT token on all default endpoint. 00967 * Input : None. 00968 * Output : None. 00969 * Return : Post0_Process. 00970 *******************************************************************************/ 00971 uint8_t Out0_Process(void) 00972 { 00973 uint32_t ControlState = pInformation->ControlState; 00974 00975 if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA)) 00976 { 00977 /* host aborts the transfer before finish */ 00978 ControlState = STALLED; 00979 } 00980 else if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA)) 00981 { 00982 DataStageOut(); 00983 ControlState = pInformation->ControlState; /* may be changed outside the function */ 00984 } 00985 00986 else if (ControlState == WAIT_STATUS_OUT) 00987 { 00988 (*pProperty->Process_Status_OUT)(); 00989 #ifndef STM32F10X_CL 00990 ControlState = STALLED; 00991 #endif /* STM32F10X_CL */ 00992 } 00993 00994 00995 /* Unexpect state, STALL the endpoint */ 00996 else 00997 { 00998 ControlState = STALLED; 00999 } 01000 01001 pInformation->ControlState = ControlState; 01002 01003 return Post0_Process(); 01004 } 01005 01006 /******************************************************************************* 01007 * Function Name : Post0_Process 01008 * Description : Stall the Endpoint 0 in case of error. 01009 * Input : None. 01010 * Output : None. 01011 * Return : - 0 if the control State is in PAUSE 01012 * - 1 if not. 01013 *******************************************************************************/ 01014 uint8_t Post0_Process(void) 01015 { 01016 #ifdef STM32F10X_CL 01017 USB_OTG_EP *ep; 01018 #endif /* STM32F10X_CL */ 01019 01020 SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); 01021 01022 if (pInformation->ControlState == STALLED) 01023 { 01024 vSetEPRxStatus(EP_RX_STALL); 01025 vSetEPTxStatus(EP_TX_STALL); 01026 } 01027 01028 #ifdef STM32F10X_CL 01029 else if ((pInformation->ControlState == OUT_DATA) || 01030 (pInformation->ControlState == WAIT_STATUS_OUT)) 01031 { 01032 ep = PCD_GetInEP(0); 01033 ep->is_in = 0; 01034 OTGD_FS_EP0StartXfer(ep); 01035 01036 vSetEPTxStatus(EP_TX_VALID); 01037 } 01038 01039 else if ((pInformation->ControlState == IN_DATA) || 01040 (pInformation->ControlState == WAIT_STATUS_IN)) 01041 { 01042 ep = PCD_GetInEP(0); 01043 ep->is_in = 1; 01044 OTGD_FS_EP0StartXfer(ep); 01045 } 01046 #endif /* STM32F10X_CL */ 01047 01048 return (pInformation->ControlState == PAUSE); 01049 } 01050 01051 /******************************************************************************* 01052 * Function Name : SetDeviceAddress. 01053 * Description : Set the device and all the used Endpoints addresses. 01054 * Input : - Val: device adress. 01055 * Output : None. 01056 * Return : None. 01057 *******************************************************************************/ 01058 void SetDeviceAddress(uint8_t Val) 01059 { 01060 #ifdef STM32F10X_CL 01061 PCD_EP_SetAddress ((uint8_t)Val); 01062 #else 01063 uint32_t i; 01064 uint32_t nEP = Device_Table.Total_Endpoint; 01065 01066 /* set address in every used endpoint */ 01067 for (i = 0; i < nEP; i++) 01068 { 01069 _SetEPAddress((uint8_t)i, (uint8_t)i); 01070 } /* for */ 01071 _SetDADDR(Val | DADDR_EF); /* set device address and enable function */ 01072 #endif /* STM32F10X_CL */ 01073 } 01074 01075 /******************************************************************************* 01076 * Function Name : NOP_Process 01077 * Description : No operation function. 01078 * Input : None. 01079 * Output : None. 01080 * Return : None. 01081 *******************************************************************************/ 01082 void NOP_Process(void) 01083 { 01084 } 01085 01086 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 20:45:32 by
1.7.2