Merge pull request #11198 from SteveCEvans/sce_rc2
[betaflight.git] / lib / main / STM32_USB-FS-Device_Driver / src / usb_core.c
blob470185347bb51a6550da2d020a6643d4ebf8f57e
1 /**
2 ******************************************************************************
3 * @file usb_core.c
4 * @author MCD Application Team
5 * @version V4.0.0
6 * @date 28-August-2012
7 * @brief Standard protocol processing (USB v2.0)
8 ******************************************************************************
9 * @attention
11 * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
13 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
14 * You may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at:
17 * http://www.st.com/software_license_agreement_liberty_v2
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
25 ******************************************************************************
29 /* Includes ------------------------------------------------------------------*/
30 #include "usb_lib.h"
31 /* Private typedef -----------------------------------------------------------*/
32 /* Private define ------------------------------------------------------------*/
33 #define ValBit(VAR,Place) (VAR & (1 << Place))
34 #define SetBit(VAR,Place) (VAR |= (1 << Place))
35 #define ClrBit(VAR,Place) (VAR &= ((1 << Place) ^ 255))
36 #define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \
37 vSetEPTxStatus(EP_TX_VALID); \
40 #define vSetEPRxStatus(st) (SaveRState = st)
41 #define vSetEPTxStatus(st) (SaveTState = st)
43 #define USB_StatusIn() Send0LengthData()
44 #define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID)
46 #define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */
47 #define StatusInfo1 StatusInfo.bw.bb0
49 /* Private macro -------------------------------------------------------------*/
50 /* Private variables ---------------------------------------------------------*/
51 uint16_t_uint8_t StatusInfo;
53 boolean Data_Mul_MaxPacketSize = FALSE;
54 /* Private function prototypes -----------------------------------------------*/
55 static void DataStageOut(void);
56 static void DataStageIn(void);
57 static void NoData_Setup0(void);
58 static void Data_Setup0(void);
59 /* Private functions ---------------------------------------------------------*/
61 /*******************************************************************************
62 * Function Name : Standard_GetConfiguration.
63 * Description : Return the current configuration variable address.
64 * Input : Length - How many bytes are needed.
65 * Output : None.
66 * Return : Return 1 , if the request is invalid when "Length" is 0.
67 * Return "Buffer" if the "Length" is not 0.
68 *******************************************************************************/
69 uint8_t *Standard_GetConfiguration(uint16_t Length)
71 if (Length == 0)
73 pInformation->Ctrl_Info.Usb_wLength =
74 sizeof(pInformation->Current_Configuration);
75 return 0;
77 pUser_Standard_Requests->User_GetConfiguration();
78 return (uint8_t *)&pInformation->Current_Configuration;
81 /*******************************************************************************
82 * Function Name : Standard_SetConfiguration.
83 * Description : This routine is called to set the configuration value
84 * Then each class should configure device itself.
85 * Input : None.
86 * Output : None.
87 * Return : Return USB_SUCCESS, if the request is performed.
88 * Return USB_UNSUPPORT, if the request is invalid.
89 *******************************************************************************/
90 RESULT Standard_SetConfiguration(void)
93 if ((pInformation->USBwValue0 <=
94 Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0)
95 && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/
97 pInformation->Current_Configuration = pInformation->USBwValue0;
98 pUser_Standard_Requests->User_SetConfiguration();
99 return USB_SUCCESS;
101 else
103 return USB_UNSUPPORT;
107 /*******************************************************************************
108 * Function Name : Standard_GetInterface.
109 * Description : Return the Alternate Setting of the current interface.
110 * Input : Length - How many bytes are needed.
111 * Output : None.
112 * Return : Return 0, if the request is invalid when "Length" is 0.
113 * Return "Buffer" if the "Length" is not 0.
114 *******************************************************************************/
115 uint8_t *Standard_GetInterface(uint16_t Length)
117 if (Length == 0)
119 pInformation->Ctrl_Info.Usb_wLength =
120 sizeof(pInformation->Current_AlternateSetting);
121 return 0;
123 pUser_Standard_Requests->User_GetInterface();
124 return (uint8_t *)&pInformation->Current_AlternateSetting;
127 /*******************************************************************************
128 * Function Name : Standard_SetInterface.
129 * Description : This routine is called to set the interface.
130 * Then each class should configure the interface them self.
131 * Input : None.
132 * Output : None.
133 * Return : - Return USB_SUCCESS, if the request is performed.
134 * - Return USB_UNSUPPORT, if the request is invalid.
135 *******************************************************************************/
136 RESULT Standard_SetInterface(void)
138 RESULT Re;
139 /*Test if the specified Interface and Alternate Setting are supported by
140 the application Firmware*/
141 Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0);
143 if (pInformation->Current_Configuration != 0)
145 if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0)
146 || (pInformation->USBwValue1 != 0))
148 return USB_UNSUPPORT;
150 else if (Re == USB_SUCCESS)
152 pUser_Standard_Requests->User_SetInterface();
153 pInformation->Current_Interface = pInformation->USBwIndex0;
154 pInformation->Current_AlternateSetting = pInformation->USBwValue0;
155 return USB_SUCCESS;
160 return USB_UNSUPPORT;
163 /*******************************************************************************
164 * Function Name : Standard_GetStatus.
165 * Description : Copy the device request data to "StatusInfo buffer".
166 * Input : - Length - How many bytes are needed.
167 * Output : None.
168 * Return : Return 0, if the request is at end of data block,
169 * or is invalid when "Length" is 0.
170 *******************************************************************************/
171 uint8_t *Standard_GetStatus(uint16_t Length)
173 if (Length == 0)
175 pInformation->Ctrl_Info.Usb_wLength = 2;
176 return 0;
179 /* Reset Status Information */
180 StatusInfo.w = 0;
182 if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
184 /*Get Device Status */
185 uint8_t Feature = pInformation->Current_Feature;
187 /* Remote Wakeup enabled */
188 if (ValBit(Feature, 5))
190 SetBit(StatusInfo0, 1);
192 else
194 ClrBit(StatusInfo0, 1);
197 /* Bus-powered */
198 if (ValBit(Feature, 6))
200 SetBit(StatusInfo0, 0);
202 else /* Self-powered */
204 ClrBit(StatusInfo0, 0);
207 /*Interface Status*/
208 else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
210 return (uint8_t *)&StatusInfo;
212 /*Get EndPoint Status*/
213 else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
215 uint8_t Related_Endpoint;
216 uint8_t wIndex0 = pInformation->USBwIndex0;
218 Related_Endpoint = (wIndex0 & 0x0f);
219 if (ValBit(wIndex0, 7))
221 /* IN endpoint */
222 if (_GetTxStallStatus(Related_Endpoint))
224 SetBit(StatusInfo0, 0); /* IN Endpoint stalled */
227 else
229 /* OUT endpoint */
230 if (_GetRxStallStatus(Related_Endpoint))
232 SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */
237 else
239 return NULL;
241 pUser_Standard_Requests->User_GetStatus();
242 return (uint8_t *)&StatusInfo;
245 /*******************************************************************************
246 * Function Name : Standard_ClearFeature.
247 * Description : Clear or disable a specific feature.
248 * Input : None.
249 * Output : None.
250 * Return : - Return USB_SUCCESS, if the request is performed.
251 * - Return USB_UNSUPPORT, if the request is invalid.
252 *******************************************************************************/
253 RESULT Standard_ClearFeature(void)
255 uint32_t Type_Rec = Type_Recipient;
256 uint32_t Status;
259 if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT))
260 {/*Device Clear Feature*/
261 ClrBit(pInformation->Current_Feature, 5);
262 return USB_SUCCESS;
264 else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
265 {/*EndPoint Clear Feature*/
266 DEVICE* pDev;
267 uint32_t Related_Endpoint;
268 uint32_t wIndex0;
269 uint32_t rEP;
271 if ((pInformation->USBwValue != ENDPOINT_STALL)
272 || (pInformation->USBwIndex1 != 0))
274 return USB_UNSUPPORT;
277 pDev = &Device_Table;
278 wIndex0 = pInformation->USBwIndex0;
279 rEP = wIndex0 & ~0x80;
280 Related_Endpoint = ENDP0 + rEP;
282 if (ValBit(pInformation->USBwIndex0, 7))
284 /*Get Status of endpoint & stall the request if the related_ENdpoint
285 is Disabled*/
286 Status = _GetEPTxStatus(Related_Endpoint);
288 else
290 Status = _GetEPRxStatus(Related_Endpoint);
293 if ((rEP >= pDev->Total_Endpoint) || (Status == 0)
294 || (pInformation->Current_Configuration == 0))
296 return USB_UNSUPPORT;
300 if (wIndex0 & 0x80)
302 /* IN endpoint */
303 if (_GetTxStallStatus(Related_Endpoint ))
305 ClearDTOG_TX(Related_Endpoint);
306 SetEPTxStatus(Related_Endpoint, EP_TX_VALID);
309 else
311 /* OUT endpoint */
312 if (_GetRxStallStatus(Related_Endpoint))
314 if (Related_Endpoint == ENDP0)
316 /* After clear the STALL, enable the default endpoint receiver */
317 SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize);
318 _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
320 else
322 ClearDTOG_RX(Related_Endpoint);
323 _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
327 pUser_Standard_Requests->User_ClearFeature();
328 return USB_SUCCESS;
331 return USB_UNSUPPORT;
334 /*******************************************************************************
335 * Function Name : Standard_SetEndPointFeature
336 * Description : Set or enable a specific feature of EndPoint
337 * Input : None.
338 * Output : None.
339 * Return : - Return USB_SUCCESS, if the request is performed.
340 * - Return USB_UNSUPPORT, if the request is invalid.
341 *******************************************************************************/
342 RESULT Standard_SetEndPointFeature(void)
344 uint32_t wIndex0;
345 uint32_t Related_Endpoint;
346 uint32_t rEP;
347 uint32_t Status;
349 wIndex0 = pInformation->USBwIndex0;
350 rEP = wIndex0 & ~0x80;
351 Related_Endpoint = ENDP0 + rEP;
353 if (ValBit(pInformation->USBwIndex0, 7))
355 /* get Status of endpoint & stall the request if the related_ENdpoint
356 is Disabled*/
357 Status = _GetEPTxStatus(Related_Endpoint);
359 else
361 Status = _GetEPRxStatus(Related_Endpoint);
364 if (Related_Endpoint >= Device_Table.Total_Endpoint
365 || pInformation->USBwValue != 0 || Status == 0
366 || pInformation->Current_Configuration == 0)
368 return USB_UNSUPPORT;
370 else
372 if (wIndex0 & 0x80)
374 /* IN endpoint */
375 _SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
378 else
380 /* OUT endpoint */
381 _SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
384 pUser_Standard_Requests->User_SetEndPointFeature();
385 return USB_SUCCESS;
388 /*******************************************************************************
389 * Function Name : Standard_SetDeviceFeature.
390 * Description : Set or enable a specific feature of Device.
391 * Input : None.
392 * Output : None.
393 * Return : - Return USB_SUCCESS, if the request is performed.
394 * - Return USB_UNSUPPORT, if the request is invalid.
395 *******************************************************************************/
396 RESULT Standard_SetDeviceFeature(void)
398 SetBit(pInformation->Current_Feature, 5);
399 pUser_Standard_Requests->User_SetDeviceFeature();
400 return USB_SUCCESS;
403 /*******************************************************************************
404 * Function Name : Standard_GetDescriptorData.
405 * Description : Standard_GetDescriptorData is used for descriptors transfer.
406 * : This routine is used for the descriptors resident in Flash
407 * or RAM
408 * pDesc can be in either Flash or RAM
409 * The purpose of this routine is to have a versatile way to
410 * response descriptors request. It allows user to generate
411 * certain descriptors with software or read descriptors from
412 * external storage part by part.
413 * Input : - Length - Length of the data in this transfer.
414 * - pDesc - A pointer points to descriptor struct.
415 * The structure gives the initial address of the descriptor and
416 * its original size.
417 * Output : None.
418 * Return : Address of a part of the descriptor pointed by the Usb_
419 * wOffset The buffer pointed by this address contains at least
420 * Length bytes.
421 *******************************************************************************/
422 uint8_t *Standard_GetDescriptorData(uint16_t Length, ONE_DESCRIPTOR *pDesc)
424 uint32_t wOffset;
426 wOffset = pInformation->Ctrl_Info.Usb_wOffset;
427 if (Length == 0)
429 pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset;
430 return 0;
433 return pDesc->Descriptor + wOffset;
436 /*******************************************************************************
437 * Function Name : DataStageOut.
438 * Description : Data stage of a Control Write Transfer.
439 * Input : None.
440 * Output : None.
441 * Return : None.
442 *******************************************************************************/
443 void DataStageOut(void)
445 ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
446 uint32_t save_rLength;
448 save_rLength = pEPinfo->Usb_rLength;
450 if (pEPinfo->CopyData && save_rLength)
452 uint8_t *Buffer;
453 uint32_t Length;
455 Length = pEPinfo->PacketSize;
456 if (Length > save_rLength)
458 Length = save_rLength;
461 Buffer = (*pEPinfo->CopyData)(Length);
462 pEPinfo->Usb_rLength -= Length;
463 pEPinfo->Usb_rOffset += Length;
464 PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length);
468 if (pEPinfo->Usb_rLength != 0)
470 vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */
471 SetEPTxCount(ENDP0, 0);
472 vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */
474 /* Set the next State*/
475 if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize)
477 pInformation->ControlState = OUT_DATA;
479 else
481 if (pEPinfo->Usb_rLength > 0)
483 pInformation->ControlState = LAST_OUT_DATA;
485 else if (pEPinfo->Usb_rLength == 0)
487 pInformation->ControlState = WAIT_STATUS_IN;
488 USB_StatusIn();
493 /*******************************************************************************
494 * Function Name : DataStageIn.
495 * Description : Data stage of a Control Read Transfer.
496 * Input : None.
497 * Output : None.
498 * Return : None.
499 *******************************************************************************/
500 void DataStageIn(void)
502 ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
503 uint32_t save_wLength = pEPinfo->Usb_wLength;
504 uint32_t ControlState = pInformation->ControlState;
506 uint8_t *DataBuffer;
507 uint32_t Length;
509 if ((save_wLength == 0) && (ControlState == LAST_IN_DATA))
511 if(Data_Mul_MaxPacketSize == TRUE)
513 /* No more data to send and empty packet */
514 Send0LengthData();
515 ControlState = LAST_IN_DATA;
516 Data_Mul_MaxPacketSize = FALSE;
518 else
520 /* No more data to send so STALL the TX Status*/
521 ControlState = WAIT_STATUS_OUT;
522 vSetEPTxStatus(EP_TX_STALL);
526 goto Expect_Status_Out;
529 Length = pEPinfo->PacketSize;
530 ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA;
532 if (Length > save_wLength)
534 Length = save_wLength;
537 DataBuffer = (*pEPinfo->CopyData)(Length);
539 UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
541 SetEPTxCount(ENDP0, Length);
543 pEPinfo->Usb_wLength -= Length;
544 pEPinfo->Usb_wOffset += Length;
545 vSetEPTxStatus(EP_TX_VALID);
547 USB_StatusOut();/* Expect the host to abort the data IN stage */
549 Expect_Status_Out:
550 pInformation->ControlState = ControlState;
553 /*******************************************************************************
554 * Function Name : NoData_Setup0.
555 * Description : Proceed the processing of setup request without data stage.
556 * Input : None.
557 * Output : None.
558 * Return : None.
559 *******************************************************************************/
560 void NoData_Setup0(void)
562 RESULT Result = USB_UNSUPPORT;
563 uint32_t RequestNo = pInformation->USBbRequest;
564 uint32_t ControlState;
566 if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
568 /* Device Request*/
569 /* SET_CONFIGURATION*/
570 if (RequestNo == SET_CONFIGURATION)
572 Result = Standard_SetConfiguration();
575 /*SET ADDRESS*/
576 else if (RequestNo == SET_ADDRESS)
578 if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0)
579 || (pInformation->USBwIndex != 0)
580 || (pInformation->Current_Configuration != 0))
581 /* Device Address should be 127 or less*/
583 ControlState = STALLED;
584 goto exit_NoData_Setup0;
586 else
588 Result = USB_SUCCESS;
591 /*SET FEATURE for Device*/
592 else if (RequestNo == SET_FEATURE)
594 if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) \
595 && (pInformation->USBwIndex == 0))
597 Result = Standard_SetDeviceFeature();
599 else
601 Result = USB_UNSUPPORT;
604 /*Clear FEATURE for Device */
605 else if (RequestNo == CLEAR_FEATURE)
607 if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP
608 && pInformation->USBwIndex == 0
609 && ValBit(pInformation->Current_Feature, 5))
611 Result = Standard_ClearFeature();
613 else
615 Result = USB_UNSUPPORT;
621 /* Interface Request*/
622 else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
624 /*SET INTERFACE*/
625 if (RequestNo == SET_INTERFACE)
627 Result = Standard_SetInterface();
631 /* EndPoint Request*/
632 else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
634 /*CLEAR FEATURE for EndPoint*/
635 if (RequestNo == CLEAR_FEATURE)
637 Result = Standard_ClearFeature();
639 /* SET FEATURE for EndPoint*/
640 else if (RequestNo == SET_FEATURE)
642 Result = Standard_SetEndPointFeature();
645 else
647 Result = USB_UNSUPPORT;
651 if (Result != USB_SUCCESS)
653 Result = (*pProperty->Class_NoData_Setup)(RequestNo);
654 if (Result == USB_NOT_READY)
656 ControlState = PAUSE;
657 goto exit_NoData_Setup0;
661 if (Result != USB_SUCCESS)
663 ControlState = STALLED;
664 goto exit_NoData_Setup0;
667 ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */
669 USB_StatusIn();
671 exit_NoData_Setup0:
672 pInformation->ControlState = ControlState;
673 return;
676 /*******************************************************************************
677 * Function Name : Data_Setup0.
678 * Description : Proceed the processing of setup request with data stage.
679 * Input : None.
680 * Output : None.
681 * Return : None.
682 *******************************************************************************/
683 void Data_Setup0(void)
685 uint8_t *(*CopyRoutine)(uint16_t);
686 RESULT Result;
687 uint32_t Request_No = pInformation->USBbRequest;
689 uint32_t Related_Endpoint, Reserved;
690 uint32_t wOffset, Status;
694 CopyRoutine = NULL;
695 wOffset = 0;
697 /*GET DESCRIPTOR*/
698 if (Request_No == GET_DESCRIPTOR)
700 if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
702 uint8_t wValue1 = pInformation->USBwValue1;
703 if (wValue1 == DEVICE_DESCRIPTOR)
705 CopyRoutine = pProperty->GetDeviceDescriptor;
707 else if (wValue1 == CONFIG_DESCRIPTOR)
709 CopyRoutine = pProperty->GetConfigDescriptor;
711 else if (wValue1 == STRING_DESCRIPTOR)
713 CopyRoutine = pProperty->GetStringDescriptor;
714 } /* End of GET_DESCRIPTOR */
718 /*GET STATUS*/
719 else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0)
720 && (pInformation->USBwLength == 0x0002)
721 && (pInformation->USBwIndex1 == 0))
723 /* GET STATUS for Device*/
724 if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
725 && (pInformation->USBwIndex == 0))
727 CopyRoutine = Standard_GetStatus;
730 /* GET STATUS for Interface*/
731 else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
733 if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)
734 && (pInformation->Current_Configuration != 0))
736 CopyRoutine = Standard_GetStatus;
740 /* GET STATUS for EndPoint*/
741 else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
743 Related_Endpoint = (pInformation->USBwIndex0 & 0x0f);
744 Reserved = pInformation->USBwIndex0 & 0x70;
746 if (ValBit(pInformation->USBwIndex0, 7))
748 /*Get Status of endpoint & stall the request if the related_ENdpoint
749 is Disabled*/
750 Status = _GetEPTxStatus(Related_Endpoint);
752 else
754 Status = _GetEPRxStatus(Related_Endpoint);
757 if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0)
758 && (Status != 0))
760 CopyRoutine = Standard_GetStatus;
766 /*GET CONFIGURATION*/
767 else if (Request_No == GET_CONFIGURATION)
769 if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
771 CopyRoutine = Standard_GetConfiguration;
774 /*GET INTERFACE*/
775 else if (Request_No == GET_INTERFACE)
777 if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
778 && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0)
779 && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001)
780 && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS))
782 CopyRoutine = Standard_GetInterface;
787 if (CopyRoutine)
789 pInformation->Ctrl_Info.Usb_wOffset = wOffset;
790 pInformation->Ctrl_Info.CopyData = CopyRoutine;
791 /* sb in the original the cast to word was directly */
792 /* now the cast is made step by step */
793 (*CopyRoutine)(0);
794 Result = USB_SUCCESS;
796 else
798 Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);
799 if (Result == USB_NOT_READY)
801 pInformation->ControlState = PAUSE;
802 return;
806 if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF)
808 /* Data is not ready, wait it */
809 pInformation->ControlState = PAUSE;
810 return;
812 if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0))
814 /* Unsupported request */
815 pInformation->ControlState = STALLED;
816 return;
820 if (ValBit(pInformation->USBbmRequestType, 7))
822 /* Device ==> Host */
823 __IO uint32_t wLength = pInformation->USBwLength;
825 /* Restrict the data length to be the one host asks for */
826 if (pInformation->Ctrl_Info.Usb_wLength > wLength)
828 pInformation->Ctrl_Info.Usb_wLength = wLength;
831 else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength)
833 if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize)
835 Data_Mul_MaxPacketSize = FALSE;
837 else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0)
839 Data_Mul_MaxPacketSize = TRUE;
843 pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize;
844 DataStageIn();
846 else
848 pInformation->ControlState = OUT_DATA;
849 vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */
852 return;
855 /*******************************************************************************
856 * Function Name : Setup0_Process
857 * Description : Get the device request data and dispatch to individual process.
858 * Input : None.
859 * Output : None.
860 * Return : Post0_Process.
861 *******************************************************************************/
862 uint8_t Setup0_Process(void)
865 union
867 uint8_t* b;
868 uint16_t* w;
869 } pBuf;
870 uint16_t offset = 1;
872 pBuf.b = PMAAddr + (uint8_t *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */
874 if (pInformation->ControlState != PAUSE)
876 pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
877 pInformation->USBbRequest = *pBuf.b++; /* bRequest */
878 pBuf.w += offset; /* word not accessed because of 32 bits addressing */
879 pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
880 pBuf.w += offset; /* word not accessed because of 32 bits addressing */
881 pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */
882 pBuf.w += offset; /* word not accessed because of 32 bits addressing */
883 pInformation->USBwLength = *pBuf.w; /* wLength */
886 pInformation->ControlState = SETTING_UP;
887 if (pInformation->USBwLength == 0)
889 /* Setup with no data stage */
890 NoData_Setup0();
892 else
894 /* Setup with data stage */
895 Data_Setup0();
897 return Post0_Process();
900 /*******************************************************************************
901 * Function Name : In0_Process
902 * Description : Process the IN token on all default endpoint.
903 * Input : None.
904 * Output : None.
905 * Return : Post0_Process.
906 *******************************************************************************/
907 uint8_t In0_Process(void)
909 uint32_t ControlState = pInformation->ControlState;
911 if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
913 DataStageIn();
914 /* ControlState may be changed outside the function */
915 ControlState = pInformation->ControlState;
918 else if (ControlState == WAIT_STATUS_IN)
920 if ((pInformation->USBbRequest == SET_ADDRESS) &&
921 (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)))
923 SetDeviceAddress(pInformation->USBwValue0);
924 pUser_Standard_Requests->User_SetDeviceAddress();
926 (*pProperty->Process_Status_IN)();
927 ControlState = STALLED;
930 else
932 ControlState = STALLED;
935 pInformation->ControlState = ControlState;
937 return Post0_Process();
940 /*******************************************************************************
941 * Function Name : Out0_Process
942 * Description : Process the OUT token on all default endpoint.
943 * Input : None.
944 * Output : None.
945 * Return : Post0_Process.
946 *******************************************************************************/
947 uint8_t Out0_Process(void)
949 uint32_t ControlState = pInformation->ControlState;
951 if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
953 /* host aborts the transfer before finish */
954 ControlState = STALLED;
956 else if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA))
958 DataStageOut();
959 ControlState = pInformation->ControlState; /* may be changed outside the function */
962 else if (ControlState == WAIT_STATUS_OUT)
964 (*pProperty->Process_Status_OUT)();
965 ControlState = STALLED;
969 /* Unexpect state, STALL the endpoint */
970 else
972 ControlState = STALLED;
975 pInformation->ControlState = ControlState;
977 return Post0_Process();
980 /*******************************************************************************
981 * Function Name : Post0_Process
982 * Description : Stall the Endpoint 0 in case of error.
983 * Input : None.
984 * Output : None.
985 * Return : - 0 if the control State is in PAUSE
986 * - 1 if not.
987 *******************************************************************************/
988 uint8_t Post0_Process(void)
991 SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
993 if (pInformation->ControlState == STALLED)
995 vSetEPRxStatus(EP_RX_STALL);
996 vSetEPTxStatus(EP_TX_STALL);
999 return (pInformation->ControlState == PAUSE);
1002 /*******************************************************************************
1003 * Function Name : SetDeviceAddress.
1004 * Description : Set the device and all the used Endpoints addresses.
1005 * Input : - Val: device address.
1006 * Output : None.
1007 * Return : None.
1008 *******************************************************************************/
1009 void SetDeviceAddress(uint8_t Val)
1011 uint32_t i;
1012 uint32_t nEP = Device_Table.Total_Endpoint;
1014 /* set address in every used endpoint */
1015 for (i = 0; i < nEP; i++)
1017 _SetEPAddress((uint8_t)i, (uint8_t)i);
1018 } /* for */
1019 _SetDADDR(Val | DADDR_EF); /* set device address and enable function */
1022 /*******************************************************************************
1023 * Function Name : NOP_Process
1024 * Description : No operation function.
1025 * Input : None.
1026 * Output : None.
1027 * Return : None.
1028 *******************************************************************************/
1029 void NOP_Process(void)
1033 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/