firmware/usbctrltrf.c
author root@rika
Thu, 23 Apr 2009 19:10:12 +0200
changeset 30 7fd00015f62f
parent 2 2f55e5dd591d
permissions -rw-r--r--
several changes..
slime@2
     1
/*********************************************************************
slime@2
     2
 *
slime@2
     3
 *                Microchip USB C18 Firmware Version 1.0
slime@2
     4
 *
slime@2
     5
 *********************************************************************
slime@2
     6
 * FileName:        usbctrltrf.c
slime@2
     7
 * Dependencies:    See INCLUDES section below
slime@2
     8
 * Processor:       PIC18
slime@2
     9
 * Compiler:        C18 2.30.01+
slime@2
    10
 * Company:         Microchip Technology, Inc.
slime@2
    11
 *
slime@2
    12
 * Software License Agreement
slime@2
    13
 *
slime@2
    14
 * The software supplied herewith by Microchip Technology Incorporated
slime@2
    15
 * (the “Company”) for its PICmicro® Microcontroller is intended and
slime@2
    16
 * supplied to you, the Company’s customer, for use solely and
slime@2
    17
 * exclusively on Microchip PICmicro Microcontroller products. The
slime@2
    18
 * software is owned by the Company and/or its supplier, and is
slime@2
    19
 * protected under applicable copyright laws. All rights are reserved.
slime@2
    20
 * Any use in violation of the foregoing restrictions may subject the
slime@2
    21
 * user to criminal sanctions under applicable laws, as well as to
slime@2
    22
 * civil liability for the breach of the terms and conditions of this
slime@2
    23
 * license.
slime@2
    24
 *
slime@2
    25
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
slime@2
    26
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
slime@2
    27
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
slime@2
    28
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
slime@2
    29
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
slime@2
    30
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
slime@2
    31
 *
slime@2
    32
 * Author               Date        Comment
slime@2
    33
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
slime@2
    34
 * Rawin Rojvanit       11/19/04    Original.
slime@2
    35
 ********************************************************************/
slime@2
    36
slime@2
    37
/** I N C L U D E S **********************************************************/
slime@2
    38
#include <p18cxxx.h>
slime@2
    39
#include "typedefs.h"
slime@2
    40
#include "usb.h"
slime@2
    41
slime@2
    42
/** V A R I A B L E S ********************************************************/
slime@2
    43
#pragma udata
slime@2
    44
byte ctrl_trf_state;                // Control Transfer State
slime@2
    45
byte ctrl_trf_session_owner;        // Current transfer session owner
slime@2
    46
slime@2
    47
POINTER pSrc;                       // Data source pointer
slime@2
    48
POINTER pDst;                       // Data destination pointer
slime@2
    49
WORD wCount;                        // Data counter
slime@2
    50
slime@2
    51
/** P R I V A T E  P R O T O T Y P E S ***************************************/
slime@2
    52
void USBCtrlTrfSetupHandler(void);
slime@2
    53
void USBCtrlTrfOutHandler(void);
slime@2
    54
void USBCtrlTrfInHandler(void);
slime@2
    55
slime@2
    56
/** D E C L A R A T I O N S **************************************************/
slime@2
    57
#pragma code
slime@2
    58
/******************************************************************************
slime@2
    59
 * Function:        void USBCtrlEPService(void)
slime@2
    60
 *
slime@2
    61
 * PreCondition:    USTAT is loaded with a valid endpoint address.
slime@2
    62
 *
slime@2
    63
 * Input:           None
slime@2
    64
 *
slime@2
    65
 * Output:          None
slime@2
    66
 *
slime@2
    67
 * Side Effects:    None
slime@2
    68
 *
slime@2
    69
 * Overview:        USBCtrlEPService checks for three transaction types that
slime@2
    70
 *                  it knows how to service and services them:
slime@2
    71
 *                  1. EP0 SETUP
slime@2
    72
 *                  2. EP0 OUT
slime@2
    73
 *                  3. EP0 IN
slime@2
    74
 *                  It ignores all other types (i.e. EP1, EP2, etc.)
slime@2
    75
 *
slime@2
    76
 * Note:            None
slime@2
    77
 *****************************************************************************/
slime@2
    78
