USB CDC library for MBED on STM32

Dependents:   PushToGo-F429

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbd_ctlreq.c Source File

usbd_ctlreq.c

00001 /**
00002   ******************************************************************************
00003   * @file    usbd_req.c
00004   * @author  MCD Application Team
00005   * @version V2.4.2
00006   * @date    11-December-2015 
00007   * @brief   This file provides the standard USB requests following chapter 9.
00008   ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
00012   *
00013   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
00014   * You may not use this file except in compliance with the License.
00015   * You may obtain a copy of the License at:
00016   *
00017   *        http://www.st.com/software_license_agreement_liberty_v2
00018   *
00019   * Unless required by applicable law or agreed to in writing, software 
00020   * distributed under the License is distributed on an "AS IS" BASIS, 
00021   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00022   * See the License for the specific language governing permissions and
00023   * limitations under the License.
00024   *
00025   ******************************************************************************
00026   */ 
00027 
00028 /* Includes ------------------------------------------------------------------*/
00029 #include "usbd_ctlreq.h"
00030 #include "usbd_ioreq.h"
00031 
00032 
00033 /** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
00034   * @{
00035   */
00036 
00037 
00038 /** @defgroup USBD_REQ 
00039   * @brief USB standard requests module
00040   * @{
00041   */ 
00042 
00043 /** @defgroup USBD_REQ_Private_TypesDefinitions
00044   * @{
00045   */ 
00046 /**
00047   * @}
00048   */ 
00049 
00050 
00051 /** @defgroup USBD_REQ_Private_Defines
00052   * @{
00053   */ 
00054 
00055 /**
00056   * @}
00057   */ 
00058 
00059 
00060 /** @defgroup USBD_REQ_Private_Macros
00061   * @{
00062   */ 
00063 /**
00064   * @}
00065   */ 
00066 
00067 
00068 /** @defgroup USBD_REQ_Private_Variables
00069   * @{
00070   */ 
00071 /**
00072   * @}
00073   */ 
00074 
00075 
00076 /** @defgroup USBD_REQ_Private_FunctionPrototypes
00077   * @{
00078   */ 
00079 static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , 
00080                                USBD_SetupReqTypedef *req);
00081 
00082 static void USBD_SetAddress(USBD_HandleTypeDef *pdev , 
00083                             USBD_SetupReqTypedef *req);
00084 
00085 static void USBD_SetConfig(USBD_HandleTypeDef *pdev , 
00086                            USBD_SetupReqTypedef *req);
00087 
00088 static void USBD_GetConfig(USBD_HandleTypeDef *pdev , 
00089                            USBD_SetupReqTypedef *req);
00090 
00091 static void USBD_GetStatus(USBD_HandleTypeDef *pdev , 
00092                            USBD_SetupReqTypedef *req);
00093 
00094 static void USBD_SetFeature(USBD_HandleTypeDef *pdev , 
00095                             USBD_SetupReqTypedef *req);
00096 
00097 static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , 
00098                             USBD_SetupReqTypedef *req);
00099 
00100 static uint8_t USBD_GetLen(uint8_t *buf);
00101 
00102 /**
00103   * @}
00104   */ 
00105 
00106 
00107 /** @defgroup USBD_REQ_Private_Functions
00108   * @{
00109   */ 
00110 
00111 
00112 /**
00113 * @brief  USBD_StdDevReq
00114 *         Handle standard usb device requests
00115 * @param  pdev: device instance
00116 * @param  req: usb request
00117 * @retval status
00118 */
00119 USBD_StatusTypeDef  USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef  *req)
00120 {
00121   USBD_StatusTypeDef ret = USBD_OK;  
00122   
00123   switch (req->bRequest) 
00124   {
00125   case USB_REQ_GET_DESCRIPTOR: 
00126     
00127     USBD_GetDescriptor (pdev, req) ;
00128     break;
00129     
00130   case USB_REQ_SET_ADDRESS:                      
00131     USBD_SetAddress(pdev, req);
00132     break;
00133     
00134   case USB_REQ_SET_CONFIGURATION:                    
00135     USBD_SetConfig (pdev , req);
00136     break;
00137     
00138   case USB_REQ_GET_CONFIGURATION:                 
00139     USBD_GetConfig (pdev , req);
00140     break;
00141     
00142   case USB_REQ_GET_STATUS:                                  
00143     USBD_GetStatus (pdev , req);
00144     break;
00145     
00146     
00147   case USB_REQ_SET_FEATURE:   
00148     USBD_SetFeature (pdev , req);    
00149     break;
00150     
00151   case USB_REQ_CLEAR_FEATURE:                                   
00152     USBD_ClrFeature (pdev , req);
00153     break;
00154     
00155   default:  
00156     USBD_CtlError(pdev , req);
00157     break;
00158   }
00159   
00160   return ret;
00161 }
00162 
00163 /**
00164 * @brief  USBD_StdItfReq
00165 *         Handle standard usb interface requests
00166 * @param  pdev: device instance
00167 * @param  req: usb request
00168 * @retval status
00169 */
00170 USBD_StatusTypeDef  USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef  *req)
00171 {
00172   USBD_StatusTypeDef ret = USBD_OK; 
00173   
00174   switch (pdev->dev_state) 
00175   {
00176   case USBD_STATE_CONFIGURED:
00177     
00178     if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) 
00179     {
00180       pdev->pClass->Setup (pdev, req); 
00181       
00182       if((req->wLength == 0)&& (ret == USBD_OK))
00183       {
00184          USBD_CtlSendStatus(pdev);
00185       }
00186     } 
00187     else 
00188     {                                               
00189        USBD_CtlError(pdev , req);
00190     }
00191     break;
00192     
00193   default:
00194      USBD_CtlError(pdev , req);
00195     break;
00196   }
00197   return USBD_OK;
00198 }
00199 
00200 /**
00201 * @brief  USBD_StdEPReq
00202 *         Handle standard usb endpoint requests
00203 * @param  pdev: device instance
00204 * @param  req: usb request
00205 * @retval status
00206 */
00207 USBD_StatusTypeDef  USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef  *req)
00208 {
00209   
00210   uint8_t   ep_addr;
00211   USBD_StatusTypeDef ret = USBD_OK; 
00212   USBD_EndpointTypeDef   *pep;
00213   ep_addr  = LOBYTE(req->wIndex);   
00214   
00215   /* Check if it is a class request */
00216   if ((req->bmRequest & 0x60) == 0x20)
00217   {
00218     pdev->pClass->Setup (pdev, req);
00219     
00220     return USBD_OK;
00221   }
00222   
00223   switch (req->bRequest) 
00224   {
00225     
00226   case USB_REQ_SET_FEATURE :
00227     
00228     switch (pdev->dev_state) 
00229     {
00230     case USBD_STATE_ADDRESSED:          
00231       if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
00232       {
00233         USBD_LL_StallEP(pdev , ep_addr);
00234       }
00235       break;    
00236       
00237     case USBD_STATE_CONFIGURED:   
00238       if (req->wValue == USB_FEATURE_EP_HALT)
00239       {
00240         if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
00241         { 
00242           USBD_LL_StallEP(pdev , ep_addr);
00243           
00244         }
00245       }
00246       pdev->pClass->Setup (pdev, req);   
00247       USBD_CtlSendStatus(pdev);
00248       
00249       break;
00250       
00251     default:                         
00252       USBD_CtlError(pdev , req);
00253       break;    
00254     }
00255     break;
00256     
00257   case USB_REQ_CLEAR_FEATURE :
00258     
00259     switch (pdev->dev_state) 
00260     {
00261     case USBD_STATE_ADDRESSED:          
00262       if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
00263       {
00264         USBD_LL_StallEP(pdev , ep_addr);
00265       }
00266       break;    
00267       
00268     case USBD_STATE_CONFIGURED:   
00269       if (req->wValue == USB_FEATURE_EP_HALT)
00270       {
00271         if ((ep_addr & 0x7F) != 0x00) 
00272         {        
00273           USBD_LL_ClearStallEP(pdev , ep_addr);
00274           pdev->pClass->Setup (pdev, req);
00275         }
00276         USBD_CtlSendStatus(pdev);
00277       }
00278       break;
00279       
00280     default:                         
00281       USBD_CtlError(pdev , req);
00282       break;    
00283     }
00284     break;
00285     
00286   case USB_REQ_GET_STATUS:                  
00287     switch (pdev->dev_state) 
00288     {
00289     case USBD_STATE_ADDRESSED:          
00290       if ((ep_addr & 0x7F) != 0x00) 
00291       {
00292         USBD_LL_StallEP(pdev , ep_addr);
00293       }
00294       break;    
00295       
00296     case USBD_STATE_CONFIGURED:
00297       pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\
00298                                          &pdev->ep_out[ep_addr & 0x7F];
00299       if(USBD_LL_IsStallEP(pdev, ep_addr))
00300       {
00301         pep->status = 0x0001;     
00302       }
00303       else
00304       {
00305         pep->status = 0x0000;  
00306       }
00307       
00308       USBD_CtlSendData (pdev,
00309                         (uint8_t *)&pep->status,
00310                         2);
00311       break;
00312       
00313     default:                         
00314       USBD_CtlError(pdev , req);
00315       break;
00316     }
00317     break;
00318     
00319   default:
00320     break;
00321   }
00322   return ret;
00323 }
00324 /**
00325 * @brief  USBD_GetDescriptor
00326 *         Handle Get Descriptor requests
00327 * @param  pdev: device instance
00328 * @param  req: usb request
00329 * @retval status
00330 */
00331 static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , 
00332                                USBD_SetupReqTypedef *req)
00333 {
00334   uint16_t len;
00335   uint8_t *pbuf;
00336   
00337     
00338   switch (req->wValue >> 8)
00339   { 
00340 #if (USBD_LPM_ENABLED == 1)
00341   case USB_DESC_TYPE_BOS:
00342     pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
00343     break;
00344 #endif    
00345   case USB_DESC_TYPE_DEVICE:
00346     pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
00347     break;
00348     
00349   case USB_DESC_TYPE_CONFIGURATION:     
00350     if(pdev->dev_speed == USBD_SPEED_HIGH )   
00351     {
00352       pbuf   = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len);
00353       pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
00354     }
00355     else
00356     {
00357       pbuf   = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len);
00358       pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
00359     }
00360     break;
00361     
00362   case USB_DESC_TYPE_STRING:
00363     switch ((uint8_t)(req->wValue))
00364     {
00365     case USBD_IDX_LANGID_STR:
00366      pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);        
00367       break;
00368       
00369     case USBD_IDX_MFC_STR:
00370       pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len);
00371       break;
00372       
00373     case USBD_IDX_PRODUCT_STR:
00374       pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
00375       break;
00376       
00377     case USBD_IDX_SERIAL_STR:
00378       pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
00379       break;
00380       
00381     case USBD_IDX_CONFIG_STR:
00382       pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len);
00383       break;
00384       
00385     case USBD_IDX_INTERFACE_STR:
00386       pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len);
00387       break;
00388       
00389     default:
00390 #if (USBD_SUPPORT_USER_STRING == 1)
00391       pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len);
00392       break;
00393 #else      
00394        USBD_CtlError(pdev , req);
00395       return;
00396 #endif   
00397     }
00398     break;
00399   case USB_DESC_TYPE_DEVICE_QUALIFIER:                   
00400 
00401     if(pdev->dev_speed == USBD_SPEED_HIGH  )   
00402     {
00403       pbuf   = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len);
00404       break;
00405     }
00406     else
00407     {
00408       USBD_CtlError(pdev , req);
00409       return;
00410     } 
00411 
00412   case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
00413     if(pdev->dev_speed == USBD_SPEED_HIGH  )   
00414     {
00415       pbuf   = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
00416       pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
00417       break; 
00418     }
00419     else
00420     {
00421       USBD_CtlError(pdev , req);
00422       return;
00423     }
00424 
00425   default: 
00426      USBD_CtlError(pdev , req);
00427     return;
00428   }
00429   
00430   if((len != 0)&& (req->wLength != 0))
00431   {
00432     
00433     len = MIN(len , req->wLength);
00434     
00435     USBD_CtlSendData (pdev, 
00436                       pbuf,
00437                       len);
00438   }
00439   
00440 }
00441 
00442 /**
00443 * @brief  USBD_SetAddress
00444 *         Set device address
00445 * @param  pdev: device instance
00446 * @param  req: usb request
00447 * @retval status
00448 */
00449 static void USBD_SetAddress(USBD_HandleTypeDef *pdev , 
00450                             USBD_SetupReqTypedef *req)
00451 {
00452   uint8_t  dev_addr; 
00453   
00454   if ((req->wIndex == 0) && (req->wLength == 0)) 
00455   {
00456     dev_addr = (uint8_t)(req->wValue) & 0x7F;     
00457     
00458     if (pdev->dev_state == USBD_STATE_CONFIGURED) 
00459     {
00460       USBD_CtlError(pdev , req);
00461     } 
00462     else 
00463     {
00464       pdev->dev_address = dev_addr;
00465       USBD_LL_SetUSBAddress(pdev, dev_addr);               
00466       USBD_CtlSendStatus(pdev);                         
00467       
00468       if (dev_addr != 0) 
00469       {
00470         pdev->dev_state  = USBD_STATE_ADDRESSED;
00471       } 
00472       else 
00473       {
00474         pdev->dev_state  = USBD_STATE_DEFAULT; 
00475       }
00476     }
00477   } 
00478   else 
00479   {
00480      USBD_CtlError(pdev , req);                        
00481   } 
00482 }
00483 
00484 /**
00485 * @brief  USBD_SetConfig
00486 *         Handle Set device configuration request
00487 * @param  pdev: device instance
00488 * @param  req: usb request
00489 * @retval status
00490 */
00491 static void USBD_SetConfig(USBD_HandleTypeDef *pdev , 
00492                            USBD_SetupReqTypedef *req)
00493 {
00494   
00495   static uint8_t  cfgidx;
00496   
00497   cfgidx = (uint8_t)(req->wValue);                 
00498   
00499   if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) 
00500   {            
00501      USBD_CtlError(pdev , req);                              
00502   } 
00503   else 
00504   {
00505     switch (pdev->dev_state) 
00506     {
00507     case USBD_STATE_ADDRESSED:
00508       if (cfgidx) 
00509       {                                                                                                                 
00510         pdev->dev_config = cfgidx;
00511         pdev->dev_state = USBD_STATE_CONFIGURED;
00512         if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
00513         {
00514           USBD_CtlError(pdev , req);  
00515           return;
00516         }
00517         USBD_CtlSendStatus(pdev);
00518       }
00519       else 
00520       {
00521          USBD_CtlSendStatus(pdev);
00522       }
00523       break;
00524       
00525     case USBD_STATE_CONFIGURED:
00526       if (cfgidx == 0) 
00527       {                           
00528         pdev->dev_state = USBD_STATE_ADDRESSED;
00529         pdev->dev_config = cfgidx;          
00530         USBD_ClrClassConfig(pdev , cfgidx);
00531         USBD_CtlSendStatus(pdev);
00532         
00533       } 
00534       else  if (cfgidx != pdev->dev_config) 
00535       {
00536         /* Clear old configuration */
00537         USBD_ClrClassConfig(pdev , pdev->dev_config);
00538         
00539         /* set new configuration */
00540         pdev->dev_config = cfgidx;
00541         if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
00542         {
00543           USBD_CtlError(pdev , req);  
00544           return;
00545         }
00546         USBD_CtlSendStatus(pdev);
00547       }
00548       else
00549       {
00550         USBD_CtlSendStatus(pdev);
00551       }
00552       break;
00553       
00554     default:                    
00555        USBD_CtlError(pdev , req);                     
00556       break;
00557     }
00558   }
00559 }
00560 
00561 /**
00562 * @brief  USBD_GetConfig
00563 *         Handle Get device configuration request
00564 * @param  pdev: device instance
00565 * @param  req: usb request
00566 * @retval status
00567 */
00568 static void USBD_GetConfig(USBD_HandleTypeDef *pdev , 
00569                            USBD_SetupReqTypedef *req)
00570 {
00571 
00572   if (req->wLength != 1) 
00573   {                   
00574      USBD_CtlError(pdev , req);
00575   }
00576   else 
00577   {
00578     switch (pdev->dev_state )  
00579     {
00580     case USBD_STATE_ADDRESSED:                     
00581       pdev->dev_default_config = 0;
00582       USBD_CtlSendData (pdev, 
00583                         (uint8_t *)&pdev->dev_default_config,
00584                         1);
00585       break;
00586       
00587     case USBD_STATE_CONFIGURED:   
00588       
00589       USBD_CtlSendData (pdev, 
00590                         (uint8_t *)&pdev->dev_config,
00591                         1);
00592       break;
00593       
00594     default:
00595        USBD_CtlError(pdev , req);
00596       break;
00597     }
00598   }
00599 }
00600 
00601 /**
00602 * @brief  USBD_GetStatus
00603 *         Handle Get Status request
00604 * @param  pdev: device instance
00605 * @param  req: usb request
00606 * @retval status
00607 */
00608 static void USBD_GetStatus(USBD_HandleTypeDef *pdev , 
00609                            USBD_SetupReqTypedef *req)
00610 {
00611   
00612     
00613   switch (pdev->dev_state) 
00614   {
00615   case USBD_STATE_ADDRESSED:
00616   case USBD_STATE_CONFIGURED:
00617     
00618 #if ( USBD_SELF_POWERED == 1)
00619     pdev->dev_config_status = USB_CONFIG_SELF_POWERED;                                  
00620 #else
00621     pdev->dev_config_status = 0;                                   
00622 #endif
00623                       
00624     if (pdev->dev_remote_wakeup) 
00625     {
00626        pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;                                
00627     }
00628     
00629     USBD_CtlSendData (pdev, 
00630                       (uint8_t *)& pdev->dev_config_status,
00631                       2);
00632     break;
00633     
00634   default :
00635     USBD_CtlError(pdev , req);                        
00636     break;
00637   }
00638 }
00639 
00640 
00641 /**
00642 * @brief  USBD_SetFeature
00643 *         Handle Set device feature request
00644 * @param  pdev: device instance
00645 * @param  req: usb request
00646 * @retval status
00647 */
00648 static void USBD_SetFeature(USBD_HandleTypeDef *pdev , 
00649                             USBD_SetupReqTypedef *req)
00650 {
00651 
00652   if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
00653   {
00654     pdev->dev_remote_wakeup = 1;  
00655     pdev->pClass->Setup (pdev, req);   
00656     USBD_CtlSendStatus(pdev);
00657   }
00658 
00659 }
00660 
00661 
00662 /**
00663 * @brief  USBD_ClrFeature
00664 *         Handle clear device feature request
00665 * @param  pdev: device instance
00666 * @param  req: usb request
00667 * @retval status
00668 */
00669 static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , 
00670                             USBD_SetupReqTypedef *req)
00671 {
00672   switch (pdev->dev_state)
00673   {
00674   case USBD_STATE_ADDRESSED:
00675   case USBD_STATE_CONFIGURED:
00676     if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) 
00677     {
00678       pdev->dev_remote_wakeup = 0; 
00679       pdev->pClass->Setup (pdev, req);   
00680       USBD_CtlSendStatus(pdev);
00681     }
00682     break;
00683     
00684   default :
00685      USBD_CtlError(pdev , req);
00686     break;
00687   }
00688 }
00689 
00690 /**
00691 * @brief  USBD_ParseSetupRequest 
00692 *         Copy buffer into setup structure
00693 * @param  pdev: device instance
00694 * @param  req: usb request
00695 * @retval None
00696 */
00697 
00698 void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
00699 {
00700   req->bmRequest     = *(uint8_t *)  (pdata);
00701   req->bRequest      = *(uint8_t *)  (pdata +  1);
00702   req->wValue        = SWAPBYTE      (pdata +  2);
00703   req->wIndex        = SWAPBYTE      (pdata +  4);
00704   req->wLength       = SWAPBYTE      (pdata +  6);
00705 
00706 }
00707 
00708 /**
00709 * @brief  USBD_CtlError 
00710 *         Handle USB low level Error
00711 * @param  pdev: device instance
00712 * @param  req: usb request
00713 * @retval None
00714 */
00715 
00716 void USBD_CtlError( USBD_HandleTypeDef *pdev ,
00717                             USBD_SetupReqTypedef *req)
00718 {
00719   USBD_LL_StallEP(pdev , 0x80);
00720   USBD_LL_StallEP(pdev , 0);
00721 }
00722 
00723 
00724 /**
00725   * @brief  USBD_GetString
00726   *         Convert Ascii string into unicode one
00727   * @param  desc : descriptor buffer
00728   * @param  unicode : Formatted string buffer (unicode)
00729   * @param  len : descriptor length
00730   * @retval None
00731   */
00732 void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
00733 {
00734   uint8_t idx = 0;
00735   
00736   if (desc != NULL) 
00737   {
00738     *len =  USBD_GetLen(desc) * 2 + 2;    
00739     unicode[idx++] = *len;
00740     unicode[idx++] =  USB_DESC_TYPE_STRING;
00741     
00742     while (*desc != '\0') 
00743     {
00744       unicode[idx++] = *desc++;
00745       unicode[idx++] =  0x00;
00746     }
00747   } 
00748 }
00749 
00750 /**
00751   * @brief  USBD_GetLen
00752   *         return the string length
00753    * @param  buf : pointer to the ascii string buffer
00754   * @retval string length
00755   */
00756 static uint8_t USBD_GetLen(uint8_t *buf)
00757 {
00758     uint8_t  len = 0;
00759 
00760     while (*buf != '\0') 
00761     {
00762         len++;
00763         buf++;
00764     }
00765 
00766     return len;
00767 }
00768 /**
00769   * @}
00770   */ 
00771 
00772 
00773 /**
00774   * @}
00775   */ 
00776 
00777 
00778 /**
00779   * @}
00780   */ 
00781 
00782 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00783