usbdrv/peripheral/pdd/pil/inc/controltransfersm.h
changeset 59 bbdce6bffaad
equal deleted inserted replaced
58:84c26be382f0 59:bbdce6bffaad
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 // Control transfer state machine.
       
    19 // Generally used for Endpoint zero.
       
    20 
       
    21 #ifndef CONTROLTRANSFER_SM_H
       
    22 #define CONTROLTRANSFER_SM_H
       
    23 
       
    24 #include <e32def.h>                     // General types definition
       
    25 #include <usb/usb_peripheral_shai.h>    // Peripheral SHAI Header
       
    26 #include <usb/usb.h>                    // Usb const
       
    27 
       
    28 #include <usb/usbcontrolxferif.h>
       
    29 
       
    30 // Forward class declaration
       
    31 class TControlStageSm;
       
    32 
       
    33 // Refer usb setup packet definition
       
    34 const TUint8 KUSB_SETUPKT_DATA_DIR_MASK = 0x80;
       
    35 const TUint8 KUSB_SETUPKT_REQ_TYPE_VENDOR_MASK = 0x40;
       
    36 const TUint8 KUSB_SETUPKT_REQ_TYPE_CLASS_MASK = 0x20;
       
    37 const TUint8 KUSB_SETUPKT_REQ_TYPE_STANDARD_MASK = 0x60;
       
    38 
       
    39 /** 
       
    40  * TUsbPeripheralSetup
       
    41  * @brief  A USB Setup packet's structure.
       
    42  * @see ProcessSetConfiguration(const TUsbPeripheralSetup&)
       
    43  *
       
    44  */
       
    45 struct TUsbcSetup
       
    46     {
       
    47     /** bmRequestType */
       
    48     TUint8 iRequestType;
       
    49     
       
    50     /** bRequest */
       
    51     TUint8 iRequest;
       
    52     
       
    53     /** wValue */
       
    54     TUint16 iValue;
       
    55     
       
    56     /** wIndex */
       
    57     TUint16 iIndex;
       
    58     
       
    59     /** wLength */
       
    60     TUint16 iLength;
       
    61     };
       
    62 
       
    63 /** Valid request catogary that a client(PIL or App) can request
       
    64  *  via this state machine
       
    65  */
       
    66 enum TControlTransferRequest
       
    67     {
       
    68     // Write . Data IN . From Device to Host
       
    69     TControlTransferRequestWrite,
       
    70 
       
    71     // Read . Data OUT . From Host to Device
       
    72     TControlTransferRequestRead,
       
    73 
       
    74     // Zero bytes status, Write . Status IN
       
    75     // Status from Device to Host
       
    76     TControlTransferRequestSendStatus
       
    77     
       
    78     // Status from Host to device will be ignored
       
    79     };
       
    80 
       
    81 // Data dir as spec defined
       
    82 enum TUsbDataDir
       
    83     {        
       
    84     EUsbDataDir_ToDevice,
       
    85     EUsbDataDir_ToHost
       
    86     };
       
    87 
       
    88 // Request catogary from Host to device as spec defined
       
    89 enum TUsbRequestType
       
    90     {
       
    91     EUsbStandardRequest,
       
    92     EUsbClassRequest,
       
    93     EUsbVendorRequest
       
    94     };
       
    95 
       
    96 // Target of the request(from host to device)
       
    97 enum TUsbRequestTarget
       
    98     {
       
    99     EUsbRequestTargetToDevice,
       
   100     EUsbRequestTargetToInterface,
       
   101     EUsbRequestTargetToEndpoint,
       
   102     EUsbRequestTargetToElement
       
   103     };
       
   104 
       
   105 typedef TUint8  TUsbRequest;
       
   106 
       
   107 /** Helper function which can parse a setup packet 
       
   108  *  and explain it as what's spec required
       
   109  */
       
   110 NONSHARABLE_CLASS(TSetupPkgParser)
       
   111     {
       
   112     public:
       
   113         TSetupPkgParser();
       
   114         // Set the setup buffer
       
   115         // this class does't hold this buffer, it do a bitwise copy
       
   116         // assumed length is 8 bytes
       
   117         static void Set(const TUint8* aSetupBuf);
       
   118         
       
   119         // Get what the next stage following the received setup
       
   120         // packet
       
   121         static UsbShai::TControlStage NextStage();
       
   122                 
       
   123         static TUsbDataDir DataDirection();
       
   124 
       
   125         static TBool IsVendorRequest();
       
   126         static TBool IsClassRequest(); 
       
   127         static TBool IsStandardRequest();
       
   128          
       
   129         static TUsbRequest Request();        
       
   130         static TUint16 Value();
       
   131         static TUint16 Index();
       
   132         
       
   133         // data length if there is a data packet(in/out) follows
       
   134         // data length will be modified during a transfer
       
   135         static TUint16 DataLength();
       
   136         
       
   137         static TUsbcSetup& SetupPacket();
       
   138         
       
   139     private:
       
   140         static TUsbcSetup iSetupPkt;
       
   141     };
       
   142 
       
   143 
       
   144 // State machine manager
       
   145 // 
       
   146 NONSHARABLE_CLASS(DControlTransferManager)
       
   147     {
       
   148     friend class TControlStageSm;
       
   149     
       
   150     public:
       
   151         DControlTransferManager(MControlTransferIf& aPktProcessor);
       
   152         
       
   153         // PSL will complete to PIL directly, in our cases, PIL will delegate to us via this interface
       
   154         void Ep0RequestComplete(TUint8* aBuf, TInt aSize, TInt aError, UsbShai::TControlPacketType aPktType);
       
   155         
       
   156         // Add a new state processor
       
   157         void AddState(UsbShai::TControlStage aStage, TControlStageSm& aStageSm);
       
   158         
       
   159     public:
       
   160         // Helper inline function
       
   161         MControlTransferIf& CtrTransferIf();
       
   162         TSetupPkgParser& PktParser();
       
   163         
       
   164     public:
       
   165         // EP0 Access interface
       
   166         // They are the same as it shows in SHAI header
       
   167         // so, PIL code can delegate those task to us, we will perform a series of checking
       
   168         // depending on which state we are in, if each condition meet, we will callback via
       
   169         // interface MControlTransferIf to perform the real work.
       
   170         TInt SetupEndpointZeroRead();
       
   171         TInt SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd=EFalse);
       
   172         TInt SendEp0ZeroByteStatusPacket();
       
   173         TInt StallEndpoint(TInt aRealEndpoint);
       
   174         void Ep0SetupPacketProceed();
       
   175         void Ep0DataPacketProceed();
       
   176     
       
   177         // Reset state machine.
       
   178         void Reset();      
       
   179         
       
   180         // Data received for data out stage
       
   181         void DataReceived(TUint16 aCount);
       
   182         TBool IsMoreBytesNeeded();
       
   183         
       
   184     private:
       
   185         // State machines for each stage
       
   186         TControlStageSm* iState[UsbShai::EControlTransferStageMax];
       
   187         // Current stage 
       
   188         UsbShai::TControlStage iCurrentStage;        
       
   189         TSetupPkgParser iPacketParser;
       
   190         
       
   191         MControlTransferIf& iCtrTransferIf;
       
   192         
       
   193         TBool iReadPending; 
       
   194         
       
   195         TUint16 iDataTransfered;        
       
   196     };
       
   197 
       
   198 // Base class of state machine
       
   199 NONSHARABLE_CLASS(TControlStageSm)
       
   200     {
       
   201     public:
       
   202 
       
   203         /** PSL --Ep0RequestComplete()--> PIL --Ep0RequestComplete()---------> 
       
   204          *                                                                    |
       
   205          *  (ProcessXXX)PIL <-- RequestComplete()<--DControlTransferManager <-
       
   206          *                                                                     
       
   207          *  @param  aPktSize the size of the packet recieved
       
   208          *          aError error code if something wrong
       
   209          *          aPktType one of the packet type specified in UsbShai::TControlPacketType
       
   210          *  
       
   211          *  @return ETrue if the packet need to be further processed
       
   212          *          EFalse if the packet was consumed
       
   213          */
       
   214         virtual TBool RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType) = 0;
       
   215         
       
   216         /** Query whether a kind of operation is allowed in specified state
       
   217          *   
       
   218          *  @param  aRequest the request to be queried
       
   219          *  
       
   220          *  @return ETrue is the operation is allowed
       
   221          *          EFalse if not
       
   222          */
       
   223         virtual TBool IsRequstAllowed(TControlTransferRequest aRequest) = 0;
       
   224         
       
   225         TControlStageSm(DControlTransferManager& aTransferMgr);           
       
   226         
       
   227     protected:
       
   228         // change state of SM in iTransferMgr
       
   229         void ChangeToStage(UsbShai::TControlStage aToStage);
       
   230         
       
   231         // Clear ReadPending in ControlTransferMgr so that it won't
       
   232         // block any further read operation
       
   233         void ClearPendingRead();
       
   234         
       
   235     protected:        
       
   236         DControlTransferManager& iTransferMgr;
       
   237     };
       
   238 
       
   239 // Concreate state class
       
   240 // State of "Setup", used to wait for a setup packet
       
   241 // it will ignore all non-setup-packet
       
   242 NONSHARABLE_CLASS(DSetupStageSm) : public TControlStageSm
       
   243     {
       
   244     public:
       
   245         DSetupStageSm(DControlTransferManager& aTransferMgr);
       
   246         
       
   247         TBool RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType);
       
   248         TBool IsRequstAllowed(TControlTransferRequest aRequest);
       
   249     };
       
   250 
       
   251 // State used to wait for user to write something to host
       
   252 // The write is supposed to be done in one shot
       
   253 NONSHARABLE_CLASS(DDataInStageSm) : public TControlStageSm
       
   254     {
       
   255     public:
       
   256         DDataInStageSm(DControlTransferManager& aTransferMgr);
       
   257         
       
   258         TBool RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType);
       
   259         TBool IsRequstAllowed(TControlTransferRequest aRequest);
       
   260     };
       
   261 
       
   262 // State used to wait some data from Host
       
   263 NONSHARABLE_CLASS(DDataOutStageSm) : public TControlStageSm
       
   264     {
       
   265     public:
       
   266         DDataOutStageSm(DControlTransferManager& aTransferMgr);
       
   267         
       
   268         TBool RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType);
       
   269         TBool IsRequstAllowed(TControlTransferRequest aRequest);
       
   270     };
       
   271 
       
   272 NONSHARABLE_CLASS(DStatusInStageSm) : public TControlStageSm
       
   273     {
       
   274     public:
       
   275         DStatusInStageSm(DControlTransferManager& aTransferMgr);
       
   276         
       
   277         TBool RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType);
       
   278         TBool IsRequstAllowed(TControlTransferRequest aRequest);
       
   279     };
       
   280 
       
   281 NONSHARABLE_CLASS(DStatusOutStageSm) : public TControlStageSm
       
   282     {
       
   283     public:
       
   284         DStatusOutStageSm(DControlTransferManager& aTransferMgr);
       
   285         
       
   286         TBool RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType);
       
   287         TBool IsRequstAllowed(TControlTransferRequest aRequest);
       
   288     };
       
   289 
       
   290 #include "controltransfersm.inl"
       
   291 
       
   292 #endif //CONTROLTRANSFER_SM_H