void USBCtrlEPService(void)
slime@2
    79
{   
slime@2
    80
    if(USTAT == EP00_OUT)
slime@2
    81
    {
slime@2
    82
        if(ep0Bo.Stat.PID == SETUP_TOKEN)           // EP0 SETUP
slime@2
    83
            USBCtrlTrfSetupHandler();
slime@2
    84
        else                                        // EP0 OUT
slime@2
    85
            USBCtrlTrfOutHandler();
slime@2
    86
    }
slime@2
    87
    else if(USTAT == EP00_IN)                       // EP0 IN
slime@2
    88
        USBCtrlTrfInHandler();
slime@2
    89
    
slime@2
    90
}//end USBCtrlEPService
slime@2
    91
slime@2
    92
/******************************************************************************
slime@2
    93
 * Function:        void USBCtrlTrfSetupHandler(void)
slime@2
    94
 *
slime@2
    95
 * PreCondition:    SetupPkt buffer is loaded with valid USB Setup Data
slime@2
    96
 *
slime@2
    97
 * Input:           None
slime@2
    98
 *
slime@2
    99
 * Output:          None
slime@2
   100
 *
slime@2
   101
 * Side Effects:    None
slime@2
   102
 *
slime@2
   103
 * Overview:        This routine is a task dispatcher and has 3 stages.
slime@2
   104
 *                  1. It initializes the control transfer state machine.
slime@2
   105
 *                  2. It calls on each of the module that may know how to
slime@2
   106
 *                     service the Setup Request from the host.
slime@2
   107
 *                     Module Example: USB9, HID, CDC, MSD, ...
slime@2
   108
 *                     As new classes are added, ClassReqHandler table in
slime@2
   109
 *                     usbdsc.c should be updated to call all available
slime@2
   110
 *                     class handlers.
slime@2
   111
 *                  3. Once each of the modules has had a chance to check if
slime@2
   112
 *                     it is responsible for servicing the request, stage 3
slime@2
   113
 *                     then checks direction of the transfer to determine how
slime@2
   114
 *                     to prepare EP0 for the control transfer.
slime@2
   115
 *                     Refer to USBCtrlEPServiceComplete() for more details.
slime@2
   116
 *
slime@2
   117
 * Note:            Microchip USB Firmware has three different states for
slime@2
   118
 *                  the control transfer state machine:
slime@2
   119
 *                  1. WAIT_SETUP
slime@2
   120
 *                  2. CTRL_TRF_TX
slime@2
   121
 *                  3. CTRL_TRF_RX
slime@2
   122
 *                  Refer to firmware manual to find out how one state
slime@2
   123
 *                  is transitioned to another.
slime@2
   124
 *
slime@2
   125
 *                  A Control Transfer is composed of many USB transactions.
slime@2
   126
 *                  When transferring data over multiple transactions,
slime@2
   127
 *                  it is important to keep track of data source, data
slime@2
   128
 *                  destination, and data count. These three parameters are
slime@2
   129
 *                  stored in pSrc,pDst, and wCount. A flag is used to
slime@2
   130
 *                  note if the data source is from ROM or RAM.
slime@2
   131
 *
slime@2
   132
 *****************************************************************************/
slime@2
   133
void USBCtrlTrfSetupHandler(void)
slime@2
   134
{
slime@2
   135
    byte i;
slime@2
   136
    
slime@2
   137
    /* Stage 1 */
slime@2
   138
    ctrl_trf_state = WAIT_SETUP;
slime@2
   139
    ctrl_trf_session_owner = MUID_NULL;     // Set owner to NULL
slime@2
   140
    wCount._word = 0;
slime@2
   141
    
slime@2
   142
    /* Stage 2 */
slime@2
   143
    USBCheckStdRequest();                   // See system\usb9\usb9.c
slime@2
   144
    
slime@2
   145
    for(i=0;i < (sizeof(ClassReqHandler)/sizeof(pFunc));i++)
slime@2
   146
    {
slime@2
   147
        if(ctrl_trf_session_owner != MUID_NULL)break;
slime@2
   148
        ClassReqHandler[i]();               // See autofiles\usbdsc.c
slime@2
   149
    }//end while
slime@2
   150
        
slime@2
   151
    /* Stage 3 */
slime@2
   152
    USBCtrlEPServiceComplete();
slime@2
   153
    
slime@2
   154
}//end USBCtrlTrfSetupHandler
slime@2
   155
slime@2
   156
/******************************************************************************
slime@2
   157
 * Function:        void USBCtrlTrfOutHandler(void)
slime@2
   158
 *
slime@2
   159
 * PreCondition:    None
slime@2
   160
 *
slime@2
   161
 * Input:           None
slime@2
   162
 *
slime@2
   163
 * Output:          None
slime@2
   164
 *
slime@2
   165
 * Side Effects:    None
slime@2
   166
 *
slime@2
   167
 * Overview:        This routine handles an OUT transaction according to
slime@2
   168
 *                  which control transfer state is currently active.
slime@2
   169
 *
slime@2
   170
 * Note:            Note that if the the control transfer was from
slime@2
   171
 *                  host to device, the session owner should be notified
slime@2
   172
 *                  at the end of each OUT transaction to service the
slime@2
   173
 *                  received data.
slime@2
   174
 *
slime@2
   175
 *****************************************************************************/
slime@2
   176
void USBCtrlTrfOutHandler(void)
slime@2
   177
{
slime@2
   178
    if(ctrl_trf_state == CTRL_TRF_RX)
slime@2
   179
    {
slime@2
   180
        USBCtrlTrfRxService();
slime@2
   181
        
slime@2
   182
        /*
slime@2
   183
         * Don't have to worry about overwriting _KEEP bit
slime@2
   184
         * because if _KEEP was set, TRNIF would not have been
slime@2
   185
         * generated in the first place.
slime@2
   186
         */
slime@2
   187
        if(ep0Bo.Stat.DTS == 0)
slime@2
   188
            ep0Bo.Stat._byte = _USIE|_DAT1|_DTSEN;
slime@2
   189
        else
slime@2
   190
            ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN;
slime@2
   191
    }
slime@2
   192
    else    // CTRL_TRF_TX
slime@2
   193
        USBPrepareForNextSetupTrf();
slime@2
   194
    
slime@2
   195
}//end USBCtrlTrfOutHandler
slime@2
   196
slime@2
   197
/******************************************************************************
slime@2
   198
 * Function:        void USBCtrlTrfInHandler(void)
slime@2
   199
 *
slime@2
   200
 * PreCondition:    None
slime@2
   201
 *
slime@2
   202
 * Input:           None
slime@2
   203
 *
slime@2
   204
 * Output:          None
slime@2
   205
 *
slime@2
   206
 * Side Effects:    None
slime@2
   207
 *
slime@2
   208
 * Overview:        This routine handles an IN transaction according to
slime@2
   209
 *                  which control transfer state is currently active.
slime@2
   210
 *
slime@2
   211
 *
slime@2
   212
 * Note:            A Set Address Request must not change the acutal address
slime@2
   213
 *                  of the device until the completion of the control
slime@2
   214
 *                  transfer. The end of the control transfer for Set Address
slime@2
   215
 *                  Request is an IN transaction. Therefore it is necessary
slime@2
   216
 *                  to service this unique situation when the condition is
slime@2
   217
 *                  right. Macro mUSBCheckAdrPendingState is defined in
slime@2
   218
 *                  usb9.h and its function is to specifically service this
slime@2
   219
 *                  event.
slime@2
   220
 *****************************************************************************/
slime@2
   221
void USBCtrlTrfInHandler(void)
slime@2
   222
{
slime@2
   223
    mUSBCheckAdrPendingState();         // Must check if in ADR_PENDING_STATE
slime@2
   224
    
slime@2
   225
    if(ctrl_trf_state == CTRL_TRF_TX)
slime@2
   226
    {
slime@2
   227
        USBCtrlTrfTxService();
slime@2
   228
        
slime@2
   229
        if(ep0Bi.Stat.DTS == 0)
slime@2
   230
            ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
slime@2
   231
        else
slime@2
   232
            ep0Bi.Stat._byte = _USIE|_DAT0|_DTSEN;
slime@2
   233
    }
slime@2
   234
    else // CTRL_TRF_RX
slime@2
   235
        USBPrepareForNextSetupTrf();
slime@2
   236
slime@2
   237
}//end USBCtrlTrfInHandler
slime@2
   238
slime@2
   239
/******************************************************************************
slime@2
   240
 * Function:        void USBCtrlTrfTxService(void)
slime@2
   241
 *
slime@2
   242
 * PreCondition:    pSrc, wCount, and usb_stat.ctrl_trf_mem are setup properly.
slime@2
   243
 *
slime@2
   244
 * Input:           None
slime@2
   245
 *
slime@2
   246
 * Output:          None
slime@2
   247
 *
slime@2
   248
 * Side Effects:    None
slime@2
   249
 *
slime@2
   250
 * Overview:        This routine should be called from only two places.
slime@2
   251
 *                  One from USBCtrlEPServiceComplete() and one from
slime@2
   252
 *                  USBCtrlTrfInHandler(). It takes care of managing a
slime@2
   253
 *                  transfer over multiple USB transactions.
slime@2
   254
 *
slime@2
   255
 * Note:            This routine works with isochronous endpoint larger than
slime@2
   256
 *                  256 bytes and is shown here as an example of how to deal
slime@2
   257
 *                  with BC9 and BC8. In reality, a control endpoint can never
slime@2
   258
 *                  be larger than 64 bytes.
slime@2
   259
 *****************************************************************************/
slime@2
   260
void USBCtrlTrfTxService(void)
slime@2
   261
{    
slime@2
   262
    WORD byte_to_send;
slime@2
   263
    
slime@2
   264
    /*
slime@2
   265
     * First, have to figure out how many byte of data to send.
slime@2
   266
     */
slime@2
   267
    if(wCount._word < EP0_BUFF_SIZE)
slime@2
   268
        byte_to_send._word = wCount._word;
slime@2
   269
    else
slime@2
   270
        byte_to_send._word = EP0_BUFF_SIZE;
slime@2
   271
    
slime@2
   272
    /*
slime@2
   273
     * Next, load the number of bytes to send to BC9..0 in buffer descriptor
slime@2
   274
     */
slime@2
   275
    ep0Bi.Stat.BC9 = 0;
slime@2
   276
    ep0Bi.Stat.BC8 = 0;
slime@2
   277
    ep0Bi.Stat._byte |= MSB(byte_to_send);
slime@2
   278
    ep0Bi.Cnt = LSB(byte_to_send);
slime@2
   279
    
slime@2
   280
    /*
slime@2
   281
     * Subtract the number of bytes just about to be sent from the total.
slime@2
   282
     */
slime@2
   283
    wCount._word = wCount._word - byte_to_send._word;
slime@2
   284
    
slime@2
   285
    pDst.bRam = (byte*)&CtrlTrfData;        // Set destination pointer
slime@2
   286
slime@2
   287
    if(usb_stat.ctrl_trf_mem == _ROM)       // Determine type of memory source
slime@2
   288
    {
slime@2
   289
        while(byte_to_send._word)
slime@2
   290
        {
slime@2
   291
            *pDst.bRam = *pSrc.bRom;
slime@2
   292
            pDst.bRam++;
slime@2
   293
            pSrc.bRom++;
slime@2
   294
            byte_to_send._word--;
slime@2
   295
        }//end while(byte_to_send._word)
slime@2
   296
    }
slime@2
   297
    else // RAM
slime@2
   298
    {
slime@2
   299
        while(byte_to_send._word)
slime@2
   300
        {
slime@2
   301
            *pDst.bRam = *pSrc.bRam;
slime@2
   302
            pDst.bRam++;
slime@2
   303
            pSrc.bRam++;
slime@2
   304
            byte_to_send._word--;
slime@2
   305
        }//end while(byte_to_send._word)
slime@2
   306
    }//end if(usb_stat.ctrl_trf_mem == _ROM)
slime@2
   307
    
slime@2
   308
}//end USBCtrlTrfTxService
slime@2
   309
slime@2
   310
/******************************************************************************
slime@2
   311
 * Function:        void USBCtrlTrfRxService(void)
slime@2
   312
 *
slime@2
   313
 * PreCondition:    pDst and wCount are setup properly.
slime@2
   314
 *                  pSrc is always &CtrlTrfData
slime@2
   315
 *                  usb_stat.ctrl_trf_mem is always _RAM.
slime@2
   316
 *                  wCount should be set to 0 at the start of each control
slime@2
   317
 *                  transfer.
slime@2
   318
 *
slime@2
   319
 * Input:           None
slime@2
   320
 *
slime@2
   321
 * Output:          None
slime@2
   322
 *
slime@2
   323
 * Side Effects:    None
slime@2
   324
 *
slime@2
   325
 * Overview:        *** This routine is only partially complete. Check for
slime@2
   326
 *                  new version of the firmware.
slime@2
   327
 *
slime@2
   328
 * Note:            None
slime@2
   329
 *****************************************************************************/
slime@2
   330
void USBCtrlTrfRxService(void)
slime@2
   331
{
slime@2
   332
    WORD byte_to_read;
slime@2
   333
slime@2
   334
    MSB(byte_to_read) = 0x03 & ep0Bo.Stat._byte;    // Filter out last 2 bits
slime@2
   335
    LSB(byte_to_read) = ep0Bo.Cnt;
slime@2
   336
    
slime@2
   337
    /*
slime@2
   338
     * Accumulate total number of bytes read
slime@2
   339
     */
slime@2
   340
    wCount._word = wCount._word + byte_to_read._word;
slime@2
   341
    
slime@2
   342
    pSrc.bRam = (byte*)&CtrlTrfData;
slime@2
   343
slime@2
   344
    while(byte_to_read._word)
slime@2
   345
    {
slime@2
   346
        *pDst.bRam = *pSrc.bRam;
slime@2
   347
        pDst.bRam++;
slime@2
   348
        pSrc.bRam++;
slime@2
   349
        byte_to_read._word--;
slime@2
   350
    }//end while(byte_to_read._word)    
slime@2
   351
    
slime@2
   352
}//end USBCtrlTrfRxService
slime@2
   353
slime@2
   354
/******************************************************************************
slime@2
   355
 * Function:        void USBCtrlEPServiceComplete(void)
slime@2
   356
 *
slime@2
   357
 * PreCondition:    None
slime@2
   358
 *
slime@2
   359
 * Input:           None
slime@2
   360
 *
slime@2
   361
 * Output:          None
slime@2
   362
 *
slime@2
   363
 * Side Effects:    None
slime@2
   364
 *
slime@2
   365
 * Overview:        This routine wrap up the ramaining tasks in servicing
slime@2
   366
 *                  a Setup Request. Its main task is to set the endpoint
slime@2
   367
 *                  controls appropriately for a given situation. See code
slime@2
   368
 *                  below.
slime@2
   369
 *                  There are three main scenarios:
slime@2
   370
 *                  a) There was no handler for the Request, in this case
slime@2
   371
 *                     a STALL should be sent out.
slime@2
   372
 *                  b) The host has requested a read control transfer,
slime@2
   373
 *                     endpoints are required to be setup in a specific way.
slime@2
   374
 *                  c) The host has requested a write control transfer, or
slime@2
   375
 *                     a control data stage is not required, endpoints are
slime@2
   376
 *                     required to be setup in a specific way.
slime@2
   377
 *
slime@2
   378
 *                  Packet processing is resumed by clearing PKTDIS bit.
slime@2
   379
 *
slime@2
   380
 * Note:            None
slime@2
   381
 *****************************************************************************/
slime@2
   382
void USBCtrlEPServiceComplete(void)
slime@2
   383
{
slime@2
   384
    if(ctrl_trf_session_owner == MUID_NULL)
slime@2
   385
    {
slime@2
   386
        /*
slime@2
   387
         * If no one knows how to service this request then stall.
slime@2
   388
         * Must also prepare EP0 to receive the next SETUP transaction.
slime@2
   389
         */
slime@2
   390
        ep0Bo.Cnt = EP0_BUFF_SIZE;
slime@2
   391
        ep0Bo.ADR = (byte*)&SetupPkt;
slime@2
   392
        
slime@2
   393
        ep0Bo.Stat._byte = _USIE|_BSTALL;
slime@2
   394
        ep0Bi.Stat._byte = _USIE|_BSTALL;
slime@2
   395
    }
slime@2
   396
    else    // A module has claimed ownership of the control transfer session.
slime@2
   397
    {
slime@2
   398
        if(SetupPkt.DataDir == DEV_TO_HOST)
slime@2
   399
        {
slime@2
   400
            if(SetupPkt.wLength < wCount._word)
slime@2
   401
                wCount._word = SetupPkt.wLength;
slime@2
   402
            USBCtrlTrfTxService();
slime@2
   403
            ctrl_trf_state = CTRL_TRF_TX;
slime@2
   404
            /*
slime@2
   405
             * Control Read:
slime@2
   406
             * <SETUP[0]><IN[1]><IN[0]>...<OUT[1]> | <SETUP[0]>
slime@2
   407
             * 1. Prepare OUT EP to respond to early termination
slime@2
   408
             *
slime@2
   409
             * NOTE:
slime@2
   410
             * If something went wrong during the control transfer,
slime@2
   411
             * the last status stage may not be sent by the host.
slime@2
   412
             * When this happens, two different things could happen
slime@2
   413
             * depending on the host.
slime@2
   414
             * a) The host could send out a RESET.
slime@2
   415
             * b) The host could send out a new SETUP transaction
slime@2
   416
             *    without sending a RESET first.
slime@2
   417
             * To properly handle case (b), the OUT EP must be setup
slime@2
   418
             * to receive either a zero length OUT transaction, or a
slime@2
   419
             * new SETUP transaction.
slime@2
   420
             *
slime@2
   421
             * Since the SETUP transaction requires the DTS bit to be
slime@2
   422
             * DAT0 while the zero length OUT status requires the DTS
slime@2
   423
             * bit to be DAT1, the DTS bit check by the hardware should
slime@2
   424
             * be disabled. This way the SIE could accept either of
slime@2
   425
             * the two transactions.
slime@2
   426
             *
slime@2
   427
             * Furthermore, the Cnt byte should be set to prepare for
slime@2
   428
             * the SETUP data (8-byte or more), and the buffer address
slime@2
   429
             * should be pointed to SetupPkt.
slime@2
   430
             */
slime@2
   431
            ep0Bo.Cnt = EP0_BUFF_SIZE;
slime@2
   432
            ep0Bo.ADR = (byte*)&SetupPkt;            
slime@2
   433
            ep0Bo.Stat._byte = _USIE;           // Note: DTSEN is 0!
slime@2
   434
    
slime@2
   435
            /*
slime@2
   436
             * 2. Prepare IN EP to transfer data, Cnt should have
slime@2
   437
             *    been initialized by responsible request owner.
slime@2
   438
             */
slime@2
   439
            ep0Bi.ADR = (byte*)&CtrlTrfData;
slime@2
   440
            ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
slime@2
   441
        }
slime@2
   442
        else    // (SetupPkt.DataDir == HOST_TO_DEV)
slime@2
   443
        {
slime@2
   444
            ctrl_trf_state = CTRL_TRF_RX;
slime@2
   445
            /*
slime@2
   446
             * Control Write:
slime@2
   447
             * <SETUP[0]><OUT[1]><OUT[0]>...<IN[1]> | <SETUP[0]>
slime@2
   448
             *
slime@2
   449
             * 1. Prepare IN EP to respond to early termination
slime@2
   450
             *
slime@2
   451
             *    This is the same as a Zero Length Packet Response
slime@2
   452
             *    for control transfer without a data stage
slime@2
   453
             */
slime@2
   454
            ep0Bi.Cnt = 0;
slime@2
   455
            ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
slime@2
   456
slime@2
   457
            /*
slime@2
   458
             * 2. Prepare OUT EP to receive data.
slime@2
   459
             */
slime@2
   460
            ep0Bo.Cnt = EP0_BUFF_SIZE;
slime@2
   461
            ep0Bo.ADR = (byte*)&CtrlTrfData;
slime@2
   462
            ep0Bo.Stat._byte = _USIE|_DAT1|_DTSEN;
slime@2
   463
        }//end if(SetupPkt.DataDir == DEV_TO_HOST)
slime@2
   464
    }//end if(ctrl_trf_session_owner == MUID_NULL)
slime@2
   465
    
slime@2
   466
    /*
slime@2
   467
     * PKTDIS bit is set when a Setup Transaction is received.
slime@2
   468
     * Clear to resume packet processing.
slime@2
   469
     */
slime@2
   470
    UCONbits.PKTDIS = 0;
slime@2
   471
slime@2
   472
}//end USBCtrlEPServiceComplete
slime@2
   473
slime@2
   474
/******************************************************************************
slime@2
   475
 * Function:        void USBPrepareForNextSetupTrf(void)
slime@2
   476
 *
slime@2
   477
 * PreCondition:    None
slime@2
   478
 *
slime@2
   479
 * Input:           None
slime@2
   480
 *
slime@2
   481
 * Output:          None
slime@2
   482
 *
slime@2
   483
 * Side Effects:    None
slime@2
   484
 *
slime@2
   485
 * Overview:        The routine forces EP0 OUT to be ready for a new Setup
slime@2
   486
 *                  transaction, and forces EP0 IN to be owned by CPU.
slime@2
   487
 *
slime@2
   488
 * Note:            None
slime@2
   489
 *****************************************************************************/
slime@2
   490
void USBPrepareForNextSetupTrf(void)
slime@2
   491
{
slime@2
   492
    ctrl_trf_state = WAIT_SETUP;            // See usbctrltrf.h
slime@2
   493
    ep0Bo.Cnt = EP0_BUFF_SIZE;              // Defined in usbcfg.h
slime@2
   494
    ep0Bo.ADR = (byte*)&SetupPkt;
slime@2
   495
    ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN;  // EP0 buff dsc init, see usbmmap.h
slime@2
   496
    ep0Bi.Stat._byte = _UCPU;               // EP0 IN buffer initialization
slime@2
   497
}//end USBPrepareForNextSetupTrf
slime@2
   498
slime@2
   499
/** EOF usbctrltrf.c *********************************************************